No need to use DataTables Plugin anymore.

Table of Contents

Introduction

DataTables plugin is one of the jQuery plugins that converts a normal looking table into a DataTable which provides a lot of features like limiting the data in the table, searching the data in the table, sorting the fields of the table and pagination if there are more pages.

See the demo image below:

datatables sample
The image above shows the table being converted into a DataTable. It has search, pagination, sorting and limiting functionalities.

Let’s start coding the table and convert it into a datatable.

Creating a table in HTML

<!DOCTYPE html>
<html>
<head>
    <title>Your Own Datatables</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- fontawesome cdn -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="datatables">
    <h1>Your Own Datatable</h1>
    <div class="filters">
        <div class="limit">
            <label>Show</label>
            <!-- Create a select box to limit the number of rows to be displayed -->
            <select name="limit" id="limit">
                <option value="5">5</option>
                <option value="10">10</option>
                <option value="15">15</option>
                <option value="20">20</option>
            </select>
            <label>entries</label>
        </div>
        <div class="search">
            <!-- A search box to search the data -->
            <input type="text" id="search" onkeyup="" placeholder="Search here.." title="Search Here">
        </div>
    </div>
    <table id="datatable">
        <!-- add sorting icons -->
        <thead>
            <tr>
                <th>ID <i class="fa fa-sort"></i></th>
                <th>Name <i class="fa fa-sort"></i></th>
                <th>Age <i class="fa fa-sort"></i></th>
                <th>Salary <i class="fa fa-sort"></i></th>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>
    <div class="table_footer">
        <div class="info">
            <!-- This section will display number of rows displayed -->
        </div>
        <div class="pagination">
            <!-- This section will contain the pagination links -->
        </div>
    </div>
</div>

<script src="script.js"></script>
</body>
</html>

Style the components to make it look like DataTables

/* import roboto font */
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap');

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Roboto', sans-serif;
    background-color: #f5f5f5;
}

/* style datatables */
.datatables {
    display: flex;
    width: 600px;
    flex-direction: column;
    align-items: center;
    margin: 20px auto;
}

.datatables table {
    width: 100%;
}

.datatables table thead th, .datatables table thead td {
    padding: 10px 18px;
    border-bottom: 1px solid #111;
}

.datatables table tbody td {
    padding: 10px 18px;
    border-bottom: 1px solid #111;
    text-align: center;
}

.datatables table tbody tr:nth-child(odd) {
    background-color: #eee;
}

/* style filters */
.filters {
    display: flex;
    width: 100%;
    justify-content: space-between;
    align-items: center;
    margin: 20px 0;
}

/* style .filters #limit select box */
.filters #limit {
    width: 60px;
    height: 30px;
    border: 1px solid #111;
    border-radius: 5px;
    padding: 0 10px;
}

/* style .filters #search input */
.filters #search {
    width: 200px;
    height: 30px;
    border: 1px solid #111;
    border-radius: 5px;
    padding: 0 10px;
}

/* table footer */
.table_footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    margin: 20px 0;
}

/* style .datatables .pagination  */
.datatables .pagination {
    display: flex;
    justify-content: center;
    align-items: center;
}

.datatables .pagination a {
    width: 30px;
    height: 30px;
    border: 1px solid #111;
    border-radius: 5px;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 15px 5px;
    text-decoration:none;
    color: #333
}

.datatables .pagination a.active {
    background-color: #111;
    color: #fff;
}

JavaScript (Real magic is here)

// create an object of random data
var randomData = [
    { id: 1, name: 'John', age: 25, salary: 10000 },
    { id: 2, name: 'Peter', age: 30, salary: 20000 },
    { id: 3, name: 'Mary', age: 28, salary: 15000 },
    { id: 4, name: 'Jane', age: 35, salary: 30000 },
    { id: 5, name: 'Mark', age: 32, salary: 25000 },
    { id: 6, name: 'Bob', age: 40, salary: 40000 },
    { id: 7, name: 'Alice', age: 38, salary: 35000 },
    { id: 8, name: 'Steve', age: 45, salary: 50000 },
    { id: 9, name: 'Paul', age: 42, salary: 45000 },
    { id: 10, name: 'Mike', age: 50, salary: 60000 },
    { id: 11, name: 'John', age: 25, salary: 10000 },
    { id: 12, name: 'Peter', age: 30, salary: 20000 },
    { id: 13, name: 'Mary', age: 28, salary: 15000 },
    { id: 14, name: 'Jane', age: 35, salary: 30000 }
];

