[javascript] Simple pagination in javascript

A simple client-side pagination example where data is fetched only once at page loading.

_x000D_
_x000D_
// dummy data_x000D_
        const myarr = [{ "req_no": 1, "title": "test1" },_x000D_
        { "req_no": 2, "title": "test2" },_x000D_
        { "req_no": 3, "title": "test3" },_x000D_
        { "req_no": 4, "title": "test4" },_x000D_
        { "req_no": 5, "title": "test5" },_x000D_
        { "req_no": 6, "title": "test6" },_x000D_
        { "req_no": 7, "title": "test7" },_x000D_
        { "req_no": 8, "title": "test8" },_x000D_
        { "req_no": 9, "title": "test9" },_x000D_
        { "req_no": 10, "title": "test10" },_x000D_
        { "req_no": 11, "title": "test11" },_x000D_
        { "req_no": 12, "title": "test12" },_x000D_
        { "req_no": 13, "title": "test13" },_x000D_
        { "req_no": 14, "title": "test14" },_x000D_
        { "req_no": 15, "title": "test15" },_x000D_
        { "req_no": 16, "title": "test16" },_x000D_
        { "req_no": 17, "title": "test17" },_x000D_
        { "req_no": 18, "title": "test18" },_x000D_
        { "req_no": 19, "title": "test19" },_x000D_
        { "req_no": 20, "title": "test20" },_x000D_
        { "req_no": 21, "title": "test21" },_x000D_
        { "req_no": 22, "title": "test22" },_x000D_
        { "req_no": 23, "title": "test23" },_x000D_
        { "req_no": 24, "title": "test24" },_x000D_
        { "req_no": 25, "title": "test25" },_x000D_
        { "req_no": 26, "title": "test26" }];_x000D_
_x000D_
        // on page load collect data to load pagination as well as table_x000D_
        const data = { "req_per_page": document.getElementById("req_per_page").value, "page_no": 1 };_x000D_
_x000D_
        // At a time maximum allowed pages to be shown in pagination div_x000D_
        const pagination_visible_pages = 4;_x000D_
_x000D_
_x000D_
        // hide pages from pagination from beginning if more than pagination_visible_pages_x000D_
        function hide_from_beginning(element) {_x000D_
            if (element.style.display === "" || element.style.display === "block") {_x000D_
                element.style.display = "none";_x000D_
            } else {_x000D_
                hide_from_beginning(element.nextSibling);_x000D_
            }_x000D_
        }_x000D_
        _x000D_
        // hide pages from pagination ending if more than pagination_visible_pages_x000D_
        function hide_from_end(element) {_x000D_
            if (element.style.display === "" || element.style.display === "block") {_x000D_
                element.style.display = "none";_x000D_
            } else {_x000D_
                hide_from_beginning(element.previousSibling);_x000D_
            }_x000D_
        }_x000D_
        _x000D_
        // load data and style for active page_x000D_
        function active_page(element, rows, req_per_page) {_x000D_
            var current_page = document.getElementsByClassName('active');_x000D_
            var next_link = document.getElementById('next_link');_x000D_
            var prev_link = document.getElementById('prev_link');_x000D_
            var next_tab = current_page[0].nextSibling; _x000D_
            var prev_tab = current_page[0].previousSibling;_x000D_
            current_page[0].className = current_page[0].className.replace("active", "");_x000D_
            if (element === "next") {_x000D_
                if (parseInt(next_tab.text).toString() === 'NaN') {_x000D_
                    next_tab.previousSibling.className += " active";_x000D_
                    next_tab.setAttribute("onclick", "return false");_x000D_
                } else {_x000D_
                    next_tab.className += " active"_x000D_
                    render_table_rows(rows, parseInt(req_per_page), parseInt(next_tab.text));_x000D_
                    if (prev_link.getAttribute("onclick") === "return false") {_x000D_
                        prev_link.setAttribute("onclick", `active_page('prev',\"${rows}\",${req_per_page})`);_x000D_
                    }_x000D_
                    if (next_tab.style.display === "none") {_x000D_
                        next_tab.style.display = "block";_x000D_
                        hide_from_beginning(prev_link.nextSibling)_x000D_
                    }_x000D_
                }_x000D_
            } else if (element === "prev") {_x000D_
                if (parseInt(prev_tab.text).toString() === 'NaN') {_x000D_
                    prev_tab.nextSibling.className += " active";_x000D_
                    prev_tab.setAttribute("onclick", "return false");_x000D_
                } else {_x000D_
                    prev_tab.className += " active";_x000D_
                    render_table_rows(rows, parseInt(req_per_page), parseInt(prev_tab.text));_x000D_
                    if (next_link.getAttribute("onclick") === "return false") {_x000D_
                        next_link.setAttribute("onclick", `active_page('next',\"${rows}\",${req_per_page})`);_x000D_
                    }_x000D_
                    if (prev_tab.style.display === "none") {_x000D_
                        prev_tab.style.display = "block";_x000D_
                        hide_from_end(next_link.previousSibling)_x000D_
                    }_x000D_
                }_x000D_
            } else {_x000D_
                element.className += "active";_x000D_
                render_table_rows(rows, parseInt(req_per_page), parseInt(element.text));_x000D_
                if (prev_link.getAttribute("onclick") === "return false") {_x000D_
                    prev_link.setAttribute("onclick", `active_page('prev',\"${rows}\",${req_per_page})`);_x000D_
                }_x000D_
                if (next_link.getAttribute("onclick") === "return false") {_x000D_
                    next_link.setAttribute("onclick", `active_page('next',\"${rows}\",${req_per_page})`);_x000D_
                }_x000D_
            }_x000D_
        }_x000D_
