最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - sorting the table when user click on the column - Stack Overflow

programmeradmin4浏览0评论

I have the html table which populated the dynamic values from json(written in the javascript code). When user click on any column header in the table, the table should sort accordingly. Any suggestions would be helpful.

When user click on the column the table should sort ascending and then descending if user clicks for the second time on the same column.

Demo /

Sample code below:

function CreateTableFromJSON() {
        var myBooks = [
            {
                "Book ID": "1",
                "Book Name": "Computer Architecture",
                "Category": "Computers",
                "Price": "125.60"
            },
            {
                "Book ID": "2",
                "Book Name": "Asp.Net 4 Blue Book",
                "Category": "Programming",
                "Price": "56.00"
            },
            {
                "Book ID": "3",
                "Book Name": "Popular Science",
                "Category": "Science",
                "Price": "210.40"
            }
        ]

        // EXTRACT VALUE FOR HTML HEADER. 
        // ('Book ID', 'Book Name', 'Category' and 'Price')
        var col = [];
        for (var i = 0; i < myBooks.length; i++) {
            for (var key in myBooks[i]) {
                if (col.indexOf(key) === -1) {
                    col.push(key);
                }
            }
        }
        var table = document.getElementById("resulttable");
 var tr = table.insertRow(1);   

        // ADD JSON DATA TO THE TABLE AS ROWS.
        for (var i = 0; i < myBooks.length; i++) {

            tr = table.insertRow(-1);

            for (var j = 0; j < col.length; j++) {
                var tabCell = tr.insertCell(-1);
                tabCell.innerHTML = myBooks[i][col[j]];
            }
        }

        // FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
        var divContainer = document.getElementById("showData");
        divContainer.innerHTML = "";
        divContainer.appendChild(table);
    }
<!DOCTYPE html>
<html>
<head>
<script src=".6.9/angular.min.js"></script>
    <title>Convert JSON Data to HTML Table</title>
    <style>
        th, td, p, input {
            font:14px Verdana;
        }
        table, th, td 
        {
            border: solid 1px #DDD;
            border-collapse: collapse;
            padding: 2px 3px;
            text-align: center;
        }
        th {
            font-weight:bold;
        }
    </style>
</head>
<body onload="CreateTableFromJSON()" > 
<table class="fdt-datatable" id="resulttable" name="resulttable">
            <tbody>
            <tr>
                <th name = "bookID"> Book ID</th>
                <th name = "bookName"> Book Name</th>
                <th name = "category"> Category</th>
                <th name = "price"> Price</th>
                </tr>
                </tbody>
                </table>
    <p id="showData"></p>
</body>
 
</html>

I have the html table which populated the dynamic values from json(written in the javascript code). When user click on any column header in the table, the table should sort accordingly. Any suggestions would be helpful.

When user click on the column the table should sort ascending and then descending if user clicks for the second time on the same column.

Demo https://jsfiddle/o2ram4tu/

Sample code below:

function CreateTableFromJSON() {
        var myBooks = [
            {
                "Book ID": "1",
                "Book Name": "Computer Architecture",
                "Category": "Computers",
                "Price": "125.60"
            },
            {
                "Book ID": "2",
                "Book Name": "Asp.Net 4 Blue Book",
                "Category": "Programming",
                "Price": "56.00"
            },
            {
                "Book ID": "3",
                "Book Name": "Popular Science",
                "Category": "Science",
                "Price": "210.40"
            }
        ]

        // EXTRACT VALUE FOR HTML HEADER. 
        // ('Book ID', 'Book Name', 'Category' and 'Price')
        var col = [];
        for (var i = 0; i < myBooks.length; i++) {
            for (var key in myBooks[i]) {
                if (col.indexOf(key) === -1) {
                    col.push(key);
                }
            }
        }
        var table = document.getElementById("resulttable");
 var tr = table.insertRow(1);   

        // ADD JSON DATA TO THE TABLE AS ROWS.
        for (var i = 0; i < myBooks.length; i++) {

            tr = table.insertRow(-1);

            for (var j = 0; j < col.length; j++) {
                var tabCell = tr.insertCell(-1);
                tabCell.innerHTML = myBooks[i][col[j]];
            }
        }

        // FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
        var divContainer = document.getElementById("showData");
        divContainer.innerHTML = "";
        divContainer.appendChild(table);
    }
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis./ajax/libs/angularjs/1.6.9/angular.min.js"></script>
    <title>Convert JSON Data to HTML Table</title>
    <style>
        th, td, p, input {
            font:14px Verdana;
        }
        table, th, td 
        {
            border: solid 1px #DDD;
            border-collapse: collapse;
            padding: 2px 3px;
            text-align: center;
        }
        th {
            font-weight:bold;
        }
    </style>
</head>
<body onload="CreateTableFromJSON()" > 
<table class="fdt-datatable" id="resulttable" name="resulttable">
            <tbody>
            <tr>
                <th name = "bookID"> Book ID</th>
                <th name = "bookName"> Book Name</th>
                <th name = "category"> Category</th>
                <th name = "price"> Price</th>
                </tr>
                </tbody>
                </table>
    <p id="showData"></p>
</body>
 
</html>

