+ Start a Discussion
Sean_kSean_k 

Ajax - Pagination

I am developing a Ajax scontrol(Report) where I show next 100/50/25 days Events.Customer is asking for pagination as there are thousands of events.
Could some body please provide guidelines or samples for the best practices to use.
Thanks,
Sean
 
mojeebahmedmojeebahmed
Hi Sean,

    First of all i am guessing that right now you get all the data, events for the next 100/50/25 days and display it on the page. I just have a quick question, how much time does it take to get this much data? there are two ways to do the paging for this data. if the time to get the data from sales-force is less, say 5 to 10 sec, then you can use client side paging. to do this you can use an open source free table data paging library from here http://www.javascripttoolbox.com/lib/table/ it is very simple and you can very easily implement it. The second way is that you use the sales-force's querymore function. when you first query for the events use a limit, say 50.  Once you get these 50 records, you can display these 50 records in the HTML table using the javascript and it is very easy. One more thing that you should do is to store these 50 records in a javascript array so you can use them later on. then you can create a couple of links at the end of the table to go forward or backward. create a function to querymore from sales-force for the events and get next 50 event records. store these 50 in the array and then clear the table by removing the rows and then display these records there. this way you can create forward paging. to go back you just have to use the javascript array you used to store the extracted event records. just traverse the array like any other array and get the number of records from the array and then clear the table and display the records there.

IF you need more detail please let me know.
PramodPramod
Hi Ahmed,

I am also looking to develop same functionality. Thanks fot the link on javascripttoolbox. If you have , could you please provide some working examples with relates to salesforce.com as well ?

Regards

Pramod


