Reputation: 123
I am trying to build a simple HTML table sorter using pure jquery and javascript without using any plugins but cannot get the date column to function right. 6/16/2015 and 1/1/2016 are not right, its almost like I am not sorting by every row. The other columns are coming out right but I cant figure out whats going on.
This is what I have so for:
Javascript:
<script src="//code.jquery.com/jquery-3.3.1.js"></script>
<script>
$(document).ready(function () {
('#HardSoftWareTbl thead').on('click', 'th', function () {
$(this).attr('data-order', ($(this).attr('data-order') === 'desc' ? 'asc' : 'desc'));
if ($(this).hasClass("dateTh")) {
sorttable(this, $('#HardSoftWareTbl thead th').index(this), true);
}
sorttable(this, $('#HardSoftWareTbl thead th').index(this), false);
});
});
function sorttable(header, index, isDate) {
var tbody = $('table tbody');
var order = $(header).attr('data-order');
tbody.find('tr').sort(function (a, b) {
var tda = $(a).find('td:eq(' + index + ')').text();
var tdb = $(b).find('td:eq(' + index + ')').text();
if (isDate) {
tda = toDate(tda);
tdb = toDate(tdb);
}
return (order === 'asc' ? (tda > tdb ? 1 : tda < tdb ? -1 : 0) : (tda < tdb ? 1 : tda > tdb ? -1 : 0));
}).appendTo(tbody);
}
function toDate(d) {
console.log("d: " + d);
var date = d.split(" ")[0].split("/");
console.log("date: " + date);
return new Date(date[2], date[0] -1, date[1]);
}
</script>
HTML:
<style>
table {width: 100%;font: 12px arial;}
th, td {min-width: 40px;text-align: center;}
th {font-weight: bold;}
</style>
<table id="HardSoftWareTbl" class="table">
<thead id="theader" >
<tr>
<th>Name</th>
<th>Description</th>
<th>Cost</th>
<th>Quantity</th>
<th class="dateTh">Date Added</th>
</tr>
</thead>
<tbody>
<tr>
<td>Surface Book</td>
<td>A portable tablet/laptop hybrid</td>
<td>$1,899.99</td>
<td>24</td>
<td>6/16/2015</td>
</tr>
<tr>
<td>Surface Studio</td>
<td>A desktop computer. Edit photos, videos, etc.</td>
<td>$2,999.99</td>
<td>87</td>
<td>1/1/2016</td>
</tr>
<tr>
<td>Visual Studio</td>
<td>The best IDE around for software development using Microsoft technology</td>
<td>$10,999.99</td>
<td>N/A</td>
<td>5/2/1999</td>
</tr>
<tr>
<td>Visual Studio</td>
<td>IDE for software development using Microsoft technology</td>
<td>$10,999.99</td>
<td>01</td>
<td>5/3/2000</td>
</tr>
</tbody>
Upvotes: 0
Views: 144
Reputation: 274
Problem in your code is that, sorttable
is getting called twice. Once with isDate set as true and immediately after with falsey value.
Added else block for:
if ($(this).hasClass("dateTh")) {
sorttable(this, $('#HardSoftWareTbl thead th').index(this), true);
}
sorttable(this, $('#HardSoftWareTbl thead th').index(this), false);
to
if ($(this).hasClass("dateTh")) {
sorttable(this, $('#HardSoftWareTbl thead th').index(this), true);
} else {
sorttable(this, $('#HardSoftWareTbl thead th').index(this), false);
}
Otherwise it will sort twice.
Checkout the pen at:
https://codepen.io/ankur-agarwal/pen/QQKJJj
I did update the toDate
assuming the format to be MM-dd-yyyy
.
Upvotes: 1
Reputation: 17943
You can write your custom date comparator like following.
function dateComparator(date1, date2) {
var date1Number = getComparableNumber(date1);
var date2Number = getComparableNumber(date2);
//Negative if date2 is bigger and possitive if date2 is smaller.
return date1Number - date2Number;
}
function getComparableNumber(date) {
if (date === undefined || date === null) {
return null;
}
var dtSplit = date.split('/');
var yearNumber = dtSplit[2];
var dayNumber = dtSplit[1];
var monthNumber = dtSplit[0];
return (yearNumber*10000) + (monthNumber*100) + dayNumber;
}
Here date is converted to a number like "1/1/2016" will be converted to 201601001. Now it's easy for your to order it.
If you are open for open source library, you can check Moment.js. It is an excellent library for date handling.
Upvotes: 0