The end goal of my chart is that it displays prices in ascending order (ex: $10.24, $12.44, $100.00).
But with my code, it puts the number 100.00 in second position but I don't know why... Does anyone have a solution? My code is in my JSFIDDLE
function sortTable(table, column, type) {
var order = $(`${table} thead tr>th:eq(' column ')`).data('order');
order = order === 'ASC' ? 'DESC' : 'ASC';
$(`${table} thead tr>th:eq(' column ')`).data('order', order);
$(`${table} tbody tr`).sort(function(a, b) {
a = $(a).find('td:eq(' column ')').text().trim();
b = $(b).find('td:eq(' column ')').text().trim();
switch (type) {
case 'text':
return order === 'ASC' ? a.localeCompare(b) : b.localeCompare(a);
break;
case 'number':
return order === 'ASC' ? a - b : b - a;
break;
case 'date':
var dateFormat = function(dt) {
[m, d, y] = dt.split('/');
return [y, m - 1, d];
}
a = new Date(...dateFormat(a));
b = new Date(...dateFormat(b));
return order === 'ASC' ? a.getTime() - b.getTime() : b.getTime() - a.getTime();
break;
}
}).appendTo(`${table} tbody`);
}
sortTable('#tableBidList', 1, 'text');
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td,
th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
.d-none {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table >
<thead>
<tr>
<th>
<span data-key-translate="quote.vehicle">Name</span>
</th>
<th>
<span data-key-translate="shaq.price">Price</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
<td price="5 1024" data-price="10.24">
<span data-eur-value="10.24">10.24</span> <span >$</span>
</td>
</tr>
<tr>
<td>B</td>
<td price="6 10000" data-price="100.00">
<span data-eur-value="100.00">100.00</span> <span >$</span>
</td>
</tr>
<tr>
<td>C</td>
<td price="5 1244" data-price="12.44">
<span data-eur-value="12.44">12.44</span> <span >$</span>
</td>
</tr>
</tbody>
</table>
CodePudding user response:
A lot is happening in the code provided. Instead, I will provide you with an alternative.
I tried my best to break the solution into small functions plus for each part I added comments in hopes to guide you.
I hope this is useful to you.
// We extract a value of type string or number.
const cell = (row, index) => {
let value = row.children[index].innerText || row.children[index].textContent;
value = value.replace('$', '');
return (value === 'number') ? value : value;
}
// We check if its a number
const isNumber = (value) => value !== '' && !isNaN(value);
// We check that both values to compare are numbers
const isComparingNumbers = (v1, v2) => isNumber(v1) && isNumber(v2);
// We compare number vs. number or we compare string vs. string
const comparing = (v1, v2) => {
return isComparingNumbers(v1, v2) ? v1 - v2 : v1.toString().localeCompare(v2)
}
// We create a comparator that will compare based on the order provided at that index
const comparator = (index, order) =>
(left, right) => (comparing)
(cell(order ? left : right, index),
cell(order ? right : left, index));
// With the header selected,
// 1. We obtain a reference to the table
// 2. We obtain a list of references of all the rows except the headers
// 3. We obtain the index by searching for the header
// 4. We perform the sorting of all rows (except the header)
// Also, we invest the flag of the order each time we call this method.
// As we sort, we change the table
const tableSorting = (event) => {
const header = event.currentTarget.header;
const table = header.closest('table');
const rowsExceptHeaders = table.querySelectorAll('tr:nth-child(n 2)');
let index = Array.from(header.parentNode.children).indexOf(header);
Array.from(rowsExceptHeaders)
.sort(comparator(index, this.asc = !this.asc))
.forEach(row => table.appendChild(row) );
};
// The main take care of selecting all the headers.
// For each header, we set that each header should listen for the click event.
// We also pass each header so it can be used by the tableSorting function.
const main = () => {
const headers = document.querySelectorAll('th');
headers.forEach(header => {
header.addEventListener('click', (tableSorting))
header.header = header;
});
}
// We wait for all DOMs be loaded prior running the main method.
$(function() {
main();
let selector = 'table tr th span[data-key-translate="shaq.price"]'
let elem = document.querySelector(selector);
elem.click();
/*
let tables = document.querySelectorAll('.table');
tables.forEach(table => {
let headers = table.querySelectorAll('th');
headers.forEach(column => {
let span = column.querySelector('span');
let title = span.innerHTML;
if (title == 'Price'){
column.click();
}
});
});
*/
});
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td,
th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
.d-none {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table >
<tr>
<th>
<span data-key-translate="quote.vehicle">Name</span>
</th>
<th>
<span data-key-translate="shaq.price">Price</span>
</th>
</tr>
<tr>
<td>A</td>
<td price="5 1024" data-price="10.24">
<span data-eur-value="10.24">10.24</span> <span >$</span>
</td>
</tr>
<tr>
<td>B</td>
<td price="6 10000" data-price="100.00">
<span data-eur-value="100.00">100.00</span> <span >$</span>
</td>
</tr>
<tr>
<td>C</td>
<td price="5 1244" data-price="12.44">
<span data-eur-value="12.44">12.44</span> <span >$</span>
</td>
</tr>
</table>