4

I'm trying to implement server side pagination like datetable and I found backbone.paginator library, I don't know if there is something else.

Through their examples they used another library to help accomplishing this which is backgrid.js and its paginator plugin

Is it possible to do this pagination without Backgrid? Could you please add any example on this?

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Basheer AL-MOMANI
  • 14,473
  • 9
  • 96
  • 92
  • Why don't you want to use the paginator plugin? What are you trying to do? Offsite recommendations are off-topic. – Emile Bergeron Sep 05 '17 at 14:45
  • @EmileBergeron actually I'm limited to how many libraries I can add to the project, by the way, what is the purpose of using backgrid and how it simplifies the creation of pagination?(should I add this to the question?) – Basheer AL-MOMANI Sep 06 '17 at 06:17
  • @BasheerAL-MOMANI Can't you look at the source of `backgrid` and judge yourself whether it's worth implementing by urself or just using the existing library? – T J Sep 06 '17 at 10:55
  • Backgrid and paginator does different things. Backgrid only handles dynamic tabular data, while paginator is just a special collection dealing with paginated endpoint with minimal configuration and parsing. – Emile Bergeron Sep 06 '17 at 13:30
  • I once needed infinite scrolling style pagination of long list where all the loaded items would be rendered, and additional pages (chunks) would be loaded and rendered. I [tried using Paginator](https://github.com/backbone-paginator/backbone.paginator/issues/344) but it's to focused on rendering a page and it was too much of a pain to work around that. So I rolled my own [infinite collection implementation](https://gist.github.com/emileber/7c3b472fa45d8a208d9a8317bb2f38ae). – Emile Bergeron Sep 06 '17 at 13:33
  • datatables dont use server side pagination. I dont see any ajax request when I paginate – lgabster Sep 15 '17 at 15:38

2 Answers2

3

I developed the following code to share with you A JS/php code that do server site pagination and you could change it according to your need and later i may summarize it better.

First make connection to DB and create pagination table:

  CREATE TABLE `pagination` (
 `id` INT( 16 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `name` VARCHAR( 50 ) NOT NULL ,
 `age` INT( 3 ) NOT NULL ,
 `company` VARCHAR( 50 ) NOT NULL
  ) 

Second insert 400 same records :

   $i=0;
   while ($i< 400){
   $pag="insert into pagination (id,name,age,company) VALUES 
  ('NULL','john','40','google')";
  $excu=$mysqli->query($pag);
   $i++;
       }

Then make test.php

 <!DOCTYPE html>
 <html><head>
 <style>
 #container{overflow-x: hidden;max-width:90%;min-width:90% ;margin: 0 auto;}
 td{max-width:10%;min-width:10%}
 tr,td{border:1px solid black }
 #page{display:inline;border:1px solid black}
 #numb,#numbs{display:none}
.button{background:white}
 </style>
 </head>
 <body >
 <?php $defaultoption ="10";?>
 <div id=container></div><span id=numb></span><span id=numbs><?php echo 
 $defaultoption;?></span>
 <script type=text/javascript  src=js.js></script>
 </body>
 </html>

Then make js.js :

  onload = function (){ 
  var container=document.getElementById("container");
  var table =document.getElementById("numbs").innerHTML;
   var xhttp = new XMLHttpRequest();
   xhttp.onreadystatechange = function() {
  if (xhttp.readyState == 4 && xhttp.status == 200) {

  container.innerHTML=xhttp.responseText;
 var button=document.getElementById("button");
 button.children[0].disabled="true";
 button.children[0].style.background="yellow";
             }}  
 xhttp.open("POST", "testa.php", true);
 xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("table="+table);
    }      


 function select(){
 var sel =document.getElementById("select");
 var table=sel.options[sel.selectedIndex].value;
 var b2 =document.getElementById("numbs");
 b2.innerHTML=table;
 var se = new XMLHttpRequest();
 se.onreadystatechange = function() {
  if (se.readyState == 4 && se.status == 200) {
  document.getElementById("container").innerHTML=se.responseText;
  var button=document.getElementById("button");
  button.children[0].disabled="true";
   button.children[0].style.background="yellow";

       }}  
   se.open("POST", "testa.php", true);
   se.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
   se.send("table="+table);
   }





   function button(button){
   var b2 =document.getElementById("numbs");
   var b1 =button.innerHTML;
   var numb = document.getElementById("numb"); 
   numb.innerHTML=b1;
   var b= b2.innerHTML; 
   var butt = new XMLHttpRequest();
     butt.onreadystatechange = function() {
   if (butt.readyState == 4 && butt.status == 200) {

  document.getElementById("container").innerHTML=butt.responseText;
  var d = document.getElementsByClassName("button");
  for(i=0;i<d.length;i++){
  if(d[i].innerHTML == numb.innerHTML){d[i].disabled="true";
  d[i].style.background="yellow";
    }}}}

  butt.open("POST", "testa.php", true);
  butt.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
   butt.send("b="+b+"&b1="+b1);
  }

Make testa.php :

  <?php
  $pag="SELECT * FROM pagination ORDER BY id ASC ";
  $exc=$mysqli->query($pag);
  $numrwos =mysqli_num_rows($exc);
  if($_POST['b']){
  $b =$_POST['b'];
  $b1 =$_POST['b1'];
  $max=($b*$b1);
  $m =($b1-1);
  $n =($m*$b);
  $min =($n-1);
  if($numrwos){
  echo "<select id=select onchange=select()><option selected=selected>Show Entries</option>";
  if($numrwos < 11){
  echo "<option>10</option>";
  }elseif($numrwos > 10 && $numrwos < 26){
  echo "<option>10</option><option>25</option>"; }elseif($numrwos > 25 && 
  $numrwos < 51){
  echo "<option>10</option><option>25</option><option>50</option>";}else{
  echo "<option>10</option><option>25</option><option>50</option>
  <option>100</option>";}
  echo "</select><br />";
  echo "<table width=80% id=table>";
  echo "<tr><td width=10%>id</td><td>name</td><td>age</td><td>company</td></tr>";
  $stop="0";
  while ($result=mysqli_fetch_array($exc)){
  if($stop > $min && $stop < $max){
  echo "<tr><td>".$result['id']."</td><td>".$result['name']."</td>
  <td>".$result['age']."</td><td>".$result['company']."</td></tr>";
  }else{}
  $stop++;
 }echo "</table><br />";
  echo "<div id=button>";
  $i=0;
  while($i < $numrwos){
  $page+=$i % $b == $b-1;
  $i++;
  if($i%$b == 1){
  $pagenum=$page+1;
  echo "<button class=button onmouseover='button(this)'>".$pagenum."</button>";}}
 echo "</div>";
 }else{echo "no records";}

 }else{
 $t =$_POST["table"];
 if($numrwos){
 echo "<select id=select onchange=select()><option selected=selected>Show Entries</option>";
 if($numrwos < 11){
 echo "<option>10</option>";
 }elseif($numrwos > 10 && $numrwos < 26){
 echo "<option>10</option><option>25</option>"; }elseif($numrwos > 25 && $numrwos < 51){
  echo "<option>10</option><option>25</option><option>50</option>";}else{
  echo "<option>10</option><option>25</option><option>50</option>
  <option>100</option>";}
  echo "</select><br />";
  echo"<table width=80% id=table>";
   echo "<tr><td width=10%>id</td><td>name</td><td>age</td><td>company</td></tr>";
  $stop="0";
  while ($result=mysqli_fetch_array($exc)){
  echo "<tr><td>".$result['id']."</td><td>".$result['name']."</td>
   <td>".$result['age']."</td><td>".$result['company']."</td></tr>";
  if($stop ==$t-1){break;}
  $stop++;
  }echo "</table><br />";
  echo "<div id=button>";
  $i=0;
  while($i < $numrwos){
  $page+=$i % $t == $t-1;
   $i++;
  if($i%$t == 1){
  $pagenum=$page+1;
   echo "<button class=button onmouseover='button(this)'>".$pagenum."</button>";}}
 echo "</div>";
  }else{echo "no records";}
  } 
  ?>

I wish that help you .

Mohammed Elhag
  • 4,272
  • 1
  • 10
  • 18
0

I did it

in the View initialize function

I call

this.reloadCustomPages();

here its implementation

reloadCustomPages: function(options) {
    var self = this;
    self.block();
    self.customPages.fetch({data: $.param(options)}).always(function () {
        self.unblock();
    });
}

in the server side (java spring) I modified the api to accept new query strings

@RequestParam(value = "pageNumber", defaultValue = "1"),
@RequestParam(value = "perPage", defaultValue = "10")

and instead of returning the list directly it returns useful pagination info like

  • total number of items in database
  • current page nuber
  • page size
  • and the items itself

check this server-side snippet (I know it's not related but worthy to look at)

@RequestMapping(value = "/editor/pages", method = RequestMethod.GET)
public void listPages(@RequestParam(value = "pageNumber", defaultValue = "1") Integer pageNumber,
                          @RequestParam(value = "perPage", defaultValue = "10") Integer perPage,
                          HttpServletResponse httpResp) throws IOException {

    Long recordsTotal = pageSvc.findTotalNumberOfPages();// select count(*) from table_name    
    List<PbCustomPage> pages = pageSvc.findPages(pageNumber, perPage);// server side query that gets a pagenated data 

    BackbonePaginatorResponse response = new BackbonePaginatorResponse();// I created this simple class 
    response.setTotalCount(recordsTotal);
    response.setPageNumber(pageNumber);
    response.setPerPage(perPage);
    response.setItems(pages);

    httpResp.setContentType("application/json");
    json.createCustomPageSerializer().addProperties().serialize(response, httpResp.getWriter());// just make your server send that obkect
}

now back the function call it will till the server to get page 1 with a page size of 10

in my template, I have this

<div class="pagination clear" style="text-align: center;">
    <%= customPages.paginationHtml %>
</div>

let me tell you how I populate it

customPages.paginationHtml = this.generatePagination(customPages);

and here is the most important part

generatePagination: function (paginationResponse) {
    var currentPage = paginationResponse.pageNumber,
        lastPage = paginationResponse.totalCount==0?1:Math.ceil(paginationResponse.totalCount/paginationResponse.perPage);
    var html = '<ul class="pagination">';
    html += '<li class="'+(currentPage == 1?"disabled":"")+'" data-pb-page-number="1"><a href="#" class="first">&laquo;&laquo;</a></li>';
    html += '<li class="'+(currentPage == 1?"disabled":"")+'" data-pb-page-number="'+(currentPage==1?1:currentPage-1)+'"><a href="#" class="prev">&laquo;</a></li>';


    for (var i = 1; i <= lastPage; i++) {
         html += '<li class="'+(currentPage == i?"active":"")+'" data-pb-page-number="'+i+'"><a href="#" class="page">'+ i +'</a></li>';
    }

    html += '<li class="'+(lastPage == currentPage?"disabled":"")+'" data-pb-page-number="'+(currentPage==lastPage?lastPage:currentPage+1)+'"><a href="#" class="next">&raquo;</a></li>';
    html += '<li class="'+(lastPage == currentPage?"disabled":"")+'" data-pb-page-number="'+(lastPage)+'"><a href="#" class="last">&raquo;&raquo;</a></li>';

    html += '</ul>';
    return html;
},

each li I create it has data-pb-page-number to be used later

one more thing, how to make new requests to other pages

in the View initialize function

this.el.on('click', 'ul.pagination li:not(.disabled,.active)', this.getCustomPagesPagination);

here its implementation

getCustomPagesPagination: function (e) {
    e.preventDefault();
    var $el = $(e.target).closest("li");
    this.reloadCustomPages({pageNumber:$el.data("pb-page-number")})
},

the the result is like this

enter image description here

this how I solved my problem but the question still not answered

Basheer AL-MOMANI
  • 14,473
  • 9
  • 96
  • 92