简体   繁体   中英

Javascript sort table div by time date

I have a table like this

 <div class="wrapper-3OdqYJdx"> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="name-OX45">John</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>1:59:08 PM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="name-OX45">David</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>12:10:00 AM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div title="Remove" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="name-OX45">Vonn</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>12:40:02 AM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div title="Edit" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="name-OX45">Anna</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>3:02:01 PM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div title="Edit" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div title="Remove" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> </div>

How I can sort this table by time date, only with javascript, without using jquery, newest on top?

I read about sorting by number here: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_sort_table_number

Im thingking about removing all < span > and </ span > in the HTML to get the full date format then convert it to unix timestamp then sort it using the code from w3schools.

But I dont know how to do it. Can you please help me?

EDIT:

The scenario is: I don't have control on the table or code generated. It's a movable table which is displayed on my screen so I use a browser extension called "Javascript Injector" to add the javascript to the current HTML, to sort the date, delete rows that has the word "debt", highlight rows that have the word "paid all" with red color - which are rows that I want to focus.

Since it's the code added to the browser extension, I have to click on that extension from time to time. So can you please help me to add a function to repeat the sorting every 30 seconds automatically? Thank you very much for your assistance.

Here is a sort on date and time

I assume the classnames are static. If dynamic we need more code

I also added some CSS for visualisation

The datestring of 1/11/2022 1:59:08 PM is parsable without RegExp so I use it as is

 const container = document.querySelector(".wrapper-3OdqYJdx") const getDateFromSpans = spans => new Date(`${spans[0].textContent} ${spans[1].textContent}`); const rows = [...container.querySelectorAll(".bodyRow-OX45")].sort((a,b)=> getDateFromSpans(a.querySelectorAll('.timeCell-OX45 span')) - getDateFromSpans(b.querySelectorAll('.timeCell-OX45 span'))) container.append(...rows)
 .bodyRow-OX45 { border: 1px solid black; } span::after { content: " - " }
 <div class="wrapper-3OdqYJdx"> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="ticker-OX45">John</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>1:59:08 PM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="ticker-OX45">David</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>12:10:00 AM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div title="Remove" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="ticker-OX45">Vonn</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>12:40:02 AM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div title="Edit" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="ticker-OX45">Anna</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>3:02:01 PM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div title="Edit" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div title="Remove" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> </div>

I would convert the children list of the container into an array of [Date, Element] pairs, sort by the first column, then convert the sorted array of [Date, Element] pairs back into an array of Element s. Finally, you just have to loop through the resulting array to append the child elements into the container one by one.

 var map = Array.prototype.map; var mainEl = document.getElementById("main"); var childEls = map.call(mainEl.children, function (el) { var d = el.children[0].textContent; var t = el.children[1].textContent; return [Date.parse(d + " " + t), el]; }).sort(function (a, b) { return a[0] - b[0]; }).map(function (pair) { return pair[1]; }); for (let childEl of childEls) { mainEl.appendChild(childEl); }
 <div id="main"> <div><span>1/11/2022</span> <span>1:59:08 PM</span> David</div> <div><span>1/11/2022</span> <span>12:10:00 AM</span> Anna</div> <div><span>1/11/2022</span> <span>12:40:02 AM</span> John</div> <div><span>1/11/2022</span> <span>3:02:01 PM</span> Vonn</div> </div>

Just in case you don't know map or call :

> | [1, 2, 3].map(function (x) {
  |   return x + 1;
  | })
< | [2, 3, 4]
> | Array.prototype.map.call([1, 2, 3], function (x) {
  |   return x + 1;
  | })
< | [2, 3, 4]

The map.call pattern is required because mainEl.children has no map method (type document.children.map in the browser console and see what happens).

Side note

As suggested in the comments, in modern JS syntax you would write childEls = [...mainEl.children].map(...) , which boils down to the same result. However, I did a perf test a couple of years ago to compare stuffs like map.call(mainEl.children, ...) and [...mainEl.children].map(...) , and the modern syntax was far slower than the old one. Maybe things have changed since then, I let you check by yourself:-)

It's probably a good idea to write your own "parse" function, because you never know how the browser implementation of Date.parse(...) deals with non standard date formats. Just pick the various bits from d + " " + t , and make a Date object with new Date(year, monthIndex, day, hours, minutes, seconds, milliseconds) .

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date

Another variant on the above. Query all elements to find the spans containing the dates and generate a timestamp to use in the comparison. An array sort function can compare the values to sort the results as desired before regenerating the HTML.

 const d=document; const q=(e,n=d)=>n.querySelector(e); const qa=(e,n=d)=>n.querySelectorAll(e); const parent=q('div.wrapper-3OdqYJdx'); const col=qa('div.timeCell-OX45'); const nodes=[]; col.forEach( div=>{ let tmp={ node:div.parentNode, time:new Date( [...qa('span', div ) ].map( span=>{ return span.textContent; }).join(' ') ).getTime() }; nodes.push( tmp ) }); nodes.sort( (a,b)=>{ if( a.time > b.time )return 1; if( a.time < b.time )return -1 if( a.time==b.time )return 0; }); parent.innerHTML=''; nodes.forEach( obj=>parent.appendChild( obj.node ) );
 span{padding:0.25rem}
 <div class="wrapper-3OdqYJdx"> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="name-OX45">John</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>1:59:08 PM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="name-OX45">David</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>12:10:00 AM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div title="Remove" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="name-OX45">Vonn</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>12:40:02 AM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div title="Edit" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="name-OX45">Anna</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>3:02:01 PM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div title="Edit" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div title="Remove" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> </div>

Your classes in Dom may be generated dynamic, so this answer will help you:

 const times = document.querySelectorAll('div[class*="timeCell"] span:first-child') const data=[]; times.forEach( item => { data.push({ time: new Date(item.innerText+" "+item.nextElementSibling.innerText ).getTime(), parent: item.parentElement.parentElement }) }) data.sort(function (a, b) { return a.time - b.time; }); const newDom = document.querySelector('div[class*="wrapper"]'); data.forEach(item => newDom.append(item.parent));
 div[class*="timeCell"] span:first-child{ color:red; }
 <div class="wrapper-3OdqYJdx"> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="name-OX45">John</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>1:59:08 PM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="name-OX45">David</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>12:10:00 AM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div title="Remove" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="name-OX45">Vonn</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>12:40:02 AM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div title="Edit" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> <div class="bodyRow-OX45"> <div class="cell-OX45 symbolCell-OX45"> <div class="name-OX45">Anna</div> </div> <div class="cell-OX45 descriptionCell-OX45">paid</div> <div class="cell-OX45 timeCell-OX45"><span>1/11/2022</span><span>3:02:01 PM</span></div> <div class="cell-OX45 buttonsCell-OX45"> <div title="Edit" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA"></div> <div title="Remove" role="button" class="button-mpsUn-6R apply-common-tooltip button-165AA dangerous-165AA"></div> </div> </div> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM