Create a Sortable HTML Table using Pure JavaScript Tutorial

In this tutorial, you can learn to create a simple Sortable HTML Table Data Order using only Pure JavaScrtip. This tutorial aims to provide students and beginners with a reference for learning to build an interactive Web application or website component. Here, I will be providing source code that demonstrates the creation of a simple HTML Table with sorting features and functionalities.

What is a Sortable HTML Table?

A sortable HTML Table is one of the most common and implemented components in web applications or websites. It is data that is shown in a table view and each column can be sorted in ascending or descending order. Ordering or Sorting column data are often triggered when the user clicks the column header.

Nowadays, there are a lot of JS libraries that allow the developer to initialize or implement a sorting feature to an HTML Table. Here, I will show you how to create a Sortable feature for the HTML Table column.

How to Create a Sortable HTML Table?

Sortable HTML Table can be achieved easily using Pure JavaScript without using other JS libraries. JavaScript comes with multiple useful built-in methods, functions, event listeners, and Web APIs and some of these became handy to build a sortable HTML table. We can simply create the HTML Table with the data we want to display and design it with CSS for how we wanted to the table to look. Then, we can initialize the sorting features using JavaScrtip. Check out the web application scripts that I provided below to know more and have a better idea of how to create a simple sortable HTML Table.

Sample Web Application

The following scripts result in a simple web page that contains static data. The data are shown in a table view where each column has a sortable link on the header that allows the users to sort the table data in ascending or descending order.

Page Interface

Here's the HTML file script known as index.html. The file contains the Page Layout and Table elements.

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <meta charset="UTF-8">
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  5. <title>HTML Table Sorting</title>
  6. <link rel="stylesheet" href="style.css">
  7. <link rel="preconnect" href="https://fonts.googleapis.com">
  8. <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  9. <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200" />
  10. </head>
  11. <div class="container">
  12. <h1 id="page-title">HTML Table Sorting using Pure JavaScript</h1>
  13. <hr id="title_hr">
  14. <div id="sortable-table-wrapper">
  15. <table id="sortable-tbl">
  16. <tr>
  17. <th>Code</th>
  18. <th>Name</th>
  19. <th>DOB</th>
  20. <th>Address</th>
  21. </tr>
  22. </thead>
  23. <tr>
  24. <td>1009</td>
  25. <td>Medge Wynn</td>
  26. <td>May 23, 1986</td>
  27. <td>Ap #597-2765 Arcu Street</td>
  28. </tr>
  29. <tr>
  30. <td>1015</td>
  31. <td>Yoshi Blanchard</td>
  32. <td>Apr 4, 1986</td>
  33. <td>Ap #114-8499 Pretium Rd.</td>
  34. </tr>
  35. <tr>
  36. <td>1041</td>
  37. <td>Denton Tyson</td>
  38. <td>Apr 22, 1992</td>
  39. <td>3846 Ipsum Street</td>
  40. </tr>
  41. <tr>
  42. <td>1021</td>
  43. <td>Mohammad Rosa</td>
  44. <td>Apr 15, 1992</td>
  45. <td>Ap #620-7967 Neque. Road</td>
  46. </tr>
  47. <tr>
  48. <td>1022</td>
  49. <td>Roth Beach</td>
  50. <td>Aug 12, 1994</td>
  51. <td>114-2482 Duis Avenue</td>
  52. </tr>
  53. <tr>
  54. <td>1049</td>
  55. <td>Jared Benton</td>
  56. <td>Mar 1, 1991</td>
  57. <td>P.O. Box 199, 5660 Quisque Rd.</td>
  58. </tr>
  59. <tr>
  60. <td>1030</td>
  61. <td>Kelsey Logan</td>
  62. <td>Sep 27, 1995</td>
  63. <td>Ap #666-8194 A Rd.</td>
  64. </tr>
  65. <tr>
  66. <td>1046</td>
  67. <td>Galena Jensen</td>
  68. <td>Feb 8, 1997</td>
  69. <td>Ap #675-3025 Dolor. Rd.</td>
  70. </tr>
  71. <tr>
  72. <td>1008</td>
  73. <td>Mariam Nolan</td>
  74. <td>May 12, 1987</td>
  75. <td>P.O. Box 240, 2164 Ornare St.</td>
  76. </tr>
  77. <tr>
  78. <td>1047</td>
  79. <td>Wyatt Mueller</td>
  80. <td>Jul 13, 1996</td>
  81. <td>977-104 Justo St.</td>
  82. </tr>
  83. </tbody>
  84. </table>
  85. </div>
  86. </div>
  87.  
  88. <script src="script.js"></script>
  89. </body>
  90. </html>

Stylesheet (CSS)