mojeebahmedmojeebahmed
Code:
<html>
<head>
 <script language="JavaScript1.2" src="/soap/ajax/9.0/connection.js" type="text/javascript"> </script> 
 <title>View Related Opportunities</title>

 <script language="JavaScript1.2" type="text/javascript">
 {!INCLUDE($Scontrol.Table_Lib)}
 </script>

 <script language="JavaScript1.2" type="text/javascript">
    
        function initialize()
        {
         try
         {
             document.getElementById("msgSection").style.display = "block";
             loadRelatedOpportunities();
         }
         catch(e) { alert("Script Initialization Failed. Please try again."); window.close(); }
        }

        function loadRelatedOpportunities()
        {   
         try
         {
    var AccountIDs = "'001xxxxxxxx001', '001xxxxxxxx002', '001xxxxxxxx003'"; // Put some Account IDs here
    var strQuery = "select Id,Name,Business_Unit__c,Region__c,StageName, AccountId, Account.Name  from Opportunity where AccountId IN (" + AccountIDs + ") ";
    
    var Results = sforce.connection.query(strQuery);
    
    loadRelatedOpportunitiesSuccess2(Results);
   }
   catch(e) 
   { 
    alert(e + "-" + e.message); 
   }
  }
  
  function loadRelatedOpportunitiesSuccess2(Results)
  {
         var Id,Name,BusinessUnit,Region,Stage, Account_ID, Account_Name;

      try
      {
          var mTableBody = document.createElement("tbody");
          
          if(Results.size > 0)
          {
              var records = Results.getArray("records");
              
           for(var j=0; j<records.length; j++)
           {
            Id    =  records[j].Id;
            Name   = records[j].Name;
            BusinessUnit = records[j].Business_Unit__c;
            Region   = records[j].Region__c;
            Stage   = records[j].StageName;
            Account_ID   =  records[j].AccountId;
            Account_Name =  records[j].Account.Name;
      
            addDBRow(Id,Name,Account_ID, Account_Name,BusinessUnit,Region,Stage,j, mTableBody)
           }
                               
                    
           var pages = records.length/10;
              if(records.length%10 >0)
                  pages++;
              
              for(var j=1 ; j<=pages ; j++)
              {
                  var aLink= "";
                  
                  if(j==1)
                      aLink = "<a href='#' id='page"+j+"' class='pagelink currentpage' onclick='pageexample("+parseInt(j-1)+"); return false;'>"+j+"</a>" ;
                  else
                      aLink = "<a href='#' id='page"+j+"' class='pagelink' onclick='pageexample("+parseInt(j-1)+"); return false;'>"+j+"</a>" ;
                      
                  document.getElementById("tfootPages").innerHTML += aLink + "\r";
              }           
     
          }
          
       
       document.getElementById("msgSection").style.display = "none";
       //document.getElementById("mainlist").style.display = "block";
       
         
         }  catch(e) { alert(e + "-" + e.message); }
        }

        function loadRelatedOpportunitiesFailure(Results)
        {
            alert(Results);
            document.getElementById("msgSection").style.display = "none";
        }

        function addDBRow(OpportunityId,Name,AccountId, AccountName,BusinessUnit,Region,Stage,index, mTableBody1)
        {
        
            var mTableBody = document.getElementById("mtblBody");//document.getElementById("mtblBody");
            var Row = document.createElement("tr");
      
      if(index%2 == 0)
          Row.className = "dataRows alternate";
      else
          Row.className = "dataRows";
      Row.Style = " ";
      
         Row.id = "tr"+ index;
               
      var Cell1 = document.createElement("td");
      var Cell2 = document.createElement("td");
      var Cell3 = document.createElement("td");
      var Cell4 = document.createElement("td");
      var Cell5 = document.createElement("td");
           
         Cell1.Style = "width:30%;";
         Cell2.Style = "width:30%;";
         Cell3.Style = "width:15%;";
         Cell4.Style = "width:10%;";
         Cell5.Style = "width:15%;";
         
         //Cell1.Class = "dataCell";
         //Cell2.Class = "dataCell";
         //Cell3.Class = "dataCell";
         //Cell4.Class = "dataCell";
         //Cell5.Class = "dataCell";
         
         Cell1.innerHTML = "<a class='OpportunityLink' href=javascript:loadDetails('" + OpportunityId + "')>" + Name + "</a>"; 
         Cell2.innerHTML = "<a class='AccountLink' href=javascript:loadDetails('" + AccountId + "')>" + AccountName + "</a>"; 
         Cell3.innerHTML = BusinessUnit;  
         Cell4.innerHTML = Region;  
         Cell5.innerHTML = Stage; 
         
         Row.appendChild(Cell1);
      Row.appendChild(Cell2);
      Row.appendChild(Cell3);
      Row.appendChild(Cell4);
      Row.appendChild(Cell5);
           
      
      mTableBody.appendChild(Row);
        }

        function loadDetails(objID)
        {
         window.opener.parent.parent.location.href = "../" + objID;
         window.close();
        }
        
        
        
        function pageexample(page) 
     {     
         for(var k = 0 ; k < document.getElementsByTagName("a").length ; k++)
         {
             var pageID = document.getElementsByTagName("a")[k].id;
             
             if(pageID.indexOf("page") == 0)
             {
                 var pageClass = document.getElementsByTagName("a")[k].className;
                 pageClass = pageClass.replace(/currentpage/, " ");
                 document.getElementsByTagName("a")[k].className = pageClass;    
             }
         }
                  
         var t = document.getElementById('t1');
         var res;
         if (page=="previous") 
         {
          res=Table.pagePrevious(t);
         }
         else if (page=="next") 
         {
          res=Table.pageNext(t);
         }
         else 
         {
          res=Table.page(t,page);
         }
         
         var currentPage = parseInt(res.page + 1);     
         
         document.getElementById('page'+currentPage).className += ' currentpage';
         
        }
        
    </script>
    <style type="text/css">
        .msgDIV {
     color: #003366;
     font-weight: bold;
     font-size: 12px;
     font-family: Arial, Helvetica, sans-serif;
        }
        table.external td
        {
            padding-right: 15px; 
            padding-left: 15px; 
            padding-bottom: 0px; 
            padding-top: 0px;
        }
        table.external
        {
            font-size:10pt;
            border-top: #e5c130 4px solid;  /*#b4a066 Company Border Color*/
            border-right: #e5c130 2px solid;
            border-bottom: #e5c130 2px solid;
            background-color:#f1f0e6;
            border-collapse: collapse;
            width:100%;

        }
        table.example        
        {   
            font-size:10pt;
            border-collapse: collapse;            
            width:100%;            
        }
        table.external a.pagelink {
         padding-left:5px;
         padding-right:5px;
         color: Brown;
        }
        table.external a.OpportunityLink {
         padding-left:5px;
         padding-right:5px;
         color: Chocolate;
        }
        table.external a.AccountLink{
         padding-left:5px;
         padding-right:5px;
         color: DarkBlue;
        }
        table.external a.currentpage
        {
         font-weight: bold;
         color: Brown;
        }
        /* Striping */
        tr.alternate
        {
         background-color: #eeeeee;
        }

        /* Sorting */
        th.table-sortable {
         cursor:pointer;
         background-image:url("sort_icon/sortable.gif");
         background-position:center left;
         background-repeat:no-repeat;
         padding-left:12px;
        }
        th.table-sorted-asc {
         background-image:url("sort_icon/sorted_up.gif");
         background-position:center left;
         background-repeat:no-repeat;
        }
        th.table-sorted-desc {
         background-image:url("sort_icon/sorted_down.gif");
         background-position:center left;
         background-repeat:no-repeat;
        }
        th.table-filtered {
         background-image:url("sort_icon/filter.gif");
         background-position:center left;
         background-repeat:no-repeat;
        }
        select.table-autofilter {
         font-size:smaller;
        }


        /* Sort Icon Styles */
        table.sort02 th.table-sortable { background-image:none; padding-left:16px; }
        table.sort02 th.table-sorted-asc { background-image:url("/servlet/servlet.ImageServer—oid=00D00000000hZdH&id=015T00000000vAY"); vertical-align: top; }
        table.sort02 th.table-sorted-desc { background-image:url("/servlet/servlet.ImageServer–oid=00D00000000hZdH&id=015T00000000vAd"); vertical-align: top; }
        
        /* Icons box */
        .iconset {
         margin:5px;
         text-align:center;
         cursor:pointer;
         width:100px;
        }
        .iconset img {
         margin:3px;
        }

        /* Documentation */
        tr.doc_section {
         font-weight:bold;
         text-align:center;
         background-color:#dddddd;
        }
        .headerRow th
        {
         border-bottom: #cccccc 2px solid;
         text-align: left;
         vertical-align: top;
         white-space: nowrap;
         height:20px;
        }
        .dataRows td
        {
         vertical-align: top;
         border-bottom: #e3deb8 1px solid;
         text-align: left;
         height:20px;
         padding-top:5px;
         padding-bottom:5px;
        }
        .titleRow th
        {
         border-bottom: white 1px solid;/*#e5c130 3px solid;*/
         vertical-align: middle;
         background-color: #eeecd1;
         text-align: left;
         font-size: 12pt;
         padding-left:10px;
        }

    </style>