// loop through the array and display the data in the #datatable tbody
let row = '';
for (var i = 0; i < 5; i++) {
    var item = randomData[i];
    row += `<tr><td>${item.id}</td><td>${item.name}</td><td>${item.age}</td><td>${item.salary}</td></tr>`;
}

// show the info in .info
document.querySelector('.info').innerHTML = `Showing 1 to 5 of ${randomData.length} entries`;
document.querySelector('#datatable tbody').innerHTML = row;

// generate the number of pages based on the number of items and the number of items per page
var numberOfPages = Math.ceil(randomData.length / 5);

// create the pagination
var pagination = '';
for (var i = 0; i < numberOfPages; i++) {
    pagination += `<a class="page-link" href="#">${i + 1}</a>`;
}
document.querySelector('.pagination').innerHTML = pagination;

// add the active class to the first page
document.querySelector('.pagination a').classList.add('active');

// add the click event to the pagination
document.querySelector('.pagination').addEventListener('click', function (e) {
    e.preventDefault();

    // fetch the value of the pagination link clicked i.e., 1, 2, 3 etc.
    var page = e.target.innerHTML;

    // calculate the start and end of the data to be displayed
    var start = (page * 5) - 5;
    var end = start + 5;

    // loop through the array and display the data in the #datatable tbody
    var row = '';
    for (var i = start; i < end; i++) {
        var item = randomData[i];
        if(item === undefined) break;
        row += `<tr><td>${item.id}</td><td>${item.name}</td><td>${item.age}</td><td>${item.salary}</td></tr>`;
    }
    // if the end is greater than the length of the array, set the end to the length of the array
    end = end > randomData.length ? randomData.length : end;

    // show the info in .info
    document.querySelector('.info').innerHTML = `Showing ${start + 1} to ${end} of ${randomData.length} entries`;

    // display the data in the #datatable tbody
    document.querySelector('#datatable tbody').innerHTML = row;

    // remove the active class from the current active pagination link
    var current = document.querySelector('.pagination .active');
    current.classList.remove('active');

    // add the active class to the clicked pagination link
    e.target.classList.add('active');
});

// add listener to the number of entries select
document.querySelector('#limit').addEventListener('change', function (e) {
    // get the number of entries and convert the value to number
    var entries = Number(e.target.value);

    // generate the number of pages based on the number of items and the number of items per page
    var numberOfPages = Math.ceil(randomData.length / entries);

    // create the pagination
    var pagination = '';
    for (var i = 0; i < numberOfPages; i++) {
        pagination += `<a class="page-link" href="#">${i + 1}</a>`;
    }

    // add the pagination links to the .pagination div
    document.querySelector('.pagination').innerHTML = pagination;
    document.querySelector('.pagination a').classList.add('active');

    // calculate the start and end of the data to be displayed based on the page number and the number of entries
    var page = document.querySelector('.pagination a').innerHTML;
    var start = (page * entries) - entries;
    var end = start + entries;

    // loop through the array and display the data in the #datatable tbody
    var row = '';
    for (var i = start; i < end; i++) {
        var item = randomData[i];
        // if the item is undefined, break the loop
        if(item === undefined) break;
        row += `<tr><td>${item.id}</td><td>${item.name}</td><td>${item.age}</td><td>${item.salary}</td></tr>`;
    }
    // if the end is greater than the length of the array, set the end to the length of the array
    end = end > randomData.length ? randomData.length : end;

    // show the info in .info
    document.querySelector('.info').innerHTML = `Showing ${start + 1} to ${end} of ${randomData.length} entries`;

    // display the data in the #datatable tbody
    document.querySelector('#datatable tbody').innerHTML = row;
});

