How to sort tables with js/html
I have a table :
Name | Department | status
I sorted the names alphabetically on click but now I created a dropdown in the status cell which displays values such as Inside/Outside and I want to sort the table when I click on one of those filters I want to only see the people who are in/out. my current JS function :
function sortStatusDesc() {
var table, rows, switching, i, x, y, shouldSwitch;
table = document.getElementById("myTable");
switching = true;
while (switching) {
switching = false;
rows = table.rows;
for (i = 1; i < (rows.length - 1); i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("th")[2];
y = rows[i + 1].getElementsByTagName("th")[2];
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
}
}
}
It sorts alphabeticaly.
javascript html
|
show 17 more comments
I have a table :
Name | Department | status
I sorted the names alphabetically on click but now I created a dropdown in the status cell which displays values such as Inside/Outside and I want to sort the table when I click on one of those filters I want to only see the people who are in/out. my current JS function :
function sortStatusDesc() {
var table, rows, switching, i, x, y, shouldSwitch;
table = document.getElementById("myTable");
switching = true;
while (switching) {
switching = false;
rows = table.rows;
for (i = 1; i < (rows.length - 1); i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("th")[2];
y = rows[i + 1].getElementsByTagName("th")[2];
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
}
}
}
It sorts alphabeticaly.
javascript html
1
Have you considered sorting the data and then rendering the sorted data? I'd imagine it would be a little faster as you wouldn't initially have to read all of the data from the DOM.
– JO3-W3B-D3V
Nov 21 '18 at 9:04
2
You usually don't actually sort rows. If you use a render() function that turns an array of data objects into a HTML table to render the table you have, you can just sort that array of source data using the array.sort() method and then just rerender the table.
– Shilly
Nov 21 '18 at 9:04
@Shilly I'm glad to see we're on the same page here!
– JO3-W3B-D3V
Nov 21 '18 at 9:05
I m new to javascript so any code would be useful
– Em44
Nov 21 '18 at 9:13
@Shilly are you going to post some code or ?
– Em44
Nov 22 '18 at 13:43
|
show 17 more comments
I have a table :
Name | Department | status
I sorted the names alphabetically on click but now I created a dropdown in the status cell which displays values such as Inside/Outside and I want to sort the table when I click on one of those filters I want to only see the people who are in/out. my current JS function :
function sortStatusDesc() {
var table, rows, switching, i, x, y, shouldSwitch;
table = document.getElementById("myTable");
switching = true;
while (switching) {
switching = false;
rows = table.rows;
for (i = 1; i < (rows.length - 1); i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("th")[2];
y = rows[i + 1].getElementsByTagName("th")[2];
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
}
}
}
It sorts alphabeticaly.
javascript html
I have a table :
Name | Department | status
I sorted the names alphabetically on click but now I created a dropdown in the status cell which displays values such as Inside/Outside and I want to sort the table when I click on one of those filters I want to only see the people who are in/out. my current JS function :
function sortStatusDesc() {
var table, rows, switching, i, x, y, shouldSwitch;
table = document.getElementById("myTable");
switching = true;
while (switching) {
switching = false;
rows = table.rows;
for (i = 1; i < (rows.length - 1); i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("th")[2];
y = rows[i + 1].getElementsByTagName("th")[2];
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
}
}
}
It sorts alphabeticaly.
javascript html
javascript html
edited Nov 22 '18 at 19:29
kit
1,1063816
1,1063816
asked Nov 21 '18 at 9:02
Em44Em44
96
96
1
Have you considered sorting the data and then rendering the sorted data? I'd imagine it would be a little faster as you wouldn't initially have to read all of the data from the DOM.
– JO3-W3B-D3V
Nov 21 '18 at 9:04
2
You usually don't actually sort rows. If you use a render() function that turns an array of data objects into a HTML table to render the table you have, you can just sort that array of source data using the array.sort() method and then just rerender the table.
– Shilly
Nov 21 '18 at 9:04
@Shilly I'm glad to see we're on the same page here!
– JO3-W3B-D3V
Nov 21 '18 at 9:05
I m new to javascript so any code would be useful
– Em44
Nov 21 '18 at 9:13
@Shilly are you going to post some code or ?
– Em44
Nov 22 '18 at 13:43
|
show 17 more comments
1
Have you considered sorting the data and then rendering the sorted data? I'd imagine it would be a little faster as you wouldn't initially have to read all of the data from the DOM.
– JO3-W3B-D3V
Nov 21 '18 at 9:04
2
You usually don't actually sort rows. If you use a render() function that turns an array of data objects into a HTML table to render the table you have, you can just sort that array of source data using the array.sort() method and then just rerender the table.
– Shilly
Nov 21 '18 at 9:04
@Shilly I'm glad to see we're on the same page here!
– JO3-W3B-D3V
Nov 21 '18 at 9:05
I m new to javascript so any code would be useful
– Em44
Nov 21 '18 at 9:13
@Shilly are you going to post some code or ?
– Em44
Nov 22 '18 at 13:43
1
1
Have you considered sorting the data and then rendering the sorted data? I'd imagine it would be a little faster as you wouldn't initially have to read all of the data from the DOM.
– JO3-W3B-D3V
Nov 21 '18 at 9:04
Have you considered sorting the data and then rendering the sorted data? I'd imagine it would be a little faster as you wouldn't initially have to read all of the data from the DOM.
– JO3-W3B-D3V
Nov 21 '18 at 9:04
2
2
You usually don't actually sort rows. If you use a render() function that turns an array of data objects into a HTML table to render the table you have, you can just sort that array of source data using the array.sort() method and then just rerender the table.
– Shilly
Nov 21 '18 at 9:04
You usually don't actually sort rows. If you use a render() function that turns an array of data objects into a HTML table to render the table you have, you can just sort that array of source data using the array.sort() method and then just rerender the table.
– Shilly
Nov 21 '18 at 9:04
@Shilly I'm glad to see we're on the same page here!
– JO3-W3B-D3V
Nov 21 '18 at 9:05
@Shilly I'm glad to see we're on the same page here!
– JO3-W3B-D3V
Nov 21 '18 at 9:05
I m new to javascript so any code would be useful
– Em44
Nov 21 '18 at 9:13
I m new to javascript so any code would be useful
– Em44
Nov 21 '18 at 9:13
@Shilly are you going to post some code or ?
– Em44
Nov 22 '18 at 13:43
@Shilly are you going to post some code or ?
– Em44
Nov 22 '18 at 13:43
|
show 17 more comments
3 Answers
3
active
oldest
votes
The folllowing snippet shown the sorting on any property.
Clicking on one of the property header changes the sorting.
In the same way, you can create the filtering. Instead of sorting the source_data on a particular property with data.sort()
, you would data.filter()
for all the entries that have the correct value.
// Name of the data we're rendering.
const source_name = 'Locations';
// Source data we want to create a table from.
const source_data = [
{ "id": 1, "name": "production hall", "department": "production", "status": "inside" },
{ "id": 2, "name": "spare parts room", "department": "production", "status": "inside" },
{ "id": 3, "name": "warehouse", "department": "production", "status": "inside" },
{ "id": 4, "name": "loading bay", "department": "production", "status": "outside" },
{ "id": 5, "name": "offices HR", "department": "administration", "status": "inside" },
{ "id": 6, "name": "offices QA", "department": "administration", "status": "inside" },
{ "id": 7, "name": "security lounge", "department": "administration", "status": "outside" }
];
// Create the table.
// For this example, we'll use string manipulation to create the HTML.
// For complex layouts a templating system is better.
const render = ( name, data ) => {
// Always include a header for the name.
// When there's 0 rows, we'll still know what the table shows.
const labels = data.length
? '<tr>' + Object.keys( data[ 0 ]).map( name => `<th data-attr="${ name }">${ name }</th>` ).join( '' ) + '</tr>'
: '';
// Actual header for the properties of our data.
const header = `<tr><th colspan="${ data.length || 1 }">${ name }</th></tr>${ labels }`;
// One row for each entry in our data.
const rows = data.map( entry => (`<tr id="entry_${ entry.id }">` + Object.values( entry ).map( value => `<td>${ value }</td>` ).join( '' ) + '</tr>' )).join( '' );
// Merge it all together.
const table = `<table><thead>${ header }</thead><tbody>${ rows }</tbody></table>`;
// Render into the page.
document.querySelector( '#output' ).innerHTML = table;
};
// Sort of the property.
const sort = ( data, property ) => {
// Sort the data on the property in alphabetical order.
return data.sort(( first, second ) => {
if ( first[ property ] < second[ property ] ) return -1;
else if ( first[ property ] > second[ property ] ) return 1;
else return 0;
});
};
// Add click events to the header so that clicking a header will sort the rows.
const add_sorting = function( table ) {
Array
.from( table.querySelectorAll( 'th' ))
.forEach( header => header.addEventListener( 'click', create_table ));
};
// Main function
const create_table = event => {
// We'll reuse this function both manually and through clicking
const property = event && event.target
? event.target.getAttribute( 'data-attr' )
: event;
const collection = sort( source_data, property );
render( source_name, collection );
add_sorting( document.querySelector( 'table' ));
};
create_table( 'name' );
th, td {
border: 1px solid grey;
}
<div id="output"></div>
add a comment |
A table section can easily be sorted according to a comparator function (e.g. "is this cell supposed to appear before that cell?", Math.min
, for example) using any comparison sort algorithm, here demonstrating the insertion sort, less than 10 lines of actual table sorting code:
class InsertionSort {
static sort_children(parent, comparator) {
for(let i = 0; i != parent.children.length; i++) {
const current = parent.children[i];
let element;
for(element = current.previousElementSibling; element && comparator(current, element); element = element.previousElementSibling);
parent.insertBefore(current, element ? element.nextElementSibling : parent.firstElementChild);
}
}
}
Having a table section (or a table) (the parent
argument to sort_children
above) with an amount of rows as children, you can sort it with the sort_children
method defined above, as long as you yourself rightfully define how your rows should compare:
InsertionSort.sort_children(your_table, (row_A, row_B) => row_A.cells[0].textContent < row_B.cells[0].textContent);
The above sorts table rows so that the cells of the first column appear in lexicographical order.
The second argument to sort_children
is the aforementioned comparator function comparator(row_A, row_B)
, which is expected to return true
for any two rows it is passed where row_A
should appear before row_B
, and false
otherwise. Since you provide the comparator function, you decide how your rows are sorted.
You can further adapt the comparator function by creating a function that returns a comparator which would be specific to a particular table column, according to a value format (text, number, etc), using the <
operator automatically (which is defined for Number
and String
, among other types):
const table_cell_comparator = (column_index, type) => ((row_A, row_B) => type(row_A.cells[column_index].textContent) < type(row_A.cells[column_index].textContent));
Then invoking table sorting with a less verbose and more readable expression:
InsertionSort.sort_children(your_table, table_cell_comparator(1, Number));
The above sorts the rows so that cells of second column with lower numeric value appear before cells with higher numeric value.
add a comment |
"Filtering" a table, as it is called, with existing rows, can easily be done with class toggling, among other things:
function filter_table(section, predicate) {
for(const row of section.rows) row.classList.toggle("filtered", predicate(row));
}
What happens above is that rows of an entire table or table section (section
above) that the predicate
function considers "filtered", are marked as such by toggling the "filtered" class on these.
The predicate
function is a function of your own design and choosing that accepts a table row and returns true
if the row should be filtered or false
otherwise.
Taking your use case with employee rows, for instance, where let's say the 3rd table cell of every row contains a select
(drop-down) control with one option for "In" and one option for "Out":
<tr><!-- ... --><td><select><option value="in">In</option><option value="out">Out</option></select></tr>
You can write the predicate that will filter employee rows according to either "In" or "Out" status ("in" in the example), as follows:
const predicate = row => row.cells[2].firstElementChild.value == "in";
How you style filtered rows is up to you, you may want to simply hide them, of course:
tr.filtered {
display: none;
}
Since the status of each employee effectively changes with the change in drop-down selection, you would be wasting resources by invoking filter_table
for every such change, which then would go through all the rows again. It is then a much better idea to listen on the "change" event that would be fired by the select
control as it changes its value:
table.addEventListener("change", event => {
if(event.target instanceof HTMLSelectElement) {
const row = event.target.parentElement.parentElement;
row.classList.toggle("filtered", predicate(row));
}
})
You only need to attach a single listener to the entire table -- "change" events bubble up the element tree. The predicate
function defined above is reused, but for the single changed row only.
P.S. Before anyone chooses to jump the wagon so to speak, and recommend use of the hidden
attribute, I don't consider it appropriate here, without more information in the question -- a filtered row is not an invalid/inapplicable document node, it may only be filtered temporarily, for instance, to aid reading the table according to a variable. Unless you actually want to remove such rows, then it's different. I believe the question as it stands asks for "perceptive" filtering.
this is exactly what I've been looking for,but if you could only help me with the implementation of this certain code because functions are not working(begginer at js sorry)
– Em44
Nov 26 '18 at 12:41
Use MDN to learn JavaScript to a point where the answer makes sense -- thefor ... of
loop, theclassList
property, theHTMLTableElement
, what the DOM is and how it works, etc. MDN is a great resource! Be careful with random blogs on Internet -- not all who write know their stuff.
– amn
Nov 26 '18 at 14:59
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53408465%2fhow-to-sort-tables-with-js-html%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
The folllowing snippet shown the sorting on any property.
Clicking on one of the property header changes the sorting.
In the same way, you can create the filtering. Instead of sorting the source_data on a particular property with data.sort()
, you would data.filter()
for all the entries that have the correct value.
// Name of the data we're rendering.
const source_name = 'Locations';
// Source data we want to create a table from.
const source_data = [
{ "id": 1, "name": "production hall", "department": "production", "status": "inside" },
{ "id": 2, "name": "spare parts room", "department": "production", "status": "inside" },
{ "id": 3, "name": "warehouse", "department": "production", "status": "inside" },
{ "id": 4, "name": "loading bay", "department": "production", "status": "outside" },
{ "id": 5, "name": "offices HR", "department": "administration", "status": "inside" },
{ "id": 6, "name": "offices QA", "department": "administration", "status": "inside" },
{ "id": 7, "name": "security lounge", "department": "administration", "status": "outside" }
];
// Create the table.
// For this example, we'll use string manipulation to create the HTML.
// For complex layouts a templating system is better.
const render = ( name, data ) => {
// Always include a header for the name.
// When there's 0 rows, we'll still know what the table shows.
const labels = data.length
? '<tr>' + Object.keys( data[ 0 ]).map( name => `<th data-attr="${ name }">${ name }</th>` ).join( '' ) + '</tr>'
: '';
// Actual header for the properties of our data.
const header = `<tr><th colspan="${ data.length || 1 }">${ name }</th></tr>${ labels }`;
// One row for each entry in our data.
const rows = data.map( entry => (`<tr id="entry_${ entry.id }">` + Object.values( entry ).map( value => `<td>${ value }</td>` ).join( '' ) + '</tr>' )).join( '' );
// Merge it all together.
const table = `<table><thead>${ header }</thead><tbody>${ rows }</tbody></table>`;
// Render into the page.
document.querySelector( '#output' ).innerHTML = table;
};
// Sort of the property.
const sort = ( data, property ) => {
// Sort the data on the property in alphabetical order.
return data.sort(( first, second ) => {
if ( first[ property ] < second[ property ] ) return -1;
else if ( first[ property ] > second[ property ] ) return 1;
else return 0;
});
};
// Add click events to the header so that clicking a header will sort the rows.
const add_sorting = function( table ) {
Array
.from( table.querySelectorAll( 'th' ))
.forEach( header => header.addEventListener( 'click', create_table ));
};
// Main function
const create_table = event => {
// We'll reuse this function both manually and through clicking
const property = event && event.target
? event.target.getAttribute( 'data-attr' )
: event;
const collection = sort( source_data, property );
render( source_name, collection );
add_sorting( document.querySelector( 'table' ));
};
create_table( 'name' );
th, td {
border: 1px solid grey;
}
<div id="output"></div>
add a comment |
The folllowing snippet shown the sorting on any property.
Clicking on one of the property header changes the sorting.
In the same way, you can create the filtering. Instead of sorting the source_data on a particular property with data.sort()
, you would data.filter()
for all the entries that have the correct value.
// Name of the data we're rendering.
const source_name = 'Locations';
// Source data we want to create a table from.
const source_data = [
{ "id": 1, "name": "production hall", "department": "production", "status": "inside" },
{ "id": 2, "name": "spare parts room", "department": "production", "status": "inside" },
{ "id": 3, "name": "warehouse", "department": "production", "status": "inside" },
{ "id": 4, "name": "loading bay", "department": "production", "status": "outside" },
{ "id": 5, "name": "offices HR", "department": "administration", "status": "inside" },
{ "id": 6, "name": "offices QA", "department": "administration", "status": "inside" },
{ "id": 7, "name": "security lounge", "department": "administration", "status": "outside" }
];
// Create the table.
// For this example, we'll use string manipulation to create the HTML.
// For complex layouts a templating system is better.
const render = ( name, data ) => {
// Always include a header for the name.
// When there's 0 rows, we'll still know what the table shows.
const labels = data.length
? '<tr>' + Object.keys( data[ 0 ]).map( name => `<th data-attr="${ name }">${ name }</th>` ).join( '' ) + '</tr>'
: '';
// Actual header for the properties of our data.
const header = `<tr><th colspan="${ data.length || 1 }">${ name }</th></tr>${ labels }`;
// One row for each entry in our data.
const rows = data.map( entry => (`<tr id="entry_${ entry.id }">` + Object.values( entry ).map( value => `<td>${ value }</td>` ).join( '' ) + '</tr>' )).join( '' );
// Merge it all together.
const table = `<table><thead>${ header }</thead><tbody>${ rows }</tbody></table>`;
// Render into the page.
document.querySelector( '#output' ).innerHTML = table;
};
// Sort of the property.
const sort = ( data, property ) => {
// Sort the data on the property in alphabetical order.
return data.sort(( first, second ) => {
if ( first[ property ] < second[ property ] ) return -1;
else if ( first[ property ] > second[ property ] ) return 1;
else return 0;
});
};
// Add click events to the header so that clicking a header will sort the rows.
const add_sorting = function( table ) {
Array
.from( table.querySelectorAll( 'th' ))
.forEach( header => header.addEventListener( 'click', create_table ));
};
// Main function
const create_table = event => {
// We'll reuse this function both manually and through clicking
const property = event && event.target
? event.target.getAttribute( 'data-attr' )
: event;
const collection = sort( source_data, property );
render( source_name, collection );
add_sorting( document.querySelector( 'table' ));
};
create_table( 'name' );
th, td {
border: 1px solid grey;
}
<div id="output"></div>
add a comment |
The folllowing snippet shown the sorting on any property.
Clicking on one of the property header changes the sorting.
In the same way, you can create the filtering. Instead of sorting the source_data on a particular property with data.sort()
, you would data.filter()
for all the entries that have the correct value.
// Name of the data we're rendering.
const source_name = 'Locations';
// Source data we want to create a table from.
const source_data = [
{ "id": 1, "name": "production hall", "department": "production", "status": "inside" },
{ "id": 2, "name": "spare parts room", "department": "production", "status": "inside" },
{ "id": 3, "name": "warehouse", "department": "production", "status": "inside" },
{ "id": 4, "name": "loading bay", "department": "production", "status": "outside" },
{ "id": 5, "name": "offices HR", "department": "administration", "status": "inside" },
{ "id": 6, "name": "offices QA", "department": "administration", "status": "inside" },
{ "id": 7, "name": "security lounge", "department": "administration", "status": "outside" }
];
// Create the table.
// For this example, we'll use string manipulation to create the HTML.
// For complex layouts a templating system is better.
const render = ( name, data ) => {
// Always include a header for the name.
// When there's 0 rows, we'll still know what the table shows.
const labels = data.length
? '<tr>' + Object.keys( data[ 0 ]).map( name => `<th data-attr="${ name }">${ name }</th>` ).join( '' ) + '</tr>'
: '';
// Actual header for the properties of our data.
const header = `<tr><th colspan="${ data.length || 1 }">${ name }</th></tr>${ labels }`;
// One row for each entry in our data.
const rows = data.map( entry => (`<tr id="entry_${ entry.id }">` + Object.values( entry ).map( value => `<td>${ value }</td>` ).join( '' ) + '</tr>' )).join( '' );
// Merge it all together.
const table = `<table><thead>${ header }</thead><tbody>${ rows }</tbody></table>`;
// Render into the page.
document.querySelector( '#output' ).innerHTML = table;
};
// Sort of the property.
const sort = ( data, property ) => {
// Sort the data on the property in alphabetical order.
return data.sort(( first, second ) => {
if ( first[ property ] < second[ property ] ) return -1;
else if ( first[ property ] > second[ property ] ) return 1;
else return 0;
});
};
// Add click events to the header so that clicking a header will sort the rows.
const add_sorting = function( table ) {
Array
.from( table.querySelectorAll( 'th' ))
.forEach( header => header.addEventListener( 'click', create_table ));
};
// Main function
const create_table = event => {
// We'll reuse this function both manually and through clicking
const property = event && event.target
? event.target.getAttribute( 'data-attr' )
: event;
const collection = sort( source_data, property );
render( source_name, collection );
add_sorting( document.querySelector( 'table' ));
};
create_table( 'name' );
th, td {
border: 1px solid grey;
}
<div id="output"></div>
The folllowing snippet shown the sorting on any property.
Clicking on one of the property header changes the sorting.
In the same way, you can create the filtering. Instead of sorting the source_data on a particular property with data.sort()
, you would data.filter()
for all the entries that have the correct value.
// Name of the data we're rendering.
const source_name = 'Locations';
// Source data we want to create a table from.
const source_data = [
{ "id": 1, "name": "production hall", "department": "production", "status": "inside" },
{ "id": 2, "name": "spare parts room", "department": "production", "status": "inside" },
{ "id": 3, "name": "warehouse", "department": "production", "status": "inside" },
{ "id": 4, "name": "loading bay", "department": "production", "status": "outside" },
{ "id": 5, "name": "offices HR", "department": "administration", "status": "inside" },
{ "id": 6, "name": "offices QA", "department": "administration", "status": "inside" },
{ "id": 7, "name": "security lounge", "department": "administration", "status": "outside" }
];
// Create the table.
// For this example, we'll use string manipulation to create the HTML.
// For complex layouts a templating system is better.
const render = ( name, data ) => {
// Always include a header for the name.
// When there's 0 rows, we'll still know what the table shows.
const labels = data.length
? '<tr>' + Object.keys( data[ 0 ]).map( name => `<th data-attr="${ name }">${ name }</th>` ).join( '' ) + '</tr>'
: '';
// Actual header for the properties of our data.
const header = `<tr><th colspan="${ data.length || 1 }">${ name }</th></tr>${ labels }`;
// One row for each entry in our data.
const rows = data.map( entry => (`<tr id="entry_${ entry.id }">` + Object.values( entry ).map( value => `<td>${ value }</td>` ).join( '' ) + '</tr>' )).join( '' );
// Merge it all together.
const table = `<table><thead>${ header }</thead><tbody>${ rows }</tbody></table>`;
// Render into the page.
document.querySelector( '#output' ).innerHTML = table;
};
// Sort of the property.
const sort = ( data, property ) => {
// Sort the data on the property in alphabetical order.
return data.sort(( first, second ) => {
if ( first[ property ] < second[ property ] ) return -1;
else if ( first[ property ] > second[ property ] ) return 1;
else return 0;
});
};
// Add click events to the header so that clicking a header will sort the rows.
const add_sorting = function( table ) {
Array
.from( table.querySelectorAll( 'th' ))
.forEach( header => header.addEventListener( 'click', create_table ));
};
// Main function
const create_table = event => {
// We'll reuse this function both manually and through clicking
const property = event && event.target
? event.target.getAttribute( 'data-attr' )
: event;
const collection = sort( source_data, property );
render( source_name, collection );
add_sorting( document.querySelector( 'table' ));
};
create_table( 'name' );
th, td {
border: 1px solid grey;
}
<div id="output"></div>
// Name of the data we're rendering.
const source_name = 'Locations';
// Source data we want to create a table from.
const source_data = [
{ "id": 1, "name": "production hall", "department": "production", "status": "inside" },
{ "id": 2, "name": "spare parts room", "department": "production", "status": "inside" },
{ "id": 3, "name": "warehouse", "department": "production", "status": "inside" },
{ "id": 4, "name": "loading bay", "department": "production", "status": "outside" },
{ "id": 5, "name": "offices HR", "department": "administration", "status": "inside" },
{ "id": 6, "name": "offices QA", "department": "administration", "status": "inside" },
{ "id": 7, "name": "security lounge", "department": "administration", "status": "outside" }
];
// Create the table.
// For this example, we'll use string manipulation to create the HTML.
// For complex layouts a templating system is better.
const render = ( name, data ) => {
// Always include a header for the name.
// When there's 0 rows, we'll still know what the table shows.
const labels = data.length
? '<tr>' + Object.keys( data[ 0 ]).map( name => `<th data-attr="${ name }">${ name }</th>` ).join( '' ) + '</tr>'
: '';
// Actual header for the properties of our data.
const header = `<tr><th colspan="${ data.length || 1 }">${ name }</th></tr>${ labels }`;
// One row for each entry in our data.
const rows = data.map( entry => (`<tr id="entry_${ entry.id }">` + Object.values( entry ).map( value => `<td>${ value }</td>` ).join( '' ) + '</tr>' )).join( '' );
// Merge it all together.
const table = `<table><thead>${ header }</thead><tbody>${ rows }</tbody></table>`;
// Render into the page.
document.querySelector( '#output' ).innerHTML = table;
};
// Sort of the property.
const sort = ( data, property ) => {
// Sort the data on the property in alphabetical order.
return data.sort(( first, second ) => {
if ( first[ property ] < second[ property ] ) return -1;
else if ( first[ property ] > second[ property ] ) return 1;
else return 0;
});
};
// Add click events to the header so that clicking a header will sort the rows.
const add_sorting = function( table ) {
Array
.from( table.querySelectorAll( 'th' ))
.forEach( header => header.addEventListener( 'click', create_table ));
};
// Main function
const create_table = event => {
// We'll reuse this function both manually and through clicking
const property = event && event.target
? event.target.getAttribute( 'data-attr' )
: event;
const collection = sort( source_data, property );
render( source_name, collection );
add_sorting( document.querySelector( 'table' ));
};
create_table( 'name' );
th, td {
border: 1px solid grey;
}
<div id="output"></div>
// Name of the data we're rendering.
const source_name = 'Locations';
// Source data we want to create a table from.
const source_data = [
{ "id": 1, "name": "production hall", "department": "production", "status": "inside" },
{ "id": 2, "name": "spare parts room", "department": "production", "status": "inside" },
{ "id": 3, "name": "warehouse", "department": "production", "status": "inside" },
{ "id": 4, "name": "loading bay", "department": "production", "status": "outside" },
{ "id": 5, "name": "offices HR", "department": "administration", "status": "inside" },
{ "id": 6, "name": "offices QA", "department": "administration", "status": "inside" },
{ "id": 7, "name": "security lounge", "department": "administration", "status": "outside" }
];
// Create the table.
// For this example, we'll use string manipulation to create the HTML.
// For complex layouts a templating system is better.
const render = ( name, data ) => {
// Always include a header for the name.
// When there's 0 rows, we'll still know what the table shows.
const labels = data.length
? '<tr>' + Object.keys( data[ 0 ]).map( name => `<th data-attr="${ name }">${ name }</th>` ).join( '' ) + '</tr>'
: '';
// Actual header for the properties of our data.
const header = `<tr><th colspan="${ data.length || 1 }">${ name }</th></tr>${ labels }`;
// One row for each entry in our data.
const rows = data.map( entry => (`<tr id="entry_${ entry.id }">` + Object.values( entry ).map( value => `<td>${ value }</td>` ).join( '' ) + '</tr>' )).join( '' );
// Merge it all together.
const table = `<table><thead>${ header }</thead><tbody>${ rows }</tbody></table>`;
// Render into the page.
document.querySelector( '#output' ).innerHTML = table;
};
// Sort of the property.
const sort = ( data, property ) => {
// Sort the data on the property in alphabetical order.
return data.sort(( first, second ) => {
if ( first[ property ] < second[ property ] ) return -1;
else if ( first[ property ] > second[ property ] ) return 1;
else return 0;
});
};
// Add click events to the header so that clicking a header will sort the rows.
const add_sorting = function( table ) {
Array
.from( table.querySelectorAll( 'th' ))
.forEach( header => header.addEventListener( 'click', create_table ));
};
// Main function
const create_table = event => {
// We'll reuse this function both manually and through clicking
const property = event && event.target
? event.target.getAttribute( 'data-attr' )
: event;
const collection = sort( source_data, property );
render( source_name, collection );
add_sorting( document.querySelector( 'table' ));
};
create_table( 'name' );
th, td {
border: 1px solid grey;
}
<div id="output"></div>
edited Nov 22 '18 at 15:38
answered Nov 22 '18 at 15:33
ShillyShilly
5,4231616
5,4231616
add a comment |
add a comment |
A table section can easily be sorted according to a comparator function (e.g. "is this cell supposed to appear before that cell?", Math.min
, for example) using any comparison sort algorithm, here demonstrating the insertion sort, less than 10 lines of actual table sorting code:
class InsertionSort {
static sort_children(parent, comparator) {
for(let i = 0; i != parent.children.length; i++) {
const current = parent.children[i];
let element;
for(element = current.previousElementSibling; element && comparator(current, element); element = element.previousElementSibling);
parent.insertBefore(current, element ? element.nextElementSibling : parent.firstElementChild);
}
}
}
Having a table section (or a table) (the parent
argument to sort_children
above) with an amount of rows as children, you can sort it with the sort_children
method defined above, as long as you yourself rightfully define how your rows should compare:
InsertionSort.sort_children(your_table, (row_A, row_B) => row_A.cells[0].textContent < row_B.cells[0].textContent);
The above sorts table rows so that the cells of the first column appear in lexicographical order.
The second argument to sort_children
is the aforementioned comparator function comparator(row_A, row_B)
, which is expected to return true
for any two rows it is passed where row_A
should appear before row_B
, and false
otherwise. Since you provide the comparator function, you decide how your rows are sorted.
You can further adapt the comparator function by creating a function that returns a comparator which would be specific to a particular table column, according to a value format (text, number, etc), using the <
operator automatically (which is defined for Number
and String
, among other types):
const table_cell_comparator = (column_index, type) => ((row_A, row_B) => type(row_A.cells[column_index].textContent) < type(row_A.cells[column_index].textContent));
Then invoking table sorting with a less verbose and more readable expression:
InsertionSort.sort_children(your_table, table_cell_comparator(1, Number));
The above sorts the rows so that cells of second column with lower numeric value appear before cells with higher numeric value.
add a comment |
A table section can easily be sorted according to a comparator function (e.g. "is this cell supposed to appear before that cell?", Math.min
, for example) using any comparison sort algorithm, here demonstrating the insertion sort, less than 10 lines of actual table sorting code:
class InsertionSort {
static sort_children(parent, comparator) {
for(let i = 0; i != parent.children.length; i++) {
const current = parent.children[i];
let element;
for(element = current.previousElementSibling; element && comparator(current, element); element = element.previousElementSibling);
parent.insertBefore(current, element ? element.nextElementSibling : parent.firstElementChild);
}
}
}
Having a table section (or a table) (the parent
argument to sort_children
above) with an amount of rows as children, you can sort it with the sort_children
method defined above, as long as you yourself rightfully define how your rows should compare:
InsertionSort.sort_children(your_table, (row_A, row_B) => row_A.cells[0].textContent < row_B.cells[0].textContent);
The above sorts table rows so that the cells of the first column appear in lexicographical order.
The second argument to sort_children
is the aforementioned comparator function comparator(row_A, row_B)
, which is expected to return true
for any two rows it is passed where row_A
should appear before row_B
, and false
otherwise. Since you provide the comparator function, you decide how your rows are sorted.
You can further adapt the comparator function by creating a function that returns a comparator which would be specific to a particular table column, according to a value format (text, number, etc), using the <
operator automatically (which is defined for Number
and String
, among other types):
const table_cell_comparator = (column_index, type) => ((row_A, row_B) => type(row_A.cells[column_index].textContent) < type(row_A.cells[column_index].textContent));
Then invoking table sorting with a less verbose and more readable expression:
InsertionSort.sort_children(your_table, table_cell_comparator(1, Number));
The above sorts the rows so that cells of second column with lower numeric value appear before cells with higher numeric value.
add a comment |
A table section can easily be sorted according to a comparator function (e.g. "is this cell supposed to appear before that cell?", Math.min
, for example) using any comparison sort algorithm, here demonstrating the insertion sort, less than 10 lines of actual table sorting code:
class InsertionSort {
static sort_children(parent, comparator) {
for(let i = 0; i != parent.children.length; i++) {
const current = parent.children[i];
let element;
for(element = current.previousElementSibling; element && comparator(current, element); element = element.previousElementSibling);
parent.insertBefore(current, element ? element.nextElementSibling : parent.firstElementChild);
}
}
}
Having a table section (or a table) (the parent
argument to sort_children
above) with an amount of rows as children, you can sort it with the sort_children
method defined above, as long as you yourself rightfully define how your rows should compare:
InsertionSort.sort_children(your_table, (row_A, row_B) => row_A.cells[0].textContent < row_B.cells[0].textContent);
The above sorts table rows so that the cells of the first column appear in lexicographical order.
The second argument to sort_children
is the aforementioned comparator function comparator(row_A, row_B)
, which is expected to return true
for any two rows it is passed where row_A
should appear before row_B
, and false
otherwise. Since you provide the comparator function, you decide how your rows are sorted.
You can further adapt the comparator function by creating a function that returns a comparator which would be specific to a particular table column, according to a value format (text, number, etc), using the <
operator automatically (which is defined for Number
and String
, among other types):
const table_cell_comparator = (column_index, type) => ((row_A, row_B) => type(row_A.cells[column_index].textContent) < type(row_A.cells[column_index].textContent));
Then invoking table sorting with a less verbose and more readable expression:
InsertionSort.sort_children(your_table, table_cell_comparator(1, Number));
The above sorts the rows so that cells of second column with lower numeric value appear before cells with higher numeric value.
A table section can easily be sorted according to a comparator function (e.g. "is this cell supposed to appear before that cell?", Math.min
, for example) using any comparison sort algorithm, here demonstrating the insertion sort, less than 10 lines of actual table sorting code:
class InsertionSort {
static sort_children(parent, comparator) {
for(let i = 0; i != parent.children.length; i++) {
const current = parent.children[i];
let element;
for(element = current.previousElementSibling; element && comparator(current, element); element = element.previousElementSibling);
parent.insertBefore(current, element ? element.nextElementSibling : parent.firstElementChild);
}
}
}
Having a table section (or a table) (the parent
argument to sort_children
above) with an amount of rows as children, you can sort it with the sort_children
method defined above, as long as you yourself rightfully define how your rows should compare:
InsertionSort.sort_children(your_table, (row_A, row_B) => row_A.cells[0].textContent < row_B.cells[0].textContent);
The above sorts table rows so that the cells of the first column appear in lexicographical order.
The second argument to sort_children
is the aforementioned comparator function comparator(row_A, row_B)
, which is expected to return true
for any two rows it is passed where row_A
should appear before row_B
, and false
otherwise. Since you provide the comparator function, you decide how your rows are sorted.
You can further adapt the comparator function by creating a function that returns a comparator which would be specific to a particular table column, according to a value format (text, number, etc), using the <
operator automatically (which is defined for Number
and String
, among other types):
const table_cell_comparator = (column_index, type) => ((row_A, row_B) => type(row_A.cells[column_index].textContent) < type(row_A.cells[column_index].textContent));
Then invoking table sorting with a less verbose and more readable expression:
InsertionSort.sort_children(your_table, table_cell_comparator(1, Number));
The above sorts the rows so that cells of second column with lower numeric value appear before cells with higher numeric value.
edited Nov 22 '18 at 23:53
answered Nov 22 '18 at 17:01
amnamn
3,95053262
3,95053262
add a comment |
add a comment |
"Filtering" a table, as it is called, with existing rows, can easily be done with class toggling, among other things:
function filter_table(section, predicate) {
for(const row of section.rows) row.classList.toggle("filtered", predicate(row));
}
What happens above is that rows of an entire table or table section (section
above) that the predicate
function considers "filtered", are marked as such by toggling the "filtered" class on these.
The predicate
function is a function of your own design and choosing that accepts a table row and returns true
if the row should be filtered or false
otherwise.
Taking your use case with employee rows, for instance, where let's say the 3rd table cell of every row contains a select
(drop-down) control with one option for "In" and one option for "Out":
<tr><!-- ... --><td><select><option value="in">In</option><option value="out">Out</option></select></tr>
You can write the predicate that will filter employee rows according to either "In" or "Out" status ("in" in the example), as follows:
const predicate = row => row.cells[2].firstElementChild.value == "in";
How you style filtered rows is up to you, you may want to simply hide them, of course:
tr.filtered {
display: none;
}
Since the status of each employee effectively changes with the change in drop-down selection, you would be wasting resources by invoking filter_table
for every such change, which then would go through all the rows again. It is then a much better idea to listen on the "change" event that would be fired by the select
control as it changes its value:
table.addEventListener("change", event => {
if(event.target instanceof HTMLSelectElement) {
const row = event.target.parentElement.parentElement;
row.classList.toggle("filtered", predicate(row));
}
})
You only need to attach a single listener to the entire table -- "change" events bubble up the element tree. The predicate
function defined above is reused, but for the single changed row only.
P.S. Before anyone chooses to jump the wagon so to speak, and recommend use of the hidden
attribute, I don't consider it appropriate here, without more information in the question -- a filtered row is not an invalid/inapplicable document node, it may only be filtered temporarily, for instance, to aid reading the table according to a variable. Unless you actually want to remove such rows, then it's different. I believe the question as it stands asks for "perceptive" filtering.
this is exactly what I've been looking for,but if you could only help me with the implementation of this certain code because functions are not working(begginer at js sorry)
– Em44
Nov 26 '18 at 12:41
Use MDN to learn JavaScript to a point where the answer makes sense -- thefor ... of
loop, theclassList
property, theHTMLTableElement
, what the DOM is and how it works, etc. MDN is a great resource! Be careful with random blogs on Internet -- not all who write know their stuff.
– amn
Nov 26 '18 at 14:59
add a comment |
"Filtering" a table, as it is called, with existing rows, can easily be done with class toggling, among other things:
function filter_table(section, predicate) {
for(const row of section.rows) row.classList.toggle("filtered", predicate(row));
}
What happens above is that rows of an entire table or table section (section
above) that the predicate
function considers "filtered", are marked as such by toggling the "filtered" class on these.
The predicate
function is a function of your own design and choosing that accepts a table row and returns true
if the row should be filtered or false
otherwise.
Taking your use case with employee rows, for instance, where let's say the 3rd table cell of every row contains a select
(drop-down) control with one option for "In" and one option for "Out":
<tr><!-- ... --><td><select><option value="in">In</option><option value="out">Out</option></select></tr>
You can write the predicate that will filter employee rows according to either "In" or "Out" status ("in" in the example), as follows:
const predicate = row => row.cells[2].firstElementChild.value == "in";
How you style filtered rows is up to you, you may want to simply hide them, of course:
tr.filtered {
display: none;
}
Since the status of each employee effectively changes with the change in drop-down selection, you would be wasting resources by invoking filter_table
for every such change, which then would go through all the rows again. It is then a much better idea to listen on the "change" event that would be fired by the select
control as it changes its value:
table.addEventListener("change", event => {
if(event.target instanceof HTMLSelectElement) {
const row = event.target.parentElement.parentElement;
row.classList.toggle("filtered", predicate(row));
}
})
You only need to attach a single listener to the entire table -- "change" events bubble up the element tree. The predicate
function defined above is reused, but for the single changed row only.
P.S. Before anyone chooses to jump the wagon so to speak, and recommend use of the hidden
attribute, I don't consider it appropriate here, without more information in the question -- a filtered row is not an invalid/inapplicable document node, it may only be filtered temporarily, for instance, to aid reading the table according to a variable. Unless you actually want to remove such rows, then it's different. I believe the question as it stands asks for "perceptive" filtering.
this is exactly what I've been looking for,but if you could only help me with the implementation of this certain code because functions are not working(begginer at js sorry)
– Em44
Nov 26 '18 at 12:41
Use MDN to learn JavaScript to a point where the answer makes sense -- thefor ... of
loop, theclassList
property, theHTMLTableElement
, what the DOM is and how it works, etc. MDN is a great resource! Be careful with random blogs on Internet -- not all who write know their stuff.
– amn
Nov 26 '18 at 14:59
add a comment |
"Filtering" a table, as it is called, with existing rows, can easily be done with class toggling, among other things:
function filter_table(section, predicate) {
for(const row of section.rows) row.classList.toggle("filtered", predicate(row));
}
What happens above is that rows of an entire table or table section (section
above) that the predicate
function considers "filtered", are marked as such by toggling the "filtered" class on these.
The predicate
function is a function of your own design and choosing that accepts a table row and returns true
if the row should be filtered or false
otherwise.
Taking your use case with employee rows, for instance, where let's say the 3rd table cell of every row contains a select
(drop-down) control with one option for "In" and one option for "Out":
<tr><!-- ... --><td><select><option value="in">In</option><option value="out">Out</option></select></tr>
You can write the predicate that will filter employee rows according to either "In" or "Out" status ("in" in the example), as follows:
const predicate = row => row.cells[2].firstElementChild.value == "in";
How you style filtered rows is up to you, you may want to simply hide them, of course:
tr.filtered {
display: none;
}
Since the status of each employee effectively changes with the change in drop-down selection, you would be wasting resources by invoking filter_table
for every such change, which then would go through all the rows again. It is then a much better idea to listen on the "change" event that would be fired by the select
control as it changes its value:
table.addEventListener("change", event => {
if(event.target instanceof HTMLSelectElement) {
const row = event.target.parentElement.parentElement;
row.classList.toggle("filtered", predicate(row));
}
})
You only need to attach a single listener to the entire table -- "change" events bubble up the element tree. The predicate
function defined above is reused, but for the single changed row only.
P.S. Before anyone chooses to jump the wagon so to speak, and recommend use of the hidden
attribute, I don't consider it appropriate here, without more information in the question -- a filtered row is not an invalid/inapplicable document node, it may only be filtered temporarily, for instance, to aid reading the table according to a variable. Unless you actually want to remove such rows, then it's different. I believe the question as it stands asks for "perceptive" filtering.
"Filtering" a table, as it is called, with existing rows, can easily be done with class toggling, among other things:
function filter_table(section, predicate) {
for(const row of section.rows) row.classList.toggle("filtered", predicate(row));
}
What happens above is that rows of an entire table or table section (section
above) that the predicate
function considers "filtered", are marked as such by toggling the "filtered" class on these.
The predicate
function is a function of your own design and choosing that accepts a table row and returns true
if the row should be filtered or false
otherwise.
Taking your use case with employee rows, for instance, where let's say the 3rd table cell of every row contains a select
(drop-down) control with one option for "In" and one option for "Out":
<tr><!-- ... --><td><select><option value="in">In</option><option value="out">Out</option></select></tr>
You can write the predicate that will filter employee rows according to either "In" or "Out" status ("in" in the example), as follows:
const predicate = row => row.cells[2].firstElementChild.value == "in";
How you style filtered rows is up to you, you may want to simply hide them, of course:
tr.filtered {
display: none;
}
Since the status of each employee effectively changes with the change in drop-down selection, you would be wasting resources by invoking filter_table
for every such change, which then would go through all the rows again. It is then a much better idea to listen on the "change" event that would be fired by the select
control as it changes its value:
table.addEventListener("change", event => {
if(event.target instanceof HTMLSelectElement) {
const row = event.target.parentElement.parentElement;
row.classList.toggle("filtered", predicate(row));
}
})
You only need to attach a single listener to the entire table -- "change" events bubble up the element tree. The predicate
function defined above is reused, but for the single changed row only.
P.S. Before anyone chooses to jump the wagon so to speak, and recommend use of the hidden
attribute, I don't consider it appropriate here, without more information in the question -- a filtered row is not an invalid/inapplicable document node, it may only be filtered temporarily, for instance, to aid reading the table according to a variable. Unless you actually want to remove such rows, then it's different. I believe the question as it stands asks for "perceptive" filtering.
answered Nov 23 '18 at 14:11
amnamn
3,95053262
3,95053262
this is exactly what I've been looking for,but if you could only help me with the implementation of this certain code because functions are not working(begginer at js sorry)
– Em44
Nov 26 '18 at 12:41
Use MDN to learn JavaScript to a point where the answer makes sense -- thefor ... of
loop, theclassList
property, theHTMLTableElement
, what the DOM is and how it works, etc. MDN is a great resource! Be careful with random blogs on Internet -- not all who write know their stuff.
– amn
Nov 26 '18 at 14:59
add a comment |
this is exactly what I've been looking for,but if you could only help me with the implementation of this certain code because functions are not working(begginer at js sorry)
– Em44
Nov 26 '18 at 12:41
Use MDN to learn JavaScript to a point where the answer makes sense -- thefor ... of
loop, theclassList
property, theHTMLTableElement
, what the DOM is and how it works, etc. MDN is a great resource! Be careful with random blogs on Internet -- not all who write know their stuff.
– amn
Nov 26 '18 at 14:59
this is exactly what I've been looking for,but if you could only help me with the implementation of this certain code because functions are not working(begginer at js sorry)
– Em44
Nov 26 '18 at 12:41
this is exactly what I've been looking for,but if you could only help me with the implementation of this certain code because functions are not working(begginer at js sorry)
– Em44
Nov 26 '18 at 12:41
Use MDN to learn JavaScript to a point where the answer makes sense -- the
for ... of
loop, the classList
property, the HTMLTableElement
, what the DOM is and how it works, etc. MDN is a great resource! Be careful with random blogs on Internet -- not all who write know their stuff.– amn
Nov 26 '18 at 14:59
Use MDN to learn JavaScript to a point where the answer makes sense -- the
for ... of
loop, the classList
property, the HTMLTableElement
, what the DOM is and how it works, etc. MDN is a great resource! Be careful with random blogs on Internet -- not all who write know their stuff.– amn
Nov 26 '18 at 14:59
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53408465%2fhow-to-sort-tables-with-js-html%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Have you considered sorting the data and then rendering the sorted data? I'd imagine it would be a little faster as you wouldn't initially have to read all of the data from the DOM.
– JO3-W3B-D3V
Nov 21 '18 at 9:04
2
You usually don't actually sort rows. If you use a render() function that turns an array of data objects into a HTML table to render the table you have, you can just sort that array of source data using the array.sort() method and then just rerender the table.
– Shilly
Nov 21 '18 at 9:04
@Shilly I'm glad to see we're on the same page here!
– JO3-W3B-D3V
Nov 21 '18 at 9:05
I m new to javascript so any code would be useful
– Em44
Nov 21 '18 at 9:13
@Shilly are you going to post some code or ?
– Em44
Nov 22 '18 at 13:43