</head>
<body onload="initialize()">
    <center id="mainlist" >
        <table class="external">
            <tr class="titleRow">
                <th  colspan="3">
                    Related Opportunities</th>
            </tr>
            <tr>
                <td  colspan="3" id="DataList">
                    <table id="t1" class="example table-autosort sort02 table-autofilter table-autopage:10 table-stripeclass:alternate table-page-number:t1page table-page-count:t1pages">
                        <thead>                            
                            <tr class="headerRow">
                                <th style="width: 30%;" title="Click to sort" class="table-sortable:default table-sortable">
                                    Opportunity Name</th>
                                <th style="width: 30%;" title="Click to sort" class="table-filterable table-sortable:default table-sortable ">
                                    Account Name</th>
                                <th style="width: 15%;" title="Click to sort" class="table-filterable table-sortable:default table-sortable ">
                                    Business Unit</th>
                                <th style="width: 10%;" title="Click to sort" class="table-filterable table-sortable:default table-sortable ">
                                    Region</th>
                                <th style="width: 15%;" title="Click to sort" class="table-filterable table-sortable:default table-sortable ">
                                    Stage</th>
                            </tr>
                        </thead>
                        <tbody id="mtblBody">

                        </tbody>
                        <tfoot>
                            
                        </tfoot>
                    </table>
                </td>
            </tr>
            <tr>
                <td style="cursor: pointer; text-align: center; border-bottom: #e5c130 1px solid">
                    <a href="#" class="pagelink" id="pageprevious" onclick="pageexample('previous'); return false;"><b>&lt;&lt;&nbsp;</b></a></td>
                <td style="text-align: center; border-bottom: #e5c130 1px solid">
                    Page <span id="t1page"></span>&nbsp;of <span id="t1pages"></span>
                </td>
                <td style="cursor: pointer; text-align: center; border-bottom: #e5c130 1px solid">
                    <a href="#" class="pagelink" id="pagenext" onclick="pageexample('next'); return false;"><b>&nbsp;&gt;&gt;</b></a></td>
            </tr>
            <tr>
                <td colspan="3" style="text-align: center;" id="tfootPages">
                </td>
            </tr>
        </table>
    </center>
    <center>
        <div id="msgSection" style="display: block;">
            <div class="msgDIV" id="msg">
                Please wait while system is processing your request.</div>
        </div>
    </center>
