37

I am trying to make pagination for my site. (http://anuntorhei.md)

CODE:

var someVar = 50;


function someStupidFunction() {
        if (objJson.length > 50) {
                document.getElementById("nextPage").style.visibility = "visible";
        }

        if (someVar <= 50) {
                document.getElementById("prevPage").style.visibility ="hidden";
        } else {
                document.getElementById("prevPage").style.visibility = "visible";
        }
}


function nextPage() {
        document.getElementById("listingTable").innerHTML = "";

        if (someVar < objJson.length) {
                document.getElementById("nextPage").style.visibility = "visible";
        } else {
                document.getElementById("nextPage").style.visibility = "hidden";
        }

        for (var i = someVar - 50; i < someVar; i++) {
                document.getElementById("listingTable").innerHTML += objJson[i].adName + "<br>";
        }

        someVar += 50;

        document.getElementById("prevPage").style.visibility = "visible";
}


function prevPage() {
        document.getElementById("listingTable").innerHTML = "";

        if (someVar > 50) {
                document.getElementById("prevPage").style.visibility = "visible";
        } else {
                document.getElementById("prevPage").style.visibility = "hidden";
        }

        for (var i = someVar - 50; i < someVar; i++) {
                document.getElementById("listingTable").innerHTML += objJson[i].adName + "<br>";
        }

        someVar -= 50;

        document.getElementById("nextPage").style.visibility = "visible";
}

But I can't understand how to "hide" nextPage button when someVar is bigger than objJson.length.

And when I reach the "end", nextPage button disappear after than objJson is smaller than someVar. What is wrong in this code?

How can I change it to make it perfect? Sorry for my bad English, can't explain all what I need, hope you understand what I need!

Aditya Vikas Devarapalli
  • 3,186
  • 2
  • 36
  • 54
tourniquet
  • 1,375
  • 2
  • 15
  • 19
  • In that link I don't see any pagination. Anyway, you can clean your code if you use ternary operator: http://jsfiddle.net/rwntwwob/ – Oriol Aug 21 '14 at 20:24
  • Because I testing pagination first (or other stuff), and when I like how this stuff work, I put it on main site! – tourniquet Aug 21 '14 at 20:25

11 Answers11

78

I'll address any questions you have... but here is an improved pattern you should follow to reduce code duplication.

As a sidenote though, you should consider not doing pagination on client-side. Since if you have a huge dataset, it would mean you need to download all the data before your page loads. Better to implement server-side pagination instead.

Fiddle: http://jsfiddle.net/Lzp0dw83/

HTML

<div id="listingTable"></div>
<a href="javascript:prevPage()" id="btn_prev">Prev</a>
<a href="javascript:nextPage()" id="btn_next">Next</a>
page: <span id="page"></span>

Javascript (put anywhere):

var current_page = 1;
var records_per_page = 2;

var objJson = [
    { adName: "AdName 1"},
    { adName: "AdName 2"},
    { adName: "AdName 3"},
    { adName: "AdName 4"},
    { adName: "AdName 5"},
    { adName: "AdName 6"},
    { adName: "AdName 7"},
    { adName: "AdName 8"},
    { adName: "AdName 9"},
    { adName: "AdName 10"}
]; // Can be obtained from another source, such as your objJson variable

function prevPage()
{
    if (current_page > 1) {
        current_page--;
        changePage(current_page);
    }
}

function nextPage()
{
    if (current_page < numPages()) {
        current_page++;
        changePage(current_page);
    }
}

function changePage(page)
{
    var btn_next = document.getElementById("btn_next");
    var btn_prev = document.getElementById("btn_prev");
    var listing_table = document.getElementById("listingTable");
    var page_span = document.getElementById("page");

    // Validate page
    if (page < 1) page = 1;
    if (page > numPages()) page = numPages();

    listing_table.innerHTML = "";

    for (var i = (page-1) * records_per_page; i < (page * records_per_page); i++) {
        listing_table.innerHTML += objJson[i].adName + "<br>";
    }
    page_span.innerHTML = page;

    if (page == 1) {
        btn_prev.style.visibility = "hidden";
    } else {
        btn_prev.style.visibility = "visible";
    }

    if (page == numPages()) {
        btn_next.style.visibility = "hidden";
    } else {
        btn_next.style.visibility = "visible";
    }
}

function numPages()
{
    return Math.ceil(objJson.length / records_per_page);
}

window.onload = function() {
    changePage(1);
};

UPDATE 2014/08/27

There is a bug above, where the for loop errors out when a particular page (the last page usually) does not contain records_per_page number of records, as it tries to access a non-existent index.

The fix is simple enough, by adding an extra checking condition into the for loop to account for the size of objJson:

Updated fiddle: http://jsfiddle.net/Lzp0dw83/1/

for (var i = (page-1) * records_per_page; i < (page * records_per_page) && i < objJson.length; i++)
Populus
  • 7,470
  • 3
  • 38
  • 54
  • thank you for help! The prevPage function work great, but something is happening with nextPage. For example, if objJson.length is 547, I have 19 pages, but when I press next button on 18 page, the page is equal with 18 again and next button don't disappear! I think the "i" variable have a wrong algorithm or may be the "error" is in another place. What are you thinking about this? – tourniquet Aug 27 '14 at 16:27
4

I created a class structure for collections in general that would meet this requirement. and it looks like this:

class Collection {

    constructor() {
        this.collection = [];
        this.index = 0;
    }

    log() {
        return console.log(this.collection);
    }

    push(value) {
        return this.collection.push(value);
    }

    pushAll(...values) {
        return this.collection.push(...values);
    }

    pop() {
        return this.collection.pop();
    }

    shift() {
        return this.collection.shift();
    }

    unshift(value) {
        return this.collection.unshift(value);
    }

    unshiftAll(...values) {
        return this.collection.unshift(...values);
    }

    remove(index) {
        return this.collection.splice(index, 1);
    }

    add(index, value) {
        return this.collection.splice(index, 0, value);
    }

    replace(index, value) {
        return this.collection.splice(index, 1, value);
    }

    clear() {
        this.collection.length = 0;
    }

    isEmpty() {
        return this.collection.length === 0;
    }

    viewFirst() {
        return this.collection[0];
    }

    viewLast() {
        return this.collection[this.collection.length - 1];
    }

    current(){
        if((this.index <= this.collection.length - 1) && (this.index >= 0)){
            return this.collection[this.index];
        }
        else{
            return `Object index exceeds collection range.`;
        }
    }

    next() {
        this.index++;
        this.index > this.collection.length - 1 ? this.index = 0 : this.index;
        return this.collection[this.index];
    }

    previous(){
        this.index--;
        this.index < 0 ? (this.index = this.collection.length-1) : this.index;
        return this.collection[this.index];
    }
}

...and essentially what you would do is have a collection of arrays of whatever length for your pages pushed into the class object, and then use the next() and previous() functions to display whatever 'page' (index) you wanted to display. Would essentially look like this:

let books = new Collection();
let firstPage - [['dummyData'], ['dummyData'], ['dummyData'], ['dummyData'], ['dummyData'],];
let secondPage - [['dumberData'], ['dumberData'], ['dumberData'], ['dumberData'], ['dumberData'],];
books.pushAll(firstPage, secondPage); // loads each array individually
books.current() // display firstPage
books.next() // display secondPage
4

This is the best one for me so far, it will include ´...´ at specific offset

function pages(current_page, last_page, onSides = 3) {
        // pages
        let pages = [];
        // Loop through
        for (let i = 1; i <= last_page; i++) {
            // Define offset
            let offset = (i == 1 || last_page) ? onSides + 1 : onSides;
            // If added
            if (i == 1 || (current_page - offset <= i && current_page + offset >= i) || 
                i == current_page || i == last_page) {
                pages.push(i);
            } else if (i == current_page - (offset + 1) || i == current_page + (offset + 1)) {
                pages.push('...');
            }
        }
        return pages;
    }
MohKoma
  • 964
  • 9
  • 9
3

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

// dummy data
        const myarr = [{ "req_no": 1, "title": "test1" },
        { "req_no": 2, "title": "test2" },
        { "req_no": 3, "title": "test3" },
        { "req_no": 4, "title": "test4" },
        { "req_no": 5, "title": "test5" },
        { "req_no": 6, "title": "test6" },
        { "req_no": 7, "title": "test7" },
        { "req_no": 8, "title": "test8" },
        { "req_no": 9, "title": "test9" },
        { "req_no": 10, "title": "test10" },
        { "req_no": 11, "title": "test11" },
        { "req_no": 12, "title": "test12" },
        { "req_no": 13, "title": "test13" },
        { "req_no": 14, "title": "test14" },
        { "req_no": 15, "title": "test15" },
        { "req_no": 16, "title": "test16" },
        { "req_no": 17, "title": "test17" },
        { "req_no": 18, "title": "test18" },
        { "req_no": 19, "title": "test19" },
        { "req_no": 20, "title": "test20" },
        { "req_no": 21, "title": "test21" },
        { "req_no": 22, "title": "test22" },
        { "req_no": 23, "title": "test23" },
        { "req_no": 24, "title": "test24" },
        { "req_no": 25, "title": "test25" },
        { "req_no": 26, "title": "test26" }];

        // on page load collect data to load pagination as well as table
        const data = { "req_per_page": document.getElementById("req_per_page").value, "page_no": 1 };

        // At a time maximum allowed pages to be shown in pagination div
        const pagination_visible_pages = 4;


        // hide pages from pagination from beginning if more than pagination_visible_pages
        function hide_from_beginning(element) {
            if (element.style.display === "" || element.style.display === "block") {
                element.style.display = "none";
            } else {
                hide_from_beginning(element.nextSibling);
            }
        }
        
        // hide pages from pagination ending if more than pagination_visible_pages
        function hide_from_end(element) {
            if (element.style.display === "" || element.style.display === "block") {
                element.style.display = "none";
            } else {
                hide_from_beginning(element.previousSibling);
            }
        }
        
        // load data and style for active page
        function active_page(element, rows, req_per_page) {
            var current_page = document.getElementsByClassName('active');
            var next_link = document.getElementById('next_link');
            var prev_link = document.getElementById('prev_link');
            var next_tab = current_page[0].nextSibling; 
            var prev_tab = current_page[0].previousSibling;
            current_page[0].className = current_page[0].className.replace("active", "");
            if (element === "next") {
                if (parseInt(next_tab.text).toString() === 'NaN') {
                    next_tab.previousSibling.className += " active";
                    next_tab.setAttribute("onclick", "return false");
                } else {
                    next_tab.className += " active"
                    render_table_rows(rows, parseInt(req_per_page), parseInt(next_tab.text));
                    if (prev_link.getAttribute("onclick") === "return false") {
                        prev_link.setAttribute("onclick", `active_page('prev',\"${rows}\",${req_per_page})`);
                    }
                    if (next_tab.style.display === "none") {
                        next_tab.style.display = "block";
                        hide_from_beginning(prev_link.nextSibling)
                    }
                }
            } else if (element === "prev") {
                if (parseInt(prev_tab.text).toString() === 'NaN') {
                    prev_tab.nextSibling.className += " active";
                    prev_tab.setAttribute("onclick", "return false");
                } else {
                    prev_tab.className += " active";
                    render_table_rows(rows, parseInt(req_per_page), parseInt(prev_tab.text));
                    if (next_link.getAttribute("onclick") === "return false") {
                        next_link.setAttribute("onclick", `active_page('next',\"${rows}\",${req_per_page})`);
                    }
                    if (prev_tab.style.display === "none") {
                        prev_tab.style.display = "block";
                        hide_from_end(next_link.previousSibling)
                    }
                }
            } else {
                element.className += "active";
                render_table_rows(rows, parseInt(req_per_page), parseInt(element.text));
                if (prev_link.getAttribute("onclick") === "return false") {
                    prev_link.setAttribute("onclick", `active_page('prev',\"${rows}\",${req_per_page})`);
                }
                if (next_link.getAttribute("onclick") === "return false") {
                    next_link.setAttribute("onclick", `active_page('next',\"${rows}\",${req_per_page})`);
                }
            }
        }

        // Render the table's row in table request-table
        function render_table_rows(rows, req_per_page, page_no) {
            const response = JSON.parse(window.atob(rows));
            const resp = response.slice(req_per_page * (page_no - 1), req_per_page * page_no)
            $('#request-table').empty()
            $('#request-table').append('<tr><th>Index</th><th>Request No</th><th>Title</th></tr>');
            resp.forEach(function (element, index) {
                if (Object.keys(element).length > 0) {
                    const { req_no, title } = element;
                    const td = `<tr><td>${++index}</td><td>${req_no}</td><td>${title}</td></tr>`;
                    $('#request-table').append(td)
                }
            });
        }

        // Pagination logic implementation
        function pagination(data, myarr) {
            const all_data = window.btoa(JSON.stringify(myarr));
            $(".pagination").empty();
            if (data.req_per_page !== 'ALL') {
                let pager = `<a href="#" id="prev_link" onclick=active_page('prev',\"${all_data}\",${data.req_per_page})>&laquo;</a>` +
                    `<a href="#" class="active" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>1</a>`;
                const total_page = Math.ceil(parseInt(myarr.length) / parseInt(data.req_per_page));
                if (total_page < pagination_visible_pages) {
                    render_table_rows(all_data, data.req_per_page, data.page_no);
                    for (let num = 2; num <= total_page; num++) {
                        pager += `<a href="#" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>${num}</a>`;
                    }
                } else {
                    render_table_rows(all_data, data.req_per_page, data.page_no);
                    for (let num = 2; num <= pagination_visible_pages; num++) {
                        pager += `<a href="#" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>${num}</a>`;
                    }
                    for (let num = pagination_visible_pages + 1; num <= total_page; num++) {
                        pager += `<a href="#" style="display:none;" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>${num}</a>`;
                    }
                }
                pager += `<a href="#" id="next_link" onclick=active_page('next',\"${all_data}\",${data.req_per_page})>&raquo;</a>`;
                $(".pagination").append(pager);
            } else {
                render_table_rows(all_data, myarr.length, 1);
            }
        }

        //calling pagination function
        pagination(data, myarr);


        // trigger when requests per page dropdown changes
        function filter_requests() {
            const data = { "req_per_page": document.getElementById("req_per_page").value, "page_no": 1 };
            pagination(data, myarr);
        }
.box {
 float: left;
 padding: 50px 0px;
}

.clearfix::after {
 clear: both;
 display: table;
}

.options {
 margin: 5px 0px 0px 0px;
 float: left;
}

.pagination {
 float: right;
}

.pagination a {
 color: black;
 float: left;
 padding: 8px 16px;
 text-decoration: none;
 transition: background-color .3s;
 border: 1px solid #ddd;
 margin: 0 4px;
}

.pagination a.active {
 background-color: #4CAF50;
 color: white;
 border: 1px solid #4CAF50;
}

.pagination a:hover:not(.active) {
 background-color: #ddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
    <table id="request-table">
   </table>
</div>

<div class="clearfix">
 <div class="box options">
  <label>Requests Per Page: </label>
      <select id="req_per_page" onchange="filter_requests()">
   <option>5</option>
   <option>10</option>
   <option>ALL</option>
  </select>
 </div>
 <div class="box pagination">
 </div>
</div>
Rakesh Sharma
  • 608
  • 6
  • 9
3

Below is the pagination logic as a function


function Pagination(pageEleArr, numOfEleToDisplayPerPage) {
    this.pageEleArr = pageEleArr;
    this.numOfEleToDisplayPerPage = numOfEleToDisplayPerPage;
    this.elementCount = this.pageEleArr.length;
    this.numOfPages = Math.ceil(this.elementCount / this.numOfEleToDisplayPerPage);
    const pageElementsArr = function (arr, eleDispCount) {
        const arrLen = arr.length;
        const noOfPages = Math.ceil(arrLen / eleDispCount);
        let pageArr = [];
        let perPageArr = [];
        let index = 0;
        let condition = 0;
        let remainingEleInArr = 0;

        for (let i = 0; i < noOfPages; i++) {

            if (i === 0) {
                index = 0;
                condition = eleDispCount;
            }
            for (let j = index; j < condition; j++) {
                perPageArr.push(arr[j]);
            }
            pageArr.push(perPageArr);
            if (i === 0) {
                remainingEleInArr = arrLen - perPageArr.length;
            } else {
                remainingEleInArr = remainingEleInArr - perPageArr.length;
            }

            if (remainingEleInArr > 0) {
                if (remainingEleInArr > eleDispCount) {
                    index = index + eleDispCount;
                    condition = condition + eleDispCount;
                } else {
                    index = index + perPageArr.length;
                    condition = condition + remainingEleInArr;
                }
            }
            perPageArr = [];
        }
        return pageArr;
    }
    this.display = function (pageNo) {
        if (pageNo > this.numOfPages || pageNo <= 0) {
            return -1;
        } else {
            console.log('Inside else loop in display method');
            console.log(pageElementsArr(this.pageEleArr, this.numOfEleToDisplayPerPage));
            console.log(pageElementsArr(this.pageEleArr, this.numOfEleToDisplayPerPage)[pageNo - 1]);
            return pageElementsArr(this.pageEleArr, this.numOfEleToDisplayPerPage)[pageNo - 1];
        }
    }
}

const p1 = new Pagination(['a', 'b', 'c', 'd', 'e', 'f', 'g'], 3);
console.log(p1.elementCount);
console.log(p1.pageEleArr);
console.log(p1.numOfPages);
console.log(p1.numOfEleToDisplayPerPage);
console.log(p1.display(3));
Biswajeet gope
  • 321
  • 3
  • 17
0

i am assuming you will display 10 data in every page

HTML:-

<!DOCTYPE html>
<html>
<head>
    <title>pagination</title>
    <link rel="stylesheet"  href="pathofcssfile.css">
</head>
<body>
    <div>
        <table id="user"></table>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <ul>
    <li value="1">1</li>
    <li value="2">2</li>
    <li value="3">3</li>
    <li value="4">4</li>
    <li value="5">5</li>
    <li value="6">6</li>
    <li value="7">7</li>
    <li value="8">8</li>
    <li value="9">9</li>
    <li value="10">10</li>

    </ul>

    <script src="pathnameofjsfile.js" type="text/javascript"></script>
</body>
</html>

JS:-

var xhr = new XMLHttpRequest();
xhr.open('GET',"https://jsonplaceholder.typicode.com/albums",true);
xhr.send();

var udata;

xhr.onload = function() 
{
    if(this.status == 200) 
    {
        var userdata = JSON.parse(this.responseText);
        console.log(userdata);
        udata = userdata;
        data(1);
    }
}

$("li").click(function ()
{       
var a = $(this).attr("value");
console.log("value li "+ a);
data(a);
});

function data(a)
{  
    var output = "";
    for(i=((a-1)*10);i<(a*10);i++)
    {
        output +='<tr>'+
                 '<td>'+ udata[i].userId + '</td>'+
                 '<td>'+ udata[i].id + '</td>'+
                 '<td>'+ udata[i].title + '</td>'+ '<br>'
                 '</tr>';
    }
    document.getElementById('user').innerHTML = output;
}

CSS:-

ul{
display: flex;
list-style-type:none;
padding: 20px;
}

li{
padding: 20px;
}

td,tr{
    padding: 10px;
}
Sandeep Mukherjee
  • 673
  • 1
  • 9
  • 17
0

Following is the Logic which accepts count from user and performs pagination in Javascript. It prints alphabets. Hope it helps!!. Thankyou.

/*
*****
USER INPUT : NUMBER OF SUGGESTIONS.
*****
*/

var recordSize = prompt('please, enter the Record Size');
console.log(recordSize);


/*
*****
POPULATE SUGGESTIONS IN THE suggestion_set LIST.
*****
*/
var suggestion_set = [];
counter = 0;

asscicount = 65;
do{
if(asscicount <= 90){
 var temp = String.fromCharCode(asscicount);
 suggestion_set.push(temp);
 asscicount += 1;     
}else{
 asscicount = 65;
 var temp = String.fromCharCode(asscicount);
 suggestion_set.push(temp); 
 asscicount += 1;     
}
counter += 1;
}while(counter < recordSize);

console.log(suggestion_set); 



/*
*****
LOGIC FOR PAGINATION
*****
*/

var totalRecords = recordSize, pageSize = 6;
var q = Math.floor(totalRecords/pageSize);
var r = totalRecords%pageSize;
var itr = 1;

if(r==0 ||r==1 ||r==2) {
itr=q;
}
else {
itr=q+1;
}
console.log(itr);

var output = "", pageCnt=1, newPage=false;

if(totalRecords <= pageSize+2) {
output += "\n";

 for(var i=0; i < totalRecords; i++){
  output += suggestion_set[i] + "\t";
 }
}

else {
 output += "\n";
 for(var i=0; i<totalRecords; i++) {
  //output += (i+1) + "\t";
  if(pageCnt==1){
  output += suggestion_set[i] + "\t";
  if((i+1)==(pageSize+1)) {
  output += "Next" + "\t";
  pageCnt++;
  newPage=true;
 }
}
else {
if(newPage) {
output += "\n" + "Previous" + "\t";
newPage = false;
}
output += suggestion_set[i] + "\t";
if((i+1)==(pageSize*pageCnt+1) && (pageSize*pageCnt+1)<totalRecords) {
if((i+2) == (pageSize*pageCnt+2) && pageCnt==itr) {
output += (suggestion_set[i] + 1) + "\t";
break;
}
else {
output += "Next" + "\t";
pageCnt++;
newPage=true;
}
}
}
}
}
console.log(output);
0

enter image description here file:icons.svg

<svg aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-triangle-left" viewBox="0 0 20 20">
<title>triangle-left</title>
<path d="M14 5v10l-9-5 9-5z"></path>
</symbol>
<symbol id="icon-triangle-right" viewBox="0 0 20 20">
<title>triangle-right</title>
<path d="M15 10l-9 5v-10l9 5z"></path>
</symbol>
</defs>
</svg>

file: style.css

 .results__btn--prev{
    float: left;
    flex-direction: row-reverse; }
  .results__btn--next{
    float: right; }

file index.html:

<body>
<form class="search">
                <input type="text" class="search__field" placeholder="Search over 1,000,000 recipes...">
                <button class="btn search__btn">
                    <svg class="search__icon">
                        <use href="img/icons.svg#icon-magnifying-glass"></use>
                    </svg>
                    <span>Search</span>
                </button>
            </form>
     <div class="results">
         <ul class="results__list">
         </ul>
         <div class="results__pages">
         </div>
     </div>
</body>

file: searchView.js

export const element = {
    searchForm:document.querySelector('.search'),
    searchInput: document.querySelector('.search__field'),
    searchResultList: document.querySelector('.results__list'),
    searchRes:document.querySelector('.results'),
    searchResPages:document.querySelector('.results__pages')

}
export const getInput = () => element.searchInput.value;
export const clearResults = () =>{
    element.searchResultList.innerHTML=``;
    element.searchResPages.innerHTML=``;
}
export const clearInput = ()=> element.searchInput.value = "";

const limitRecipeTitle = (title, limit=17)=>{
    const newTitle = [];
    if(title.length>limit){
        title.split(' ').reduce((acc, cur)=>{
            if(acc+cur.length <= limit){
                newTitle.push(cur);
            }
            return acc+cur.length;
        },0);
    }

    return `${newTitle.join(' ')} ...`
}
const renderRecipe = recipe =>{
    const markup = `
        <li>
            <a class="results__link" href="#${recipe.recipe_id}">
                <figure class="results__fig">
                    <img src="${recipe.image_url}" alt="${limitRecipeTitle(recipe.title)}">
                </figure>
                <div class="results__data">
                    <h4 class="results__name">${recipe.title}</h4>
                    <p class="results__author">${recipe.publisher}</p>
                </div>
            </a>
        </li>
    `;
    var htmlObject = document.createElement('div');
    htmlObject.innerHTML = markup;
    element.searchResultList.insertAdjacentElement('beforeend',htmlObject);
}

const createButton = (page, type)=>`

    <button class="btn-inline results__btn--${type}" data-goto=${type === 'prev'? page-1 : page+1}>
    <svg class="search__icon">
        <use href="img/icons.svg#icon-triangle-${type === 'prev'? 'left' : 'right'}}"></use>
    </svg>
    <span>Page ${type === 'prev'? page-1 : page+1}</span>
    </button>
`
const renderButtons = (page, numResults, resultPerPage)=>{
    const pages = Math.ceil(numResults/resultPerPage);
    let button;
    if(page == 1 && pages >1){
        //button to go to next page
        button = createButton(page, 'next');
    }else if(page<pages){
      //both buttons  
      button = `
      ${createButton(page, 'prev')}
      ${createButton(page, 'next')}`;


    }
    else if (page === pages && pages > 1){
        //Only button to go to prev page
        button = createButton(page, 'prev');
    }

    element.searchResPages.insertAdjacentHTML('afterbegin', button);
}
export const renderResults = (recipes, page=1, resultPerPage=10) =>{
    /*//recipes.foreach(el=>renderRecipe(el))
    //or foreach will automatically call the render recipes
    //recipes.forEach(renderRecipe)*/
    const start = (page-1)*resultPerPage;
    const end = page * resultPerPage;
    recipes.slice(start, end).forEach(renderRecipe);
    renderButtons(page, recipes.length, resultPerPage);
}

file: Search.js

export default class Search{
    constructor(query){
        this.query = query;
    }
    async getResults(){
        try{
            const res = await axios(`https://api.com/api/search?&q=${this.query}`);
            this.result = res.data.recipes;
            //console.log(this.result);
        }catch(error){
            alert(error);
        }
    }
}

file: Index.js

onst state = {};
const controlSearch = async()=>{
  const query = searchView.getInput();
  if (query){
    state.search = new Search(query); 
    searchView.clearResults();
    searchView.clearInput();
    await state.search.getResults();
    searchView.renderResults(state.search.result);
  }
}
//event listner to the parent object to delegate the event
element.searchForm.addEventListener('submit', event=>{
  console.log("submit search");
  event.preventDefault();
  controlSearch();
});

element.searchResPages.addEventListener('click', e=>{
  const btn = e.target.closest('.btn-inline');
  if(btn){
    const goToPage = parseInt(btn.dataset.goto, 10);//base 10
    searchView.clearResults();
    searchView.renderResults(state.search.result, goToPage);
  }
});

Rafiq
  • 8,987
  • 4
  • 35
  • 35
0

Just create and save a page token in global variable with window.nextPageToken. Send this to API server everytime you make a request and have it return the next one with response and you can easily keep track of last token. The below is an example how you can move forward and backward from search results. The key is the offset you send to API based on the nextPageToken that you have saved:

function getPrev() {
  var offset = Number(window.nextPageToken) - limit * 2;
  if (offset < 0) {
    offset = 0;
  }
  window.nextPageToken = offset;
  if (canSubmit(searchForm, offset)) {
    searchForm.submit();
  }
}

function getNext() {
  var offset = Number(window.nextPageToken);
  window.nextPageToken = offset;
  if (canSubmit(searchForm, offset)) {
    searchForm.submit();
  }
}
ttfreeman
  • 5,076
  • 4
  • 26
  • 33
0

var data = [1, 2, 3, 4, 5, 6, 7];
      var item_per_page = 3;
      var current_page = 1;

      var pagination = {
        total: data.length,
        per_page: item_per_page,
        current_page: current_page,
        last_page: Math.ceil(data.length / item_per_page),
        from: (current_page - 1) * item_per_page + 1,
        to: current_page * item_per_page,
      };

      changePage();
      function changePage() {
        var temp = [];
        for (let i = pagination.from; i <= pagination.to; i++) {
          temp.push(data[i - 1]);
        }
        document.getElementById("result").innerHTML = temp.filter(x => x);
        console.log(pagination);
      }

      function up() {
        if (pagination.from == 1) {
          return false;
        }

        pagination.current_page -= 1;
        pagination.from = (pagination.current_page - 1) * item_per_page + 1;
        pagination.to = pagination.current_page * item_per_page;

        changePage();
      }

      function down() {
        if (pagination.last_page == pagination.current_page) {
          return false;
        }

        pagination.current_page += 1;

        pagination.from = (pagination.current_page - 1) * item_per_page + 1;
        pagination.to = pagination.current_page * item_per_page;

        changePage();
      }
      console.log(pagination);
button {
        width: 100px;
      }
<div style="display: grid">
      <button type="button" onclick="up()">Up</button>
      <div id="result"></div>
      <button type="button" onclick="down()">Down</button>
    </div>
Vijay Kanaujia
  • 439
  • 4
  • 9
-2

You can use the code from this minimal plugin. https://www.npmjs.com/package/paginator-js

Array.prototype.paginate = function(pageNumber, itemsPerPage){
  pageNumber   = Number(pageNumber)
  itemsPerPage = Number(itemsPerPage)
  pageNumber   = (pageNumber   < 1 || isNaN(pageNumber))   ? 1 : pageNumber
  itemsPerPage = (itemsPerPage < 1 || isNaN(itemsPerPage)) ? 1 : itemsPerPage

  var start     = ((pageNumber - 1) * itemsPerPage)
  var end       = start + itemsPerPage
  var loopCount = 0
  var result    = {
    data: [],
    end: false
  }

  for(loopCount = start; loopCount < end; loopCount++){
    this[loopCount] && result.data.push(this[loopCount]);
  }

  if(loopCount == this.length){
    result.end = true
  }

  return result
}
Rohit
  • 5,631
  • 4
  • 31
  • 59