Home > Back-end >  Sort Divs by Date/Time
Sort Divs by Date/Time

Time:12-27

I am trying to sort some dynamically created Divs by date/time using JS/jQuery. There are 2 different types of divs (.note and .activity) which are using data-datetime="" or just datetime="" so I am attempting to sort them by the content in elements with the class name .timeago.

    setTimeout(function() {

        function sortDescending(a, b) {
            var date1 = $(a).find(".timeago").text();
            date1 = date1.split('/');
            date1 = new Date(date1[2], date1[1] - 1, date1[0]);
            var date2 = $(b).find(".timeago").text();
            date2 = date2.split('/');
            date2 = new Date(date2[2], date2[1] - 1, date2[0]);

            return date1 < date2 ? 1 : -1;
        };

        $('.notes .note').sort(sortDescending).appendTo('.notes');


    }, 3000);
.note { margin-bottom:30px;}
.note .timeago {color:red; font-weight:bold;}
.activity .timeago {color:green; font-weight:bold;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div  id="accordion">

<!------ Notes ------>

    <div  data-toggle="collapse" href="#collapse0">
        <div >
            <div >
                <div >
                    <abbr  data-datetime="2022-10-30T18:54:39Z" title="10/30/2022 11:54 AM">10/30/2022 11:54 AM</abbr>
                </div>
                <div >Should Be 1</div>
            </div>
            <div  id="collapse0">
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
            </div>
        </div>
    </div>

    <div  data-toggle="collapse" href="#collapse1">
        <div >
            <div >
                <div >
                    <abbr  data-datetime="2022-08-11T15:39:41Z" title="8/11/2022 8:39 AM">8/11/2022 8:39 AM</abbr>
                </div>
                <div >Should Be 5</div>
            </div>
            <div  id="collapse1">
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
            </div>
        </div>
    </div>

    <div  data-toggle="collapse" href="#collapse2">
        <div >
            <div >
                <div >
                    <abbr  data-datetime="2022-10-05T14:53:01Z" title="10/5/2022 7:53 AM">10/5/2022 7:53 AM</abbr>
                </div>
                <div >Should Be 2</div>
            </div>
            <div  id="collapse2">
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
            </div>
        </div>
    </div>
    
<!------ End Notes ------>
    


<!------ Activities ------>

    <div  data-toggle="collapse" href="#collapse3">
        <div >
            <div >Should Be 6</div>
            <div >
                <time  datetime="2022-04-03T15:41:09-07:00">4/3/2022 3:41 PM</time>
            </div>
        </div>
        <div  id="collapse3">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </div>
    </div>

    <div  data-toggle="collapse" href="#collapse4">
        <div >
            <div >Should Be 3</div>
            <div >
                <time  datetime="2022-10-03T06:55:52-07:00">10/3/2022 6:55 AM</time>
            </div>
        </div>
        <div  id="collapse4">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </div>
    </div>

    <div  data-toggle="collapse" href="#collapse5">
        <div >
            <div >Should Be 4</div>
            <div >
                <time  datetime="2022-09-03T09:29:33-07:00">9/3/2022 9:29 AM</time>
            </div>
        </div>
        <div  id="collapse5">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </div>
    </div>
    
<!------ End Activities ------>


</div>

I have created a JS Fiddle for this - https://jsfiddle.net/bstime/oyec69g5/11/

CodePudding user response:

You can do that...

function sortNotes()
  {
  let divParent = document.querySelector('#accordion');
    
  [...document.querySelectorAll('#accordion > div.note')]
  .sort( (a,b) =>
    {
    let aDate = new Date(a.querySelector('.timeago').textContent).getTime()
      , bDate = new Date(b.querySelector('.timeago').textContent).getTime();
    return bDate - aDate;
    }) 
  .forEach(note =>  divParent.appendChild(note) )
  }
  
sortNotes();
.note { margin-bottom:30px;}
.note .timeago {color:red; font-weight:bold;}
.activity .timeago {color:green; font-weight:bold;}
<div  id="accordion">
  <div   >
    <div >
      <div >
        <div >
          <abbr  data-datetime="2022-10-30T18:54:39Z" title="10/30/2022 11:54 AM">10/30/2022 11:54 AM</abbr>
        </div>
        <div>Should Be 1</div>
      </div>
      <div  >
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
      </div>
    </div>
  </div>
  <div >
    <div >
      <div >
        <div >
          <abbr  data-datetime="2022-08-11T15:39:41Z" title="8/11/2022 8:39 AM">8/11/2022 8:39 AM</abbr>
        </div>
        <div>Should Be 5</div>
      </div>
      <div  id="collapse1">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
      </div>
    </div>
  </div>
  <div   >
    <div >
      <div >
        <div >
          <abbr  data-datetime="2022-10-05T14:53:01Z" title="10/5/2022 7:53 AM">10/5/2022 7:53 AM</abbr>
        </div>
        <div>Should Be 2</div>
      </div>
      <div  id="collapse2">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
      </div>
    </div>
  </div>
  <div  >
    <div >
      <div >Should Be 6</div>
      <div >
        <time  datetime="2022-04-03T15:41:09-07:00">4/3/2022 3:41 PM</time>
      </div>
    </div>
    <div  >
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    </div>
  </div>
  <div  >
    <div >
      <div >Should Be 3</div>
      <div >
        <time  datetime="2022-10-03T06:55:52-07:00">10/3/2022 6:55 AM</time>
      </div>
    </div>
    <div >
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    </div>
  </div>
  <div  >
    <div >
      <div >Should Be 4</div>
      <div >
        <time  datetime="2022-09-03T09:29:33-07:00">9/3/2022 9:29 AM</time>
      </div>
    </div>
    <div  >
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    </div>
  </div>
</div>

from PO comment :
that works when using on the fiddle but when I apply it to the site im getting: Uncaught TypeError: Cannot read properties of null (reading 'textContent')

in case of invalid date values...

function sortNotes()
  {
  let divParent = document.querySelector('#accordion')
    , allNotes  = [...document.querySelectorAll('#accordion > div.note')]
    ;
  allNotes.forEach( note =>
    {
    let refTimeago = note.querySelector('.timeago');
    note._refDate = refTimeago ? new Date(refTimeago.textContent).getTime() : 0;
    if (isNaN(note._refDate) ) note._refDate = 0;
    });
  allNotes
  .sort( (a,b) => b._refDate - a._refDate ) 
  .forEach( note => 
    {
    delete note._refDate;
    divParent.appendChild(note);
    })  
  }
sortNotes();

CodePudding user response:

Your date constructor params were incorrect so the date being parsed failed. I split the last date part (the year time eg: 2022 9:29 AM) with space and get the first item to only get the year.

setTimeout(function() {

  function sortDescending(a, b) {
    var date1 = $(a).find(".timeago").text();
    date1 = date1.split('/');
    date1 = new Date(date1[2].split(' ')[0], date1[0], date1[1]);

    var date2 = $(b).find(".timeago").text();
    date2 = date2.split('/');
    date2 = new Date(date2[2].split(' ')[0], date2[0], date2[1]);

    return date1 < date2 ? 1 : -1;
  };

  $('.notes .note').sort(sortDescending).appendTo('.notes');


}, 3000);

CodePudding user response:

There is already a good plain Javascript solution, but since you are using jQuery, here is a jQuery option. It also seems clunky to me to have to use the text of your page for the sorting, when you do have an attribute which is presumably there explicitly for this kind of programmatic manipulation - eg maybe in future the text will change format and won't be parseable in JS.

function sortDescending(a, b) {
    // Find the element with the attributes we're after ...
    let $timeElementA = $('.timeago', a);
    let $timeElementB = $('.timeago', b);

    // ... and use whichever of the 2 attribute possibilities are there
    let timeA = $timeElementA.data('datetime')
        ? new Date($timeElementA.data('datetime'))
        : new Date($timeElementA.attr('datetime'));
    let timeB = $timeElementB.data('datetime')
        ? new Date($timeElementB.data('datetime'))
        : new Date($timeElementB.attr('datetime'));

    // Javascript sort should return a value >0, <0, or 0.  
    // Simply subtracting our 2 values works here.
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#description
    return timeB - timeA;
}

setTimeout(function() {
    $('.notes .note').sort(sortDescending).each(function(i, el) {
        $('.notes').append(el);
    });
}, 3000);
.note {
  margin-bottom: 30px;
}

.note .timeago {
  color: red;
  font-weight: bold;
}

.activity .timeago {
  color: green;
  font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div  id="accordion">

<!------ Notes ------>

    <div  data-toggle="collapse" href="#collapse0">
        <div >
            <div >
                <div >
                    <abbr  data-datetime="2022-10-30T18:54:39Z" title="10/30/2022 11:54 AM">10/30/2022 11:54 AM</abbr>
                </div>
                <div >Should Be 1</div>
            </div>
            <div  id="collapse0">
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
            </div>
        </div>
    </div>

    <div  data-toggle="collapse" href="#collapse1">
        <div >
            <div >
                <div >
                    <abbr  data-datetime="2022-08-11T15:39:41Z" title="8/11/2022 8:39 AM">8/11/2022 8:39 AM</abbr>
                </div>
                <div >Should Be 5</div>
            </div>
            <div  id="collapse1">
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
            </div>
        </div>
    </div>

    <div  data-toggle="collapse" href="#collapse2">
        <div >
            <div >
                <div >
                    <abbr  data-datetime="2022-10-05T14:53:01Z" title="10/5/2022 7:53 AM">10/5/2022 7:53 AM</abbr>
                </div>
                <div >Should Be 2</div>
            </div>
            <div  id="collapse2">
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
            </div>
        </div>
    </div>
    
<!------ End Notes ------>
    


<!------ Activities ------>

    <div  data-toggle="collapse" href="#collapse3">
        <div >
            <div >Should Be 6</div>
            <div >
                <time  datetime="2022-04-03T15:41:09-07:00">4/3/2022 3:41 PM</time>
            </div>
        </div>
        <div  id="collapse3">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </div>
    </div>

    <div  data-toggle="collapse" href="#collapse4">
        <div >
            <div >Should Be 3</div>
            <div >
                <time  datetime="2022-10-03T06:55:52-07:00">10/3/2022 6:55 AM</time>
            </div>
        </div>
        <div  id="collapse4">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </div>
    </div>

    <div  data-toggle="collapse" href="#collapse5">
        <div >
            <div >Should Be 4</div>
            <div >
                <time  datetime="2022-09-03T09:29:33-07:00">9/3/2022 9:29 AM</time>
            </div>
        </div>
        <div  id="collapse5">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </div>
    </div>
    
<!------ End Activities ------>


</div>

  • Related