</body>
</html>

 

mojeebahmedmojeebahmed
Here are the instructioon to use the above code. First of all you must have the Table.js file from http://www.javascripttoolbox.com/lib/table/ and create a sinppet in salesforce with any name and include that snippet in the below code and replace the line "{!INCLUDE($Scontrol.Table_Lib)}" with your own snippet. now run the code and hopefully it will run with out any other tweaking. you can place the S-control link on accounts page.

have a close look at the HTML portion of the code where i have defined a table and other html elements and then i have setup the class names for these elements. you can read about the table paging from the above link in more detail. you can change the css in the page to change the table layout.

Let me know if you have any other question.
PramodPramod
Ahmed ,

Thanks for your quick response. I will get back to you soon with results.

Regards

Pramod
PramodPramod
Hi Ahmed ,

Your logic works beautifully for the first search result. However I am creating table based on the custom search criteria. so when user searches second time , rows gets appended to the first search result. To clear first result, I must use mtblBody.innerHTML = " " . (mtblBody is tbody object instance) This works on Firefox but in case of IE tbody.innerHTML is READONLY  . (innerHTMLproperties from Microsoft)

How do I clear tbody so that every time user searches , tbody is created as new object  rather then appending  rows ?

Any suggestions how to get around this?  (Code attached below)

Thanks for your help.

Pramod