Next, here is the CSS file script known as style.css. This file contains the stylesheet codes for the page interface and table elements designs.

  1. @import url('https://fonts.googleapis.com/css2?family=Dongle:wght@300;400;700&family=Roboto+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;1,100;1,200;1,300;1,400;1,500;1,600&display=swap" rel="stylesheet');
  2. *{
  3. margin: 0;
  4. padding: 0;
  5. box-sizing: border-box;
  6. font-family: 'Dongle', sans-serif;
  7. font-family: 'Roboto Mono', monospace;
  8. }
  9. ::selection{
  10. color: #fff;
  11. background: #4db2ec;
  12. }
  13. body{
  14. display: flex;
  15. align-items: center;
  16. justify-content: center;
  17. min-height: 100vh;
  18. background: #4facfe;
  19. background-image: linear-gradient(to right, #4facfe 0%, #00f2fe 100%);
  20. padding: 2em 0;
  21. }
  22. #page-title{
  23. color: #fff;
  24. text-align: center;
  25. font-weight: 500;
  26. text-shadow: 0px 0px 15px #0000003a;
  27. }
  28. #title_hr{
  29. width:60px;
  30. border: 2px solid #ffffff;
  31. margin: .35em auto;
  32. }
  33. @media (min-width: 780px){
  34. #page-title{
  35. width: 780px;
  36. }
  37. }
  38. /* Table Wrapper */
  39. #sortable-table-wrapper{
  40. width: 700px;
  41. background-color: #fff;
  42. border: 1px solid #d1d1d1;
  43. padding: 1em .75em;
  44. margin: 1em auto;
  45. border-radius: 5px;
  46. box-shadow: 1px 1px 10px #00000046;
  47. overflow-y:auto;
  48. }
  49.  
  50. /* Table */
  51. #sortable-tbl{
  52. border-collapse:collapse;
  53. width: 100%;
  54. }
  55. /* Table Cell */
  56. #sortable-tbl th,#sortable-tbl td{
  57. border: 1px solid #cfcfcf;
  58. padding: .5em .35em;
  59. }
  60. /* Sortable Table Sort Link */
  61. .tableSortableClass a.tbl-sort-link {
  62. width: 100%;
  63. display: flex;
  64. justify-content: space-between;
  65. align-items: center;
  66. cursor: pointer;
  67. }
  68.  
  69. /* Sortable Table Sort Link Icon Holder */
  70. .tableSortableClass a.tbl-sort-link span.tbl-sort-order {
  71. display: flex;
  72. align-items: center;
  73. justify-content: center;
  74. }
  75. .tableSortableClass a.tbl-sort-link span.tbl-sort-order>span{
  76. color: #afafaf;
  77. font-size: 1.1rem;
  78. width: 13px;
  79. }
  80. .tableSortableClass a.tbl-sort-link span.tbl-sort-order>span.tbl-sort-order-desc{
  81. rotate: 180deg;
  82. }
  83. .tableSortableClass a.tbl-sort-link[data-sort="true"][data-order="asc"] span.tbl-sort-order>span:nth-child(1){
  84. color:#404040;
  85. }
  86. .tableSortableClass a.tbl-sort-link[data-sort="true"][data-order="desc"] span.tbl-sort-order>span:nth-child(2){
  87. color:#404040;
  88. }

JavaScript

