Search code examples
javascripthtmljquerycss

How can I integrate pagination with the filter table function?


I have implemented a table with pagination and a filter function using jQuery. The pagination works fine, and the filter function successfully filters the table rows based on the input value. However, when I apply the filter, the pagination is not updated accordingly. I want the pagination to adjust based on the filtered results, so that only the relevant page numbers are displayed.

//full code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <!-- تضمين مكتبة jQuery -->
    <title>Pagination Example</title>

    <style>
        .pagination {
            display: flex;
            justify-content: center;
            margin-top: 20px;
        }

        .pagination a {
            margin: 0 5px;
            padding: 5px 10px;
            background-color: #f2f2f2;
            color: #333;
            text-decoration: none;
            border-radius: 3px;
        }

        .pagination a.active {
            background-color: #4CAF50;
            color: white;
        }
    </style>
</head>
<body>
    <input type="text" id="filter-input">
    <table id="data-table">
        <thead>
           <tr id="table-header">
              <th data-column="ALARM_DESC" data-order="asc">
                 ALARM_DESC
                 <div class="resize-handle"></div>
              </th>
              <th data-column="ALARM_NAME" data-order="asc">
                 ALARM_NAME
                 <div class="resize-handle"></div>
              </th>
              <th data-column="APPLICAITON" data-order="asc">
                 APPLICAITON
                 <div class="resize-handle"></div>
              </th>
              <th data-column="ALARM_PATH" data-order="asc">
                 ALARM_PATH
                 <div class="resize-handle"></div>
              </th>
           </tr>
        </thead>
        <tbody id="table-body">
         <tr class="high-priority">
            <td class="ALARM_DESC">first desc</td>
            <td class="ALARM_NAME">first name</td>
            <td class="APPLICAITON">first app</td>
            <td class="ALARM_PATH">first path</td>
    
         </tr>
           <tr class="high-priority">
              <td class="ALARM_DESC">Second desc</td>
              <td class="ALARM_NAME">Second name</td>
              <td class="APPLICAITON">second app</td>
              <td class="ALARM_PATH">second path</td>
      
           </tr>
           
           <tr class="high-priority">
            <td class="ALARM_DESC">third desc</td>
            <td class="ALARM_NAME">third name</td>
            <td class="APPLICAITON">third app</td>
            <td class="ALARM_PATH">third path</td>
    
         </tr>
         <tr class="high-priority">
            <td class="ALARM_DESC">four desc</td>
            <td class="ALARM_NAME">four name</td>
            <td class="APPLICAITON">four app</td>
            <td class="ALARM_PATH">four path</td>
    
         </tr>
         
        </tbody>
     </table>
     
     
     


     <script>
         $(document).ready(function() {
            add_pagination();
         })
        function add_pagination() {
            var rowsPerPage = 2; // عدد الصفوف في كل صفحة
            var $table = $('#data-table');
            var $tbody = $table.find('tbody');
            var $rows = $tbody.find('tr');
            var totalRows = $rows.length;
            var totalPages = Math.ceil(totalRows / rowsPerPage);
            var $pagination = $('<div class="pagination"></div>'); // إنشاء عنصر الترقيم

            // إضافة عنصر الترقيم إلى الصفحة
            $table.after($pagination);

            // إنشاء روابط الترقيم في العنصر
            for (var i = 1; i <= totalPages; i++) {
                var $link = $('<a href="#"></a>').text(i);
                $link.attr('data-page', i);
                $pagination.append($link);
            }

            // إظهار الصفوف المناسبة في الصفحة الأولى
            $rows.hide();
            $rows.slice(0, rowsPerPage).show();
            $pagination.find('a:first').addClass('active');

            // التبديل بين الصفحات
            $pagination.on('click', 'a', function(e) {
                e.preventDefault();
                var page = $(this).attr('data-page');
                var startIndex = (page - 1) * rowsPerPage;
                var endIndex = startIndex + rowsPerPage;

                $rows.hide();
                $rows.slice(startIndex, endIndex).show();

                $pagination.find('a').removeClass('active');
                $(this).addClass('active');
            });
        }

        
// تحديث الترقيم بعد عملية الفلترة
// تحديث الترقيم بعد عملية الفلترة
function updatePagination() {
    var $filteredRows = $tbody.find('tr:visible');
    var totalFilteredRows = $filteredRows.length;
    var totalPages = Math.ceil(totalFilteredRows / rowsPerPage);

    $pagination.empty(); // إزالة روابط الترقيم الحالية

    // إنشاء روابط الترقيم مرة أخرى
    for (var i = 1; i <= totalPages; i++) {
        var $link = $('<a href="#"></a>').text(i);
        $link.attr('data-page', i);
        $pagination.append($link);
    }

    // إظهار الصفوف المناسبة في الصفحة الأولى بعد التحديث
    $filteredRows.hide();
    $filteredRows.slice(0, rowsPerPage).show();
    $pagination.find('a:first').addClass('active');
}
// تنفيذ عملية الفلترة
function filterTable() {
    var input, filter, table, tr, td, i, j;
    input = document.getElementById("filter-input");
    filter = input.value.toUpperCase();
    table = document.getElementById("data-table");
    tr = table.getElementsByTagName("tr");

    for (i = 1; i < tr.length; i++) { // تجاهل الصف الأول (العناوين)
        var display = false;
        td = tr[i].getElementsByTagName("td");

        for (j = 0; j < td.length; j++) {
            var cell = td[j];
            if (cell) {
                var txtValue = cell.textContent || cell.innerText;
                if (txtValue.toUpperCase().indexOf(filter) > -1) {
                    display = true;
                    break;
                }
            }
        }

        if (display) {
            tr[i].style.display = "";
        } else {
            tr[i].style.display = "none";
        }
    }

    updatePagination(); // تحديث الترقيم بعد عملية الفلترة
}
var inputElement = document.getElementById("filter-input");
inputElement.addEventListener("keyup", filterTable);
inputElement.addEventListener("keyup", removeClassFromTd);

    </script>