_x000D_
        // Render the table's row in table request-table_x000D_
        function render_table_rows(rows, req_per_page, page_no) {_x000D_
            const response = JSON.parse(window.atob(rows));_x000D_
            const resp = response.slice(req_per_page * (page_no - 1), req_per_page * page_no)_x000D_
            $('#request-table').empty()_x000D_
            $('#request-table').append('<tr><th>Index</th><th>Request No</th><th>Title</th></tr>');_x000D_
            resp.forEach(function (element, index) {_x000D_
                if (Object.keys(element).length > 0) {_x000D_
                    const { req_no, title } = element;_x000D_
                    const td = `<tr><td>${++index}</td><td>${req_no}</td><td>${title}</td></tr>`;_x000D_
                    $('#request-table').append(td)_x000D_
                }_x000D_
            });_x000D_
        }_x000D_
_x000D_
        // Pagination logic implementation_x000D_
        function pagination(data, myarr) {_x000D_
            const all_data = window.btoa(JSON.stringify(myarr));_x000D_
            $(".pagination").empty();_x000D_
            if (data.req_per_page !== 'ALL') {_x000D_
                let pager = `<a href="#" id="prev_link" onclick=active_page('prev',\"${all_data}\",${data.req_per_page})>&laquo;</a>` +_x000D_
                    `<a href="#" class="active" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>1</a>`;_x000D_
                const total_page = Math.ceil(parseInt(myarr.length) / parseInt(data.req_per_page));_x000D_
                if (total_page < pagination_visible_pages) {_x000D_
                    render_table_rows(all_data, data.req_per_page, data.page_no);_x000D_
                    for (let num = 2; num <= total_page; num++) {_x000D_
                        pager += `<a href="#" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>${num}</a>`;_x000D_
                    }_x000D_
                } else {_x000D_
                    render_table_rows(all_data, data.req_per_page, data.page_no);_x000D_
                    for (let num = 2; num <= pagination_visible_pages; num++) {_x000D_
                        pager += `<a href="#" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>${num}</a>`;_x000D_
                    }_x000D_
                    for (let num = pagination_visible_pages + 1; num <= total_page; num++) {_x000D_
                        pager += `<a href="#" style="display:none;" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>${num}</a>`;_x000D_
                    }_x000D_
                }_x000D_
                pager += `<a href="#" id="next_link" onclick=active_page('next',\"${all_data}\",${data.req_per_page})>&raquo;</a>`;_x000D_
                $(".pagination").append(pager);_x000D_
            } else {_x000D_
                render_table_rows(all_data, myarr.length, 1);_x000D_
            }_x000D_
        }_x000D_
_x000D_
        //calling pagination function_x000D_
        pagination(data, myarr);_x000D_
_x000D_
_x000D_
        // trigger when requests per page dropdown changes_x000D_
        function filter_requests() {_x000D_
            const data = { "req_per_page": document.getElementById("req_per_page").value, "page_no": 1 };_x000D_
            pagination(data, myarr);_x000D_
        }
_x000D_
.box {_x000D_
 float: left;_x000D_
 padding: 50px 0px;_x000D_
}_x000D_
_x000D_
.clearfix::after {_x000D_
 clear: both;_x000D_
 display: table;_x000D_
}_x000D_
_x000D_
.options {_x000D_
 margin: 5px 0px 0px 0px;_x000D_
 float: left;_x000D_
}_x000D_
_x000D_
.pagination {_x000D_
 float: right;_x000D_
}_x000D_
_x000D_
.pagination a {_x000D_
 color: black;_x000D_
 float: left;_x000D_
 padding: 8px 16px;_x000D_
 text-decoration: none;_x000D_
 transition: background-color .3s;_x000D_
 border: 1px solid #ddd;_x000D_
 margin: 0 4px;_x000D_
}_x000D_
_x000D_
.pagination a.active {_x000D_
 background-color: #4CAF50;_x000D_
 color: white;_x000D_
 border: 1px solid #4CAF50;_x000D_
}_x000D_
_x000D_
.pagination a:hover:not(.active) {_x000D_
 background-color: #ddd;_x000D_
}
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>_x000D_
<div>_x000D_
    <table id="request-table">_x000D_
   </table>_x000D_
</div>_x000D_
_x000D_
<div class="clearfix">_x000D_
 <div class="box options">_x000D_
  <label>Requests Per Page: </label>_x000D_
      <select id="req_per_page" onchange="filter_requests()">_x000D_
   <option>5</option>_x000D_
   <option>10</option>_x000D_
   <option>ALL</option>_x000D_
  </select>_x000D_
 </div>_x000D_
 <div class="box pagination">_x000D_
 </div>_x000D_
</div>
_x000D_
_x000D_
_x000D_