I want to sort a table when user clicks on a table header. My code works well, everything gets sorted but only when there are no <a href=#>
around <td>
.
sorttable.js
function sortTable(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("data_table");
switching = true;
dir = "asc";
while (switching) {
switching = false;
rows = table.rows;
for (i = 1; i < (rows.length - 1); i ) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i 1].getElementsByTagName("TD")[n];
if (dir == "asc") {
if (x.innerHTML.toUpperCase() > y.innerHTML.toUpperCase()) {
shouldSwitch = true;
break;
}
} else if (dir == "desc") {
if (x.innerHTML.toUpperCase() < y.innerHTML.toUpperCase()) {
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i 1], rows[i]);
switching = true;
switchcount ;
} else {
if (switchcount == 0 && dir == "asc") {
dir = "desc";
switching = true;
}
}
}
}
<table id="data_table">
<thead>
<tr>
<th onclick="sortTable(0)">Name</th>
<th onclick="sortTable(1)">Number</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="/registrants/45">caregiver testing testing</a></td>
<td>23</td>
</tr>
<tr>
<td><a href="/registrants/72">aaaaaaa test GoodeE</a></td>
<td>1</td>
</tr>
<tr>
<td><a href="/registrants/74">bbbBBBbb GoodeX</a></td>
<td>2</td>
</tr>
<tr>
<td><a href="/registrants/76">EEEEeFFFFgggHH GoodeC</a></td>
<td>-7</td>
</tr>
</tbody>
</table>
I'm JS newbie so no I'm not entirely sure what's going on with my code but I think that's the issue. How to cover such case?
CodePudding user response:
You can check if a <td>
includes an <a>
, and if so, replace the <td>
with the <a>
. Like this:
function sortTable(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("data_table");
switching = true;
dir = "asc";
while (switching) {
switching = false;
rows = table.rows;
for (i = 1; i < (rows.length - 1); i ) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("TD")[n];
// new code starts
x_a = x.getElementsByTagName("a")[0];
if (x_a != undefined) {
x = x_a;
};
// new code ends
y = rows[i 1].getElementsByTagName("TD")[n];
// new code starts
y_a = y.getElementsByTagName("a")[0];
if (y_a != undefined) {
y = y_a;
};
// new code ends
if (dir == "asc") {
if (x.innerHTML.toUpperCase() > y.innerHTML.toUpperCase()) {
shouldSwitch = true;
break;
}
} else if (dir == "desc") {
if (x.innerHTML.toUpperCase() < y.innerHTML.toUpperCase()) {
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i 1], rows[i]);
switching = true;
switchcount ;
} else {
if (switchcount == 0 && dir == "asc") {
dir = "desc";
switching = true;
}
}
}
}
<table id="data_table">
<thead>
<tr>
<th onclick="sortTable(0)">Name</th>
<th onclick="sortTable(1)">Number</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="/registrants/45">caregiver testing testing</a></td>
<td>23</td>
</tr>
<tr>
<td><a href="/registrants/72">aaaaaaa test GoodeE</a></td>
<td>1</td>
</tr>
<tr>
<td><a href="/registrants/74">bbbBBBbb GoodeX</a></td>
<td>2</td>
</tr>
<tr>
<td><a href="/registrants/76">EEEEeFFFFgggHH GoodeC</a></td>
<td>-7</td>
</tr>
</tbody>
</table>
Edit:
Come to think of it, it would be much simpler and safer to just replace innerHTML
with textContent
in the original code.
Like this:
function sortTable(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("data_table");
switching = true;
dir = "asc";
while (switching) {
switching = false;
rows = table.rows;
for (i = 1; i < (rows.length - 1); i ) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i 1].getElementsByTagName("TD")[n];
if (dir == "asc") {
if (x.textContent.toUpperCase() > y.textContent.toUpperCase()) {
shouldSwitch = true;
break;
}
} else if (dir == "desc") {
if (x.textContent.toUpperCase() < y.textContent.toUpperCase()) {
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i 1], rows[i]);
switching = true;
switchcount ;
} else {
if (switchcount == 0 && dir == "asc") {
dir = "desc";
switching = true;
}
}
}
}
<table id="data_table">
<thead>
<tr>
<th onclick="sortTable(0)">Name</th>
<th onclick="sortTable(1)">Number</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="/registrants/45">caregiver testing testing</a></td>
<td>23</td>
</tr>
<tr>
<td>aaaaaaa test GoodeE</td>
<td>1</td>
</tr>
<tr>
<td><a href="/registrants/74">bbbBBBbb GoodeX</a></td>
<td>2</td>
</tr>
<tr>
<td><a href="/registrants/76">EEEEeFFFFgggHH GoodeC</a></td>
<td>-7</td>
</tr>
</tbody>
</table>