// add listener to the search input
document.querySelector('#search').addEventListener('keyup', function (e) {
    // get the search value
    var search = e.target.value;

    // filter the data based on the search value
    var filteredData = randomData.filter(function (item) {
        // return the item if the name, age or salary contains the search value
        return (item.name.toLowerCase().includes(search.toLowerCase()) || item.age.toString().includes(search)) || item.salary.toString().includes(search);
    });

    // generate the number of pages based on the number of items and the number of items per page
    var numberOfPages = Math.ceil(filteredData.length / 5);

    // create the pagination only if there is at least 1 page
    var pagination = '';
    if (numberOfPages > 0) {
        for (var i = 0; i < numberOfPages; i++) {
            pagination += `<a class="page-link" href="#">${i + 1}</a>`;
        }
        document.querySelector('.pagination').innerHTML = pagination;
        document.querySelector('.pagination a').classList.add('active');
    }
    var page = document.querySelector('.pagination a').innerHTML;

    // calculate the start and end of the data to be displayed based on the page number and the number of entries
    if (filteredData.length < 5) {
        var start = (page * filteredData.length) - filteredData.length;
        var end = start + filteredData.length;
    } else {
        var start = (page * 5) - 5;
        var end = start + 5;
    }

    // loop through the array and display the data in the #datatable tbody
    var row = '';
    for (var i = start; i < end; i++) {
        var item = filteredData[i];
        row += `<tr><td>${item.id}</td><td>${item.name}</td><td>${item.age}</td><td>${item.salary}</td></tr>`;
    }

    // if the filtered data is empty, display the No data found message
    if (filteredData.length === 0) {
        row = `<tr><td colspan="4" class="text-center">No data found</td></tr>`;
        // show the info in .info if no data found
        document.querySelector('.info').innerHTML = `Showing 0 of ${randomData.length} entries`;
    } else {
        end = end > randomData.length ? randomData.length : end;
        // show the info in .info if not empty
        document.querySelector('.info').innerHTML = `Showing ${start+1} to ${end} of ${randomData.length} entries`;
    }

    // display the data in the #datatable tbody
    document.querySelector('#datatable tbody').innerHTML = row;
});

// sort the fields when .fa-sort is clicked
document.querySelector('#datatable thead').addEventListener('click', function (e) {
    // get the field and order
    var field = e.target.dataset.field;
    var order = e.target.dataset.order;

    // sort the data based on the field and order
    var text = e.target.innerHTML;
    var className = e.target.className;
    if (className === 'fa fa-sort') {
        e.target.dataset.order = 'asc';
        e.target.className = '';
        e.target.className = 'fa fa-sort-asc';
        e.target.innerHTML = text;
    } else if (className === 'fa fa-sort-asc') {
        e.target.dataset.order = 'desc';
        e.target.className = '';
        e.target.className = 'fa fa-sort-desc';
        e.target.innerHTML = text;
    } else if (className === 'fa fa-sort-desc') {
        e.target.dataset.order = 'asc';
        e.target.className = '';
        e.target.className = 'fa fa-sort-asc';
        e.target.innerHTML = text;
    }

    // sort the data based on the field and order (using sort function)
    randomData.sort(function (a, b) {
        if (order === 'asc') {
            return a[field] > b[field] ? 1 : -1;
        } else {
            return a[field] < b[field] ? 1 : -1;
        }
    });

    // generate the number of pages based on the number of items and the number of items per page
    var page = document.querySelector('.pagination a.active').innerHTML;
    var start = (page * 5) - 5;
    var end = start + 5;
    var row = '';
    for (var i = start; i < end; i++) {
        var item = randomData[i];
        row += `<tr><td>${item.id}</td><td>${item.name}</td><td>${item.age}</td><td>${item.salary}</td></tr>`;
    }

    // display the data in the #datatable tbody
    document.querySelector('#datatable tbody').innerHTML = row;
});

Project Demo

Full Tutorial Coming Soon.

Get this tutorial as soon as it arrives and many more already there. Subscribe the YouTube channel below and enable the notifications.

https://youtube.com/@developeranil

Find More Projects

https://thinkshare.one/learn/projects/

If you have any issues, feel free to let me know by leaving a comment below.

Leave a Comment

Your email address will not be published. Required fields are marked *