The following JavaScript is working for most cases (alphabetically), and it should be ignoring new lines or spaces, and also it should be ignoring the inner HTML. However when sorting column 2, it doesn't follow the logical numbering 1, 2, 14, 17.. as it sorts first the 1s.. then 2s.. etc. Not right numerically.
I need it to follow both rules of sorting alphabetically and numerically at the same time. I saw this post about the issue, but can't seem to implement it.
window.onload = function() {
document.querySelectorAll('th').forEach((element) => { // Table headers
element.addEventListener('click', function() {
let table = this.closest('table');
// If the column is sortable
if (this.querySelector('span')) {
let order_icon = this.querySelector('span');
let order = encodeURI(order_icon.innerHTML).includes('%E2%86%91') ? 'desc' : 'asc';
let separator = '-----'; // Separate the value of it's index, so data keeps intact
let value_list = {}; // <tr> Object
let obj_key = []; // Values of selected column
let string_count = 0;
let number_count = 0;
// <tbody> rows
table.querySelectorAll('tbody tr').forEach((line, index_line) => {
// Value of each field
let key = line.children[element.cellIndex].textContent.toUpperCase().trim();
// Check if value is date, numeric or string
if (line.children[element.cellIndex].hasAttribute('data-timestamp')) {
// if value is date, we store it's timestamp, so we can sort like a number
key = line.children[element.cellIndex].getAttribute('data-timestamp');
} else if (key.replace('-', '').match(/^[0-9,.]*$/g)) {
number_count++;
} else {
string_count++;
}
value_list[key + separator + index_line] = line.outerHTML.replace(/(\t)|(\n)/g, ''); // Adding <tr> to object
obj_key.push(key + separator + index_line);
});
if (string_count === 0) { // If all values are numeric
obj_key.sort(function(a, b) {
return a.split(separator)[0] - b.split(separator)[0];
});
} else {
obj_key.sort();
}
if (order === 'desc') {
obj_key.reverse();
order_icon.innerHTML = '↓';
} else {
order_icon.innerHTML = '↑';
}
let html = '';
obj_key.forEach(function(chave) {
html += value_list[chave];
});
table.getElementsByTagName('tbody')[0].innerHTML = html;
}
});
});
}
<table border="1" id="myTable2" class="resize-table-font">
<thead>
<tr>
<th>
<p align="center">name <span>↑</span></p>
</th>
<th>
<p align="center">ref <span>↑</span></p>
</th>
</tr>
</thead>
<tr>
<td>
1</td>
<td>
(book
3: 16)</td>
</tr>
<tr>
<td>
22</td>
<td>
(book 3: 16)</td>
</tr>
<tr>
<td>
book</td>
<td>
(book 2: 1-3)</td>
</tr>
<tr>
<td>
2</td>
<td>
(book 19: 12)</td>
</tr>
<tr>
<td>
how</td>
<td>
(book 19: 10, 12)</td>
</tr>
<tr>
<td>
when</td>
<td>
(book 19: 28; 21: 31)؟</td>
</tr>
<tr>
<td>
love</td>
<td>
(book 19: 30; 21: 31)؟</td>
</tr>
<tr>
<td>
3</td>
<td>
(book 10: 41; 14: 6, 7; 15: 3)</td>
</tr>
<tr>
<td>
tg</td>
<td>
(book 21: 30)</td>
</tr>
<tr>
<td>
web</td>
<td>
(book 19: 26; 21: 30)</td>
</tr>
<tr>
<td>
internet</td>
<td>
(book 15: 32; 19: 7)</td>
</tr>
<tr>
<td>
far4</td>
<td>
(book 19: 13)</td>
</tr>
<tr>
<td>
far3</td>
<td>
(book 21: 32)</td>
</tr>
<tr>
<td>
far33</td>
<td>
(book 20: 8; 21: 27)</td>
</tr>
</table>