Share asked May 14, 2019 at 16:08 user3684675user3684675 3814 gold badges8 silver badges34 bronze badges 5
  • 1 Datatable is best for this type of functionality. – Sanjay Commented May 14, 2019 at 16:14
  • why you dont use a third party ponent for this? – Umer Hayyat Commented May 14, 2019 at 16:15
  • What have you tried? I don't see any click listeners. Does it make sense for you to sort on the client? – malifa Commented May 14, 2019 at 16:16
  • You can: 1. Move myBooks into a higher closure 2. Reorder myBooks when the user click on the header 3. Destroy old data in your HTML table 4. recreate your HTML table from the reordered myBooks This is not optimal, but this is the simplest answer I can think. – Ngob Commented May 14, 2019 at 16:19
  • The naming of your object keys seems to be bad , use underscores or lowerCamelCase to name the keys so that you can access them in your sort function. Add onClick listener to the headers , pass the key you want to sort with , sort the object and re create your table !! – Mahesh Kumaran Commented May 14, 2019 at 16:31
Add a ment  | 

2 Answers 2

Reset to default 4

I edited your code and add some new staff fort sortering
Here is jsfiddle
Snippet is below

function CreateTableFromJSON() {
        var myBooks = [
            {
                "Book ID": "1",
                "Book Name": "Computer Architecture",
                "Category": "Computers",
                "Price": "125.60"
            },
            {
                "Book ID": "2",
                "Book Name": "Asp.Net 4 Blue Book",
                "Category": "Programming",
                "Price": "56.00"
            },
            {
                "Book ID": "3",
                "Book Name": "Popular Science",
                "Category": "Science",
                "Price": "210.40"
            }
        ]

        // EXTRACT VALUE FOR HTML HEADER. 
        // ('Book ID', 'Book Name', 'Category' and 'Price')
        var col = [];
        for (var i = 0; i < myBooks.length; i++) {
            for (var key in myBooks[i]) {
                if (col.indexOf(key) === -1) {
                    col.push(key);
                }
            }
        }
        var table = document.getElementById("resulttable");
        var tbody = document.getElementById("resulttable_body");
        var tr = tbody.insertRow(0);   

        // ADD JSON DATA TO THE TABLE AS ROWS.
        for (var i = 0; i < myBooks.length; i++) {

            tr = tbody.insertRow(-1);

            for (var j = 0; j < col.length; j++) {
                var tabCell = tr.insertCell(-1);
                tabCell.innerHTML = myBooks[i][col[j]];
            }
        }

        // FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
        var divContainer = document.getElementById("showData");
        divContainer.innerHTML = "";
        divContainer.appendChild(table);
    }

	
// FOR TABLE SORT
$(document).ready(function(){

var sortOrder = 1; // flag to toggle the sorting order
function getVal(elm, colIndex){
	var td = $(elm).children('td').eq(colIndex).text();
	if(typeof td !== "undefined"){
		var v = td.toUpperCase();
		if($.isNumeric(v)){
			v = parseInt(v,10);
		}
		return v;
	}
}

$(document).on('click', '.sortable', function(){
	var self = $(this);
	var colIndex = self.prevAll().length;
	var o = (sortOrder == 1) ? 'asc' : 'desc'; // you can use for css to show sort direction
	sortOrder *= -1; // toggle the sorting order
	
    $('.sortable').removeClass('asc').removeClass('desc');
    self.addClass(o);

	var tbody = self.closest("table").find("tbody");
	var tr = tbody.children("tr"); //.get();

    tr.sort(function(a, b) {
        var A = getVal(a, colIndex);
        var B = getVal(b, colIndex);

        if(A < B) {
            return -1*sortOrder;
        }
        if(A > B) {
            return 1*sortOrder;
        }
        return 0;
    });

    $.each(tr, function(index, row) {
		//console.dir(row)
        tbody.append(row);
    });

});

});
        th, td, p, input {
            font:14px Verdana;
        }
        table, th, td 
        {
            border: solid 1px #DDD;
            border-collapse: collapse;
            padding: 2px 3px;
            text-align: center;
        }
        th {
            font-weight:bold;
        }
<!DOCTYPE html>
<html>
<head>
    <script src="https://ajax.googleapis./ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <title>Convert JSON Data to HTML Table</title>
</head>
<body onload="CreateTableFromJSON()" > 
<table class="fdt-datatable" id="resulttable" name="resulttable">
<thead>
	<tr>
	<th name = "bookID" class="sortable"> Book ID</th>
	<th name = "bookName" class="sortable"> Book Name</th>
	<th name = "category" class="sortable"> Category</th>
	<th name = "price" class="sortable"> Price</th>
	</tr>
</thead>
<tbody id="resulttable_body">
</tbody>
</table>
<p id="showData"></p>
</body>
 
</html>

For your question from ent about this jsfiddle code

HTML part
You have table with everything in tbody. I separated row with th to thead and I have empty tbody. Because I need to separate header fields which is clickable, and to separate content which can be sort.
Important thing is to add class sortable on which column you want to be sortable. In this case all column is sortable except first with checkboxes

JavaScript part
I added var tbody = document.getElementById("resulttable_body"); and at the end all rows are added to our empty tbody.appendChild(row);
Mayor thing is that you created element input and you append input to table cell, which look like this image:

I've created td element and put input inside it

    //Multi Stage Checkbox creation
    tblCell = document.createElement('td');
    var input = document.createElement("INPUT");
    input.setAttribute("type", "checkbox");
    input.setAttribute("name", "");
    input.setAttribute("value", "");
    input.setAttribute("id", 1);
    tblCell.appendChild(input);
    tblCell.style.textAlign = 'center';
    row.appendChild(tblCell);
发布评论

评论列表(0)

  1. 暂无评论