</body>
</html>

I have tried adding the updatePagination() function to the filterTable() function, hoping that it would update the pagination after filtering the table. I expected the pagination to adjust based on the filtered results, showing only the relevant page numbers. However, the pagination remains unchanged, displaying all the page numbers even if some of the rows are filtered out.

I would appreciate any guidance on how to integrate the pagination with the filter function so that the pagination reflects the filtered results accurately. Thank you!


Solution

  • To integrate pagination with table filtering using jQuery, I encapsulated the functionality within a self-executing anonymous function for local scope management.

    I initialized pagination on document load ($(document).ready()) and bound the keyup event to update filtering dynamically, ensuring that pagination links reflect the filtered results accurately without global variable clutter.

    This approach streamlined the implementation by modularizing pagination creation (addPagination()), updating pagination links based on filtered rows (updatePagination()), and handling user input filtering (filterTable()) effectively.

    (function() {
        var rowsPerPage = 2;
        var $table = $('#data-table');
        var $tbody = $table.find('tbody');
        var $pagination = $('<div class="pagination"></div>');
    
        $(document).ready(function() {
            addPagination();
            $('#filter-input').on('keyup', filterTable);
        });
    
        function addPagination() {
            var $rows = $tbody.find('tr');
            var totalRows = $rows.length;
            var totalPages = Math.ceil(totalRows / rowsPerPage);
    
            $table.after($pagination);
    
            for (var i = 1; i <= totalPages; i++) {
                var $link = $('<a href="#"></a>').text(i);
                $link.attr('data-page', i);
                $pagination.append($link);
            }
    
            $rows.hide();
            $rows.slice(0, rowsPerPage).show();
            $pagination.find('a:first').addClass('active');
    
            $pagination.on('click', 'a', function(e) {
                e.preventDefault();
                var page = $(this).attr('data-page');
                var startIndex = (page - 1) * rowsPerPage;
                var endIndex = startIndex + rowsPerPage;
    
                $rows.hide();
                $rows.slice(startIndex, endIndex).show();
    
                $pagination.find('a').removeClass('active');
                $(this).addClass('active');
            });
        }
    
        function updatePagination() {
            var $rows = $tbody.find('tr');
            var $filteredRows = $tbody.find('tr:visible');
            var totalFilteredRows = $filteredRows.length;
            var totalPages = Math.ceil(totalFilteredRows / rowsPerPage);
    
            $pagination.empty();
    
            for (var i = 1; i <= totalPages; i++) {
                var $link = $('<a href="#"></a>').text(i);
                $link.attr('data-page', i);
                $pagination.append($link);
            }
    
            $filteredRows.hide();
            $filteredRows.slice(0, rowsPerPage).show();
            $pagination.find('a:first').addClass('active');
        }
    
        function filterTable() {
            var input = $('#filter-input').val().toUpperCase();
            var $rows = $tbody.find('tr');
    
            $rows.each(function() {
                var $row = $(this);
                var display = false;
    
                $row.find('td').each(function() {
                    var $cell = $(this);
                    var txtValue = $cell.text().toUpperCase();
    
                    if (txtValue.indexOf(input) > -1) {
                        display = true;
                        return false; // Exit the loop early if match found
                    }
                });
    
                if (display) {
                    $row.show();
                } else {
                    $row.hide();
                }
            });
    
            updatePagination();
        }
    })();
    .pagination {
        display: flex;
        justify-content: center;
        margin-top: 20px;
    }
    
    .pagination a {
        margin: 0 5px;
        padding: 5px 10px;
        background-color: #f2f2f2;
        color: #333;
        text-decoration: none;
        border-radius: 3px;
    }
    
    .pagination a.active {
        background-color: #4CAF50;
        color: white;
    }
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    
    <input type="text" id="filter-input">
    <table id="data-table">
        <thead>
           <tr id="table-header">
              <th data-column="ALARM_DESC" data-order="asc">
                 ALARM_DESC
                 <div class="resize-handle"></div>
              </th>
              <th data-column="ALARM_NAME" data-order="asc">
                 ALARM_NAME
                 <div class="resize-handle"></div>
              </th>
              <th data-column="APPLICAITON" data-order="asc">
                 APPLICAITON
                 <div class="resize-handle"></div>
              </th>
              <th data-column="ALARM_PATH" data-order="asc">
                 ALARM_PATH
                 <div class="resize-handle"></div>
              </th>
           </tr>
        </thead>
        <tbody id="table-body">
         <tr class="high-priority">
            <td class="ALARM_DESC">first desc</td>
            <td class="ALARM_NAME">first name</td>
            <td class="APPLICAITON">first app</td>
            <td class="ALARM_PATH">first path</td>
         </tr>
         <tr class="high-priority">
            <td class="ALARM_DESC">Second desc</td>
            <td class="ALARM_NAME">Second name</td>
            <td class="APPLICAITON">second app</td>
            <td class="ALARM_PATH">second path</td>
         </tr>
         <tr class="high-priority">
            <td class="ALARM_DESC">third desc</td>
            <td class="ALARM_NAME">third name</td>
            <td class="APPLICAITON">third app</td>
            <td class="ALARM_PATH">third path</td>
         </tr>
         <tr class="high-priority">
            <td class="ALARM_DESC">four desc</td>
            <td class="ALARM_NAME">four name</td>
            <td class="APPLICAITON">four app</td>
            <td class="ALARM_PATH">four path</td>
         </tr>
        </tbody>
    </table>