CMedina CMedina - 5 months ago 13
jQuery Question

Order table html asc

I have a function that adds rows to my table, but the problem is that it's not always in asc order, have a number column to sort the items.

I need reorder my table HTML acording to the column N°.

It's my table:

+------+---------------+---------------+-----------+
| N° | COLUMN1 | COLUMN2 | COLUMN3 |
+------+---------------+---------------+-----------+
| 2 | AAAAAAAAAAAA | XXXXXXXXXXXX | 00000000 |
| 1 | BBBBBBBBBBBB | YYYYYYYYYYYY | 00000000 |
| 3 | CCCCCCCCCCCC | ZZZZZZZZZZZZ | 00000000 |
+------+---------------+---------------+-----------+


The result expected is:

+------+---------------+---------------+-----------+
| N° | COLUMN1 | COLUMN2 | COLUMN3 |
+------+---------------+---------------+-----------+
| 1 | BBBBBBBBBBBB | YYYYYYYYYYYY | 00000000 |
| 2 | AAAAAAAAAAAA | XXXXXXXXXXXX | 00000000 |
| 3 | CCCCCCCCCCCC | ZZZZZZZZZZZZ | 00000000 |
+------+---------------+---------------+-----------+


Each column has an attribute order, looks like this:

<tr data-order='2'>......</tr>
<tr data-order='1'>......</tr>
<tr data-order='3'>......</tr>


I try with the pluging DataTable (It's working), but I would like to sort my table without additional plugin.

Thanks for help in advance! :)

EDIT: Solution to the problem...

as I had mentioned I have a function that adds a new tr.

function addnewTR(newOrder, new_tr){
//Code
}


First, find if the order exist in the table, if exist set the tr to the variable.

$('#myTable tbody tr').each(function (i) {

var _tr;
var order = $(this).data("order");

if (order_actual == newOrder) {
_tr = this;
};

});


Second, Check the position of
_tr
to insert my new element using insertAfter (if exist the order in the table) or append (if the order is new).

if (_tr !== undefined) {
$(new_tr).insertAfter(_tr);
} else {
$("#myTable tbody").append(new_tr);
}

Answer

Following is a pure javascript solution. It does keep the original order thus you can say it's stable sorting. Note :

  1. I assumed you data-order only contains integers
  2. Can have duplicate values for data-order
  3. Sort in ASC order

Explanation:

  1. You need to get <tr> list from table
  2. Store it on a object in following form { "data-order" : [ HTMLElement:tr_1 , HTMLElement:tr_2 ]
  3. Then empty all the rows on the table
  4. Get the key set from the Object created on step 2
  5. Sort it
  6. Print it ( note each element on your object could have more than one object, if you allow duplicate data-order values)

var table = document.getElementsByTagName("table")[0];
var new_tbody = document.createElement('tbody');
var tr_list = document.getElementsByTagName("table")[0].rows;
var tr_list_obj = {};
for(var tr_index in tr_list){
	var tr = tr_list[tr_index];
	if(tr instanceof HTMLElement){
  	if(tr_list_obj[tr.getAttribute("data-order")] instanceof Array){
    	tr_list_obj[tr.getAttribute("data-order")].push(tr);
    }else{
    	tr_list_obj[tr.getAttribute("data-order")] = new Array();
    	tr_list_obj[tr.getAttribute("data-order")].push(tr);
    }
  }
}


tr_list[0].parentNode.innerHTML = '';


tr_list_sort_array = Object.keys(tr_list_obj);
tr_list_sort_array.sort();

for(var tr_index in tr_list_sort_array){
	for(var tr_index_2 in tr_list_obj[tr_list_sort_array[tr_index]]){
  		table.appendChild(tr_list_obj[tr_list_sort_array[tr_index]][tr_index_2]);
  }
}
<table>
<tr data-order='2'><td>First 2</td></tr>
<tr data-order='1'><td>First 1</td></tr>
<tr data-order='3'><td>First 3</td></tr>
<tr data-order='5'><td>First 5</td></tr>
<tr data-order='4'><td>First 4</td></tr>
<tr data-order='9'><td>First 9</td></tr>
<tr data-order='4'><td>Second 4</td></tr>
<tr data-order='1'><td>Second 1</td></tr>
<tr data-order='3'><td>Second 3</td></tr>
</table>