Lastly, here is the JavaScript file script known as script.js. The file contains the JS codes that initialize the Sorting and makes it functional.

  1. // HTML Table Sorting Class
  2. class TableSorting {
  3. Table;
  4. col = 1;
  5. sortOrder = 'asc';
  6.  
  7. // Contructor Intitalize Default
  8. constructor(table, options = {}){
  9. // Set Table Element
  10. this.Table = table
  11.  
  12. // Set Default Sorting Column
  13. if(!!options.col){
  14. this.col = options.col
  15. }
  16. // Set Default Sorting Order
  17. if(!!options.sortOrder){
  18. this.sortOrder = options.sortOrder
  19. }
  20. // Add Sort Link to table header columns
  21. this.theadAddSort()
  22. }
  23.  
  24. theadAddSort(){
  25. // Adding Table Sort Class name for the design
  26. this.Table.classList.add('tableSortableClass')
  27. // Selecting the first thead row
  28. var theadRow = this.Table.querySelector('thead tr:nth-child(1)')
  29.  
  30. // Add Column sort link
  31. theadRow.querySelectorAll('th').forEach((el, idx) =>{
  32. // Get the column Text
  33. var thTxt = el.innerText
  34. // Increment Index to get the node child index
  35. idx += 1;
  36. // Creating a New Element as the sort link of the column
  37. var newContent = document.createElement('a')
  38. // adding class to the sort link
  39. newContent.classList.add('tbl-sort-link')
  40.  
  41. // Sort Link Content
  42. newContent.innerHTML = `<span class='tbl-sort-title'>${thTxt}</span>
  43. <span class="tbl-sort-order">
  44. <span class="tbl-sort-order-asc material-symbols-outlined">straight</span>
  45. <span class="tbl-sort-order-desc material-symbols-outlined">straight</span></span>`;
  46. // Clean the Column Content Temporarily
  47. el.innerHTML = '';
  48. // Inserting or Adding the New Column content to current column
  49. el.appendChild(newContent)
  50. // Sort Table Data
  51. this.orderData()
  52. })
  53.  
  54. // Updating Active Sorting Icon
  55. this.updateSortIcons()
  56. // Trigger for changing the table sort order
  57. this.changeSort()
  58. }
  59.  
  60. updateSortIcons(){
  61. // Select All the thead table row first child's table cel
  62. var theadRow = this.Table.querySelector('thead tr:nth-child(1)')
  63. theadRow.querySelectorAll('th').forEach((el, idx) =>{
  64. idx++;
  65. // add dataset to the sort link if the current sort column and this column index is equal
  66. if(idx == this.col){
  67. el.querySelector('a.tbl-sort-link').dataset.sort = 'true'
  68. el.querySelector('a.tbl-sort-link').dataset.order = this.sortOrder
  69. }
  70. })
  71. }
  72. orderData(){
  73. // variable to identify if there's data needed to reorder
  74. var hasSort = false;
  75. // Elements to reorder
  76. var reorder = [];
  77. // Selecting all the table body rows
  78. var trs = this.Table.querySelectorAll('tbody tr')
  79. trs.forEach((el, idx) => {
  80. // Check if this element has a next element, continue to the process if it does
  81. if(el.nextElementSibling != null){
  82.  
  83. if(this.sortOrder == `asc`){
  84. // Checking the Data Order if descending. If yes, store elements to reorder array
  85. if(el.querySelector(`td:nth-child(${this.col})`).innerText.toLowerCase() > el.nextElementSibling.querySelector(`td:nth-child(${this.col})`).innerText.toLowerCase()){
  86. hasSort = true
  87. reorder.push({eltoTransfer:el.nextElementSibling, transferBefore: el})
  88. }
  89. }else{
  90. // Checking the Data Order if ascending. If yes, store elements to reorder array
  91. if(el.querySelector(`td:nth-child(${this.col})`).innerText.toLowerCase() < el.nextElementSibling.querySelector(`td:nth-child(${this.col})`).innerText.toLowerCase()){
  92. hasSort = true
  93. reorder.push({eltoTransfer:el.nextElementSibling, transferBefore: el})
  94. }
  95. }
  96.  
  97. }
  98. })
  99. if(hasSort){
  100. // If there's data to reorder execute the transfer of elements
  101. reorder.forEach(data => {
  102. data.eltoTransfer.parentNode.insertBefore(data.eltoTransfer, data.transferBefore)
  103. })
  104. // Re-Check Order
  105. this.orderData()
  106. }
  107. }
  108. changeSort(){
  109. // Select All Sort Order Link
  110. this.Table.querySelectorAll('a.tbl-sort-link').forEach((el, idx)=>{
  111. // Iterate Index to get element child index
  112. idx++;
  113. // Add Click Event Listener to each sort link
  114. el.addEventListener('click', e => {
  115. // prevent default if link is clicked
  116. e.preventDefault()
  117. // getting the current element
  118. var currentCol = this.col
  119. if(currentCol == idx){
  120. // If current column and this element index is still the same, update only the sort order
  121. if(this.sortOrder == 'asc')
  122. this.sortOrder = 'desc';
  123. else
  124. this.sortOrder = 'asc';
  125. }else{
  126. // If the current Column is different to this element index
  127.  
  128. // set sorting order to asc by default
  129. this.sortOrder = `asc`
  130. // Getting the current sort order link element
  131. var currentColOrder = this.Table.querySelector(`a.tbl-sort-link[data-sort='true']`)
  132.  
  133. // Remove the sort ordering datasets to the current sort order link
  134. if(!!currentColOrder.dataset.sort)
  135. delete currentColOrder.dataset.sort;
  136.  
  137. if(!!currentColOrder.dataset.order)
  138. delete currentColOrder.dataset.order;
  139. // Update the sort column
  140. this.col = idx
  141. }
  142. // Update Sort Icons
  143. this.updateSortIcons()
  144. // Update Table sort order
  145. this.orderData()
  146. })
  147. })
  148. }
  149.  
  150. }
  151. // Select Table Element to Sort
  152. const table = document.getElementById('sortable-tbl')
  153. // Initialize Sortaing Table
  154. const sortTable = new TableSorting(table, {col:2, sortOrder: 'asc'})

Snapshots

Here are some snapshots of the overall result of the file scripts that I provided.

Page Interface

Sortable HTML Table using JavaScript

Sample Sort #1 (column 1 in ascending order)

Sortable HTML Table using JavaScript

Sample Sort #2 (column 1 in descending order)

Sortable HTML Table using JavaScript

Sample Sort #3 (column 2 in descending order)

Sortable HTML Table using JavaScript

There you go! I have provided also the complete source code zip file of the web application scripts that I provided on this website and it is free to download. The download button is located below this tutorial's content. Feel free to download and modify the source code the way you wanted to meet your own requirements and enhance your programming capabilities.

DEMO VIDEO

That's it! I hope this Create a Sortable HTML Table using Pure JavaScript Tutorial will help you with what you are looking for and will be useful for your current and future web application projects.

Explore more on this website for more Tutorials and Free Source Codes.

Happy Coding =)

Add new comment