1

I have multiple div elements with data-timestamp attribute

What I want to do is sort these divs by data-timestamp (newer to older). I decided to loop through elements and swap their positions. If an element's next sibling has a newer data-timestamp than the current element, then next sibling inserts before current.

$.each($('.sorted-chat-item'), function( i, value ) {
        //current element's timestamp
        var date = new Date($(value).attr('data-timestamp'));
        //all elements
        var list = $('.sorted-chat-item');

        for(var j = i+1; j < list.length; j++){
            //next element's timestamp
            var nextDate = new Date($(list[j]).attr('data-timestamp'));
            if(date < nextDate){
                $(list[j]).insertBefore( $(list[i]) );
            }
        }
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='sorted-chat-item' data-timestamp="2017-09-01 18:09:22">2017-09-01 18:09:22</div>
<div class='sorted-chat-item' data-timestamp="2017-09-01 18:01:27">2017-09-01 18:01:27</div>
<div class='sorted-chat-item' data-timestamp="2017-09-01 18:31:36">2017-09-01 18:31:36</div>

but it doesn't sort correctly. Any idea, what am I doing wrong?

6
  • What you are doing is called bubblesort and it needs more iterations to sort the whole list. You must repeat the each function as long as there are changes Commented Sep 1, 2017 at 15:03
  • You're missing a " in the last div to close the data-timestamp attribute. Commented Sep 1, 2017 at 15:04
  • thanks for reply, can you please be more specific? Commented Sep 1, 2017 at 15:05
  • I've edited your question, your code seems to work to me. Commented Sep 1, 2017 at 15:06
  • 1
    Easiest method will be to put all the DOM elements in an array, use a pre-built sort mechanism then put them back. See linked duplicate, changing the answer's $().find('.header h3').text() to $().data("timestamp") Commented Sep 1, 2017 at 15:08

2 Answers 2

2

I have not tested this, and you should probably use the id of the parent rather then parent(), but i imagine something like this would work

function sortByCustomDate(a, b){
    var aDate = new Date($(a).attr('data-timestamp'));
    var bDate = new Date($(b).attr('data-timestamp'));
    return ((aDate < bDate) ? -1 : ((aDate > bDate) ? 1 : 0));
}


var $parent = $('.sorted-chat-item').parent();
var $allElements = $('.sorted-chat-item');
$allElements.sort(sortByCustomDate);
$parent.empty().append($allElements);
Sign up to request clarification or add additional context in comments.

Comments

1

Below is in plain js, but it does what you want. We're first sorting the items, then removing and appending them to their container

Array.from(document.getElementsByClassName('sorted-chat-item')).sort((a, b) => {
  return new Date(b.getAttribute('data-timestamp')).getTime() - new Date(a.getAttribute('data-timestamp')).getTime();
}).forEach(e => {
  let p = e.parentNode;
  p.removeChild(e);
  p.appendChild(e);
});
<div>
  <div class='sorted-chat-item' data-timestamp="2017-09-01 18:09:22">2017-09-01 18:09:22</div>
  <div class='sorted-chat-item' data-timestamp="2017-09-01 18:01:27">2017-09-01 18:01:27</div>
  <div class='sorted-chat-item' data-timestamp="2017-09-01 18:31:36">2017-09-01 18:31:36</div>
</div>

2 Comments

I like your plain JS approach but OP was already using jQuery. I assume you were writing yours as I was writing mine, but the idea is the same ;) So have a +1
@DarkMukke thanks, yours is a good one two. You got my revenge.. :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.