Code:
  function displayResultnew(Results)
  {
   var Id,field1,field2,field3,field4, field5,field6;
   
   try
   {
    
    var mTableBody = document.getElementById("mtblBody");

    //Following is not supported in IE. but same code works in firefox
    
    mTableBody.innerHTML = "";
   
    if(Results.size > 0)
    {
     
     var records = Results.getArray("records");
     
     for(var j=0; j<records.length; j++)
     {
      Id    =  records[j].Id;
      field1 = records[j].field1;
      field2 = records[j].field2 ;
      field3  = records[j].field3 ;
      field4   = records[j].field4;
      field5   =  records[j].field5;
      field6 = records[j].field6;
      
      addDBRow(Id,field1,field2,field3,field4, field5,field6,j,mTableBody);
     }
     
     pages = records.length/10;
     if(records.length%10 >0)
     pages++;
     
     document.getElementById("tfootPages").innerHTML = "";
   
     for(var j=1 ; j<=pages ; j++)
     {
      var aLink= "";

      if(j==1)
      aLink = "<a href='#' id='page"+j+"' class='pagelink currentpage' onclick='pageexample("+parseInt(j-1)+"); return false;'>"+j+"</a>" ;
      else
      aLink = "<a href='#' id='page"+j+"' class='pagelink' onclick='pageexample("+parseInt(j-1)+"); return false;'>"+j+"</a>" ;

      document.getElementById("tfootPages").innerHTML += aLink + "\r";
     }           

     pageexample("0");
     
    }
    
   }  
   catch(e) 
   { 
    alert(e + "-" + e.message); 
   }
  }

  function addDBRow(Id,field1,field2,field3,field4, field5,field6,index, mTableBody1)
  {
   
   var mTableBody = mTableBody1;
  
   var Row = document.createElement("tr");

   if(index%2 == 0)
   Row.className = "dataRows alternate";
   else
   Row.className = "dataRows";
   Row.Style = " ";

   Row.id = "tr"+ index;

   var Cell1 = document.createElement("td");
   var Cell2 = document.createElement("td");
   var Cell3 = document.createElement("td");
   var Cell4 = document.createElement("td");
   var Cell5 = document.createElement("td");
   var Cell6 = document.createElement("td");
   
   Cell1.Style = "width = 120";
   Cell2.Style = "width = 300";
   Cell3.Style = "width = 300";
   Cell4.Style = "width = 300";
   Cell5.Style = "width = 25";
   Cell6.Style = "width = 300";
   
   Cell1.innerHTML = field1; 
   Cell2.innerHTML = field2; 
   Cell3.innerHTML = field3;  
   Cell4.innerHTML = field4;  
   Cell5.innerHTML = field5; 
   Cell6.innerHTML = field6; 

   Row.appendChild(Cell1);
   Row.appendChild(Cell2);
   Row.appendChild(Cell3);
   Row.appendChild(Cell4);
   Row.appendChild(Cell5); 
   Row.appendChild(Cell6); 

   mTableBody.appendChild(Row);
   
  }    

  function pageexample(page) 
  {     
   for(var k = 0 ; k < document.getElementsByTagName("a").length ; k++)
   {
    var pageID = document.getElementsByTagName("a")[k].id;

    if(pageID.indexOf("page") == 0)
    {
     var pageClass = document.getElementsByTagName("a")[k].className;
     pageClass = pageClass.replace(/currentpage/, " ");
     document.getElementsByTagName("a")[k].className = pageClass;    
    }
   }

   var t = document.getElementById("t1");
   var res;
   
   if (page=="previous") 
   {
    res=Table.pagePrevious(t);
   }
   else if (page=="next") 
   {
    res=Table.pageNext(t);
   }
   else 
   {
    res=Table.page(t,page);
   }

   var currentPage = parseInt(res.page + 1);     

   document.getElementById("page"+currentPage).className += "currentpage";
  }

    <table id="t1" class="example table-autosort sort02 table-autofilter table-autopage:10 table-stripeclass:alternate table-page-number:t1page table-page-count:t1pages">
      <thead>                            
      <tr class="headerRow">
       <th style="width = 120">field1</th>
       <th style="width = 300">field2</th>
       <th style="width = 300">field3</th>
       <th style="width = 300">field4</th>
       <th style="width = 25">field5<th>
       <th style="width = 300">field6</th> 
      </tr>
     </thead>
     
     <tbody id="mtblBody"></tbody>
     
     <tfoot>
     <tr>
      <td colspan="5" style="text-align: left;" id="tfootPages"></td>
       <td style="text-align: left; border-bottom: #e5c130 1px solid">
       <a href="#" class="pagelink" id="pageprevious" onclick="pageexample('previous'); return false;"><b>&lt;&lt;&nbsp;</b></a> Page 
        <span id="t1page"></span>&nbsp;of <span id="t1pages"></span>
       <a href="#" class="pagelink" id="pagenext" onclick="pageexample('next'); return false;"><b>&nbsp;&gt;&gt;</b></a>
      </td>
     </tr> 
     </tfoot>
     
    </table>

PramodPramod
any help would be great here ... :smileysad:
mojeebahmedmojeebahmed
Hi

    One way to clear the table is to assign a unique Id to each of the row you insert dynamically. like
Row.Id = "rowId" + i ;

    and then when you want to clear the table, just delete these rows by selecting them with their Ids and removing the seleted element from the table.

function removeTbodyRow(rowid)// like 'rowId0'
{  
    var deletedRow = document.getElementById(rowid);   // Selecting the Row element to be deleted

    document.getElementById('tableId').deleteRow(
deletedRow.rowIndex);
}

 modify the above function and use it to remove all the rows in the table. let me know what happen.

PramodPramod
Hi Ahmed ,

This is what worked ..

        function clearTable(tbody)
        {
            while (tbody.rows.length > 0)
            {
            tbody.deleteRow(0);   
            }
        }

Thanks for your excellent help. I am able to create pagination the way I wanted :smileyvery-happy:

Best Regards

Pramod
Will MoxleyWill Moxley
I'm having trouble using this library with firefox.  It works great with IE.  The problem I have with Firefox is that when I first bring up the list, it shows all records (I happen to have 800 records).  I then have to start clicking the paging links for it to only show one page of 10 records at a time.  Any ideas?
GhilliGhilli
Hi,
 
I have a reqiurement like i need to display the specific number of pages per page (Pagination). Kindly share the code wiith me.
 
It would be very helpful for me.
 
Thank you very much.