Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tablesorter + ajax pager + filter #270

Closed
efib opened this issue Mar 28, 2013 · 16 comments
Closed

tablesorter + ajax pager + filter #270

efib opened this issue Mar 28, 2013 · 16 comments
Labels

Comments

@efib
Copy link

efib commented Mar 28, 2013

Hi,
when im using tablesorter with ajax processing pager and filter for each column.
the pager work perfect with the ajax but when im adding the widget 'filter' to the tablesorter im keep getting the same request for page 0 constantly (can be seen in the network at chrome)
i saw there was a bug similar to this that has been solved. but for me it is still happening, even after updating the libraries,
please advice..
Thanks !

@Mottie
Copy link
Owner

Mottie commented Mar 28, 2013

HI @efib! Could you please share the initialization code you are using.

@Mottie
Copy link
Owner

Mottie commented Apr 1, 2013

Actually, now that I think about it, I bet you had an older version with the error.. then you updated the library, but the browser cache didn't update, so you were still seeing the error. Try clearing your browser cache and trying again.

If that doesn't work, it would help me find the problem if you could share the code you are using.

@efib
Copy link
Author

efib commented Apr 2, 2013

Hi,
I did try to clean the cache but didn't solved the problem.
my initialization script is as follow:

$(function() {

    // call the tablesorter plugin 
    $("table").tablesorter({
            theme : 'blue',

            // hidden filter input/selects will resize the columns, so try to minimize the change 
            widthFixed : false,

            // initialize zebra striping and filter widgets 
            widgets : [ "stickyHeaders", "resizable", "columns", "filter" ], //"scroller" /// "filter", 

            headers : {
                0 : {
                    //sorter : false,
                     sorter: 'checkbox',
                    filter : false
                },
                1: {
                    sorter: "digit",
                    filter : true
                },
                2: {
                    sorter: "digit",
                    filter : true
                },
                3: {
                    sorter: "text",
                    filter : true
                }
                ,
                4: {
                      sorter: "text",
                      filter : true
                  },
                5: {
                      sorter: "text",
                      filter : true
                  },
                6: {
                      sorter: "text",
                      filter : true
                  },
                  7: {
                      sorter: "text",
                      filter : true
                  },
                8: {
                      sorter: "text",
                      filter : true
                  },
                9: {
                      sorter: "digit",
                      filter : true
                  }
            },

             // if true, server-side sorting should be performed because
            // client-side sorting will be disabled, but the ui and events
            // will still be used.
            serverSideSorting: true,

            // *** FUNCTIONALITY ***
            // prevent text selection in header
            cancelSelection: false,

            // ignore case while sorting
            ignoreCase: true,



            sortList:[[1,1]],


            widgetOptions : {

            // css class name applied to the sticky header row (tr) 
            stickyHeaders : 'tablesorter-stickyHeader',

            // css class applied to the table row containing the filters & the inputs within that row 
            filter_cssFilter : 'tablesorter-filter',

            // If there are child rows in the table (rows with class name from "cssChildRow" option) 
            // and this option is true and a match is found anywhere in the child row, then it will make that row 
            // visible; default is false 
            filter_childRows : false,

            // if true, filters are collapsed initially, but can be revealed by hovering over the grey bar immediately 
            // below the header row. Additionally, tabbing through the document will open the filter row when an input gets focus 
            filter_hideFilters : false,

            // Set this option to false to make the searches case sensitive 
            filter_ignoreCase : true,

            // jQuery selector string of an element used to reset the filters 
            filter_reset : '.reset',

            // Delay in milliseconds before the filter widget starts searching; This option prevents searching for 
            // every character while typing and should make searching large tables faster. 
            filter_searchDelay : 3000,

            // Set this option to true to use the filter to find text from the start of the column 
            // So typing in "a" will find "albert" but not "frank", both have a's; default is false 
            filter_startsWith : false,


            filter_serversideFiltering : true


        //***************************************************************
        //** The Following Code are for categorized filters / exact Match
        //** More Explanation Can Be Found On http://mottie.github.com/tablesorter/docs/example-widget-filter-custom.html 
        //***************************************************************
        // Add select box to 4th column (zero-based index) 
        // each option has an associated function that returns a boolean 
        // function variables: 
        // e = exact text from cell 
        // n = normalized value returned by the column parser 
        // f = search filter input value 
        // i = column index 
        //filter_functions : { 

        // Add select menu to this column 
        // set the column value to true, and/or add "filter-select" class name to header 
        // 0 : true, 

        // Exact match only 
        //  1 : function(e, n, f, i) { 
        //    return e === f; 
        //  }, 

        // Add these options to the select dropdown (regex example) 
        //  2 : { 
        //    "A - D" : function(e, n, f, i) { return /^[A-D]/.test(e); }, 
        //    "E - H" : function(e, n, f, i) { return /^[E-H]/.test(e); }, 
        //    "I - L" : function(e, n, f, i) { return /^[I-L]/.test(e); }, 
        //    "M - P" : function(e, n, f, i) { return /^[M-P]/.test(e); }, 
        //    "Q - T" : function(e, n, f, i) { return /^[Q-T]/.test(e); }, 
        //    "U - X" : function(e, n, f, i) { return /^[U-X]/.test(e); }, 
        //    "Y - Z" : function(e, n, f, i) { return /^[Y-Z]/.test(e); } 
        //  }, 

        // Add these options to the select dropdown (numerical comparison example) 
        // Note that only the normalized (n) value will contain numerical data 
        // If you use the exact text, you'll need to parse it (parseFloat or parseInt) 
        //  4 : { 
        //    "< $10"      : function(e, n, f, i) { return n < 10; }, 
        //    "$10 - $100" : function(e, n, f, i) { return n >= 10 && n <=100; }, 
        //    "> $100"     : function(e, n, f, i) { return n > 100; } 
        //  } 
        //} 

        // Note: Inside thead -> tr you can put the following: 
        // add "filter-select" class or filter_functions : { 0: true } 
        // add "filter-match" class to just match the content, so selecting "Denni" will also show "Dennis" 
        // Example: 
        // <th class="filter-select" data-placeholder="Select a name">First Name</th>  

        }

    }).tablesorterPager({



        ajaxUrl: '/myAjaxUrl?page={page}&size={size}&sortList={sortList:scol}&filter={filterList:fcol}',

        container: $(".pager"),


        ajaxProcessing: function(data){
            if (data && data.hasOwnProperty('rows')) {
              var r, row, c, d = data.rows,
              // total number of rows (required)
              total = data.total_rows,
              // array of header names (optional)
              headers = data.cols,
              // all rows: array of arrays; each internal array has the table cell data for that row
              rows = [],
              // len should match pager set size (c.size)
              len = d.length;
              // this will depend on how the json is set up - see City0.json
              // rows
              for ( r=0; r < len; r++ ) {
                row = []; // new row array
                // cells
                for ( c in d[r] ) {
                  if (typeof(c) === "string") {
                    row.push(d[r][c]); // add each table cell data to row array
                  }
                }
                rows.push(row); // add new row array to rows array
              }
              return [ total, rows, headers ];
            }
          },

          // output string - default is '{page}/{totalPages}'; possible variables: {page}, {totalPages}, {startRow}, {endRow} and {totalRows}
          output: '{startRow} to {endRow} ({totalRows})',


          // apply disabled classname to the pager arrows when the rows at either extreme is visible - default is true
          updateArrows: false,

          // starting page of the pager (zero based index)
          page: 0,

          // Number of visible rows - default is 10
          size: 20,

          // if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
          // table row set to a height to compensate; default is false
          fixedHeight: false,

          // remove rows from the table to speed up the sort of large tables.
          // setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
          removeRows: false,

          // css class names of pager arrows
          cssNext        : '.next',  // next page arrow
          cssPrev        : '.prev',  // previous page arrow
          cssFirst       : '.first', // go to first page arrow
          cssLast        : '.last',  // go to last page arrow
          cssPageDisplay : '.pagedisplay', // location of where the "output" is displayed
          cssPageSize    : '.pagesize', // page size selector - select dropdown that sets the "size" option
          cssErrorRow    : 'tablesorter-errorRow', // error information row

          // class added to arrows when at the extremes (i.e. prev/first arrows are "disabled" when on the first page)
          cssDisabled    : 'disabled' // Note there is no period "." in front of this class name


     });

});

@efib
Copy link
Author

efib commented Apr 2, 2013

This is my html

<script src="/public/js/jquery-1.8.3.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<link rel="stylesheet" href="/MySystem/public/css/style.css">
<link rel="stylesheet" href="/MySystem/public/css/tablesorter/theme.blue.css">
<link rel="stylesheet" href="/public/css/tablesorter/pager/jquery.tablesorter.pager.css">
<script src="/public/js/tablesorter/jquery.tablesorter.js"></script>
<script src="/public/js/tablesorter/pager/jquery.tablesorter.pager.js"></script>
<script src="/public/js/tablesorter/jquery.tablesorter.widgets.js"></script>
<script src="/public/js/tablesorter/jquery.tablesorter.scroller.js"></script>
<script src="/public/js/MySystem.tablesorterAjax.js"></script>
<div  id="area" class="websites tableWrapperPadding"> 
<div id="stickyfilter" class=""><span></span><p>Filter</p></div>
<table class="tablesorter jqtransform"> 
    <thead class="sticky"> 
        <tr> 

                        <th ><input type="checkbox" class="styled" id="checkAll"  onchange="checkAll(this);" ></th>

                        <th >Base WebSite Id</th>


                        <th >Web Site ID</th>


                        <th >Status</th>


                        <th >Domain1</th>


                        <th >Domain2</th>


                        <th >Path</th>


                        <th >Country</th>


                        <th >Is deleted</th>


                        <th >Server IP</th>
        </tr> 
    </thead> 
    <tbody>



                    <tr>

                            <td><input type="checkbox" class="styled" id="3" onchange="updateChecked(this, 3);"></td>


                            <td>







                                                    3





                            </td>

                            <td>







                                                    3





                            </td>

                            <td>








                            </td>

                            <td>








                            </td>

                            <td>







                                                    www.e.com





                            </td>

                            <td>








                            </td>

                            <td>







                                                    Finland





                            </td>

                            <td>






                                                    <span class="tableicon MMactive"></span>






                            </td>

                            <td>








                            </td>

                    </tr>

                    <tr>

                            <td><input type="checkbox" class="styled" id="4" onchange="updateChecked(this, 4);"></td>


                            <td>







                                                    4





                            </td>

                            <td>







                                                    4





                            </td>

                            <td>








                            </td>

                            <td>








                            </td>

                            <td>







                                                    www.b.com





                            </td>

                            <td>








                            </td>

                            <td>







                                                    Other Country





                            </td>

                            <td>






                                                    <span class="tableicon MMactive"></span>






                            </td>

                            <td>








                            </td>

                    </tr>

                    <tr>

                            <td><input type="checkbox" class="styled" id="5" onchange="updateChecked(this, 5);"></td>


                            <td>







                                                    5





                            </td>

                            <td>







                                                    5





                            </td>

                            <td>








                            </td>

                            <td>








                            </td>

                            <td>







                                                    www.c.com





                            </td>

                            <td>








                            </td>

                            <td>







                                                    Other Country





                            </td>

                            <td>






                                                    <span class="tableicon MMactive"></span>






                            </td>

                            <td>








                            </td>

                    </tr>

                    <tr>

                            <td><input type="checkbox" class="styled" id="6" onchange="updateChecked(this, 6);"></td>


                            <td>







                                                    6





                            </td>

                            <td>







                                                    6





                            </td>

                            <td>








                            </td>

                            <td>








                            </td>

                            <td>







                                                    www.d.com





                            </td>

                            <td>








                            </td>

                            <td>







                                                    Other Country





                            </td>

                            <td>






                                                    <span class="tableicon MMactive"></span>






                            </td>

                            <td>








                            </td>

                    </tr>

                    <tr>

                            <td><input type="checkbox" class="styled" id="7" onchange="updateChecked(this, 7);"></td>


                            <td>







                                                    7





                            </td>

                            <td>







                                                    7





                            </td>

                            <td>








                            </td>

                            <td>








                            </td>

                            <td>







                                                    www.f.com





                            </td>

                            <td>








                            </td>

                            <td>







                                                    Other Country





                            </td>

                            <td>






                                                    <span class="tableicon MMactive"></span>






                            </td>

                            <td>








                            </td>

                    </tr>
    </tbody>
</table>
</div>
<div id="StickyTools" class="websites">


            <div class="clear"></div>
            <div class="pager tablesorter-pager">
                <p class="page">Page:</p>
                <div class="styled-select"><select class="gotoPage"><option>1</option><option>2</option><option>3</option><option>4</option><option>5</option></select></div>   
                <div class="arrownavwrap">  
                    <img src="/images/first.png" class="first" alt="First" title="First page">
                    <img src="/images/prev.png" class="prev" alt="Prev" title="Previous page">
                    <span class="pagedisplay">1 - 10 / 50 (50)</span> <!-- this can be any element, including an input -->
                    <img src="/images/next.png" class="next" alt="Next" title="Next page">
                    <img src="/images/last.png" class="last" alt="Last" title="Last page">
                </div>
                <p class="page">Display:</p>
                <div class="styled-select">
                <select class="pagesize" onchange="fncs();">
                    <option selected="selected" value="10">10</option>
                    <option value="25">25</option>
                    <option value="50">50</option>
                </select> 
                </div>
                <button class="smallButton reset" class="display:inline-block; clear:both;">Reset Filters</button>
            </div>



    <div class="jqoption">
        <span id="jqleftsideimg"></span>
        <div class="jqoptionstrip">
            <div class="tablelinks">    










                        <a id="getVisitWebSiteButtonId" class="smallButton selectOne" rel="customListButton" href="javascript:perform('/visitWebSite?id=)');">
                            <span class="jqstripbg">
                                <span class="addButtonicon"></span>
                                <span class="txtlink">Visit Web Site</span>
                            </span>
                        </a>
                        <span class="divider"></span>           



            </div>
            <div class="jqmnenustrip"></div>
        </div>
        <img src="/images/jq-optionbg-right.png" class="jqmnenurightend" alt="" />
    </div>
</div>

@efib
Copy link
Author

efib commented Apr 4, 2013

any idea on how to solve it ?

@Mottie
Copy link
Owner

Mottie commented Apr 4, 2013

Hi @efib!

I looked over your code and it all appears to be correct. I'm not sure why you're still having errors, but could you please double check that the tablesorter, tablesorter widgets AND the pager plugin have all been updated to the latest version.

If it still doesn't work properly, it would help if you could share a live demo of your code.

I think in the next version, I'll make the pager addon output some debugging info to help further isolate the problem.

@psharp
Copy link

psharp commented Apr 4, 2013

Greetings Mottie,

I am also having the same issue when using the filter option. I have a dynamic data source used for paging/sorting, but as soon as I add the filter component, the plugin goes into a "get page 0 " loop.The requests are about 1/2 second apart and it seems that I cannot turn it off.

The version that I'm using was taken from github and the date of the source files is March 4.

This is the init code:

<link rel="stylesheet" type="text/css" href="/lib/tablesorter-master/css/theme.jui.css" />
<link rel="stylesheet" type="text/css" href="/lib/tablesorter-master/addons/pager/jquery.tablesorter.pager.css" />
<script type="text/javascript" src="/lib/tablesorter-master/addons/pager/jquery.tablesorter.pager.js"></script>
<script type="text/javascript" src="/lib/tablesorter-master/js/jquery.tablesorter.js"></script>
<script type="text/javascript" src="/lib/tablesorter-master/js/jquery.tablesorter.widgets.js"></script>
<script type="text/javascript" src="/lib/tablesorter-master/js/jquery.tablesorter.widgets-filter-formatter.js"></script>
$("#HistoryAjax .tablesorter")
    .tablesorter({
      theme: 'jui',
      widthFixed: false,
      sortLocaleCompare: true, 
      widgets: ['zebra','stickyHeaders','uitheme','filter']
    }) 

    .tablesorterPager({
      container: $(".pager"),
      ajaxUrl : 'controller/ctl_apps_soar.php?action=archive_ajax&page={page}&size={size}&{sortList:col}&{filterList:fcol}',
      ajaxProcessing: function(data){
        if (data && data.hasOwnProperty('rows')) {
          var r, row, c, d = data.rows,
          total = data.total_rows,

          headers = data.cols,

          rows = [],
          len = d.length;

          for ( r=0; r < len; r++ ) {

            row = []; 

            for ( c in d[r] ) {

              if (typeof(c) === "string") {

                row.push(d[r][c]); 
              }
            }
            rows.push(row); 
          }
          return [ total, rows, headers ];

        }
      },

      output: '{startRow} to {endRow} ({totalRows}) filtered ({filteredRows})',
      updateArrows: true,
      page: 0,
      size: 20,
      fixedHeight: false,
      removeRows: false,


      cssNext        : '.next',  // next page arrow
      cssPrev        : '.prev',  // previous page arrow

      cssFirst       : '.first', // go to first page arrow

      cssLast        : '.last',  // go to last page arrow

      cssPageDisplay : '.pagedisplay', // location of where the "output" is displayed

      cssPageSize    : '.pagesize', // page size selector - select dropdown that sets the "size" option

      cssErrorRow    : 'tablesorter-errorRow', // error information row


      // class added to arrows when at the extremes (i.e. prev/first arrows are "disabled" when on the first page)
      cssDisabled    : 'disabled' // Note there is no period "." in front of this class name
    });

and the html:

<table>
    <thead>
    <tr>
    <td class="pager" colspan="12">
        <img src="../common/images/img_result_beg.png" class="first"/>
        <img src="../common/images/img_result_back.png" class="prev"/>
        <span class="pagedisplay"></span> <!-- this can be any element, including an input -->
        <img src="../common/images/img_result_next.png" class="next"/>
        <img src="../common/images/img_result_end.png" class="last"/>
        <select class="pagesize">
                <option value="10">10</option>
                <option selected="selected" value="20">20</option>
                <option value="30">30</option>
                <option value="40">40</option>
        </select>
    </td>
    </tr>
    </thead>
</table>
<table class="tablesorter">
    <thead>
    <tr>
        <th>1</th>
        <th>2</th>
        <th>3</th>
        <th>4</th>
        <th>5</th>
        <th>6</th>
        <th>7</th>
        <th>8</th>
        <th>9</th>
        <th>10</th>
        <th>11</th>
        <th>12</th>
    </tr>
  </thead>
  <tbody> <!-- tbody will be loaded via JSON -->
  </tbody>
</table>

@psharp
Copy link

psharp commented Apr 4, 2013

It should be noted that without the filter option, the table sorter works perfectly.

@Mottie
Copy link
Owner

Mottie commented Apr 4, 2013

Thanks, I'll dive into the code and see if I can fix it.

@psharp
Copy link

psharp commented Apr 4, 2013

FWIW, I did also try the following option set to override the default settings of the sort and filter:

.tablesorter({
    headers    : {
        0 : { sorter : "digit" }, 
        1 : { sorter : "text" }, 
        2 : { sorter : "shortDate" }, 
        3 : { sorter : "text" }, 
        4 : { sorter : "text" }, 
        5 : { sorter : "text" }, 
        6 : { sorter : "text" }, 
        7 : { sorter : "text" }, 
        8 : { sorter : "text", filter : false },
        9 : { sorter : "text" },
        10 : { sorter : "text" },
        11 : { sorter : "text", filter : false}
      },
      theme: 'jui',
      widthFixed: false,
      sortLocaleCompare: true, // needed for accented characters in the data
      widgets: ['zebra','stickyHeaders','uitheme','filter'],
      widgetOptions : { filter_hideFilters : false, filter_ignoreCase : true, filter_serversideFiltering : true }
    })

@psharp
Copy link

psharp commented Apr 8, 2013

Any luck with this?

After jumping into the code, my guess is that the problem may live in jquery.tablesorter.pager.js (near getAjaxUrl) .

Without the ajax part of it, the plugin just fine. Sadly, the dataset is so large, it even breaks chrome, so I really have to use the ajax aspect of this :)

@Mottie
Copy link
Owner

Mottie commented Apr 9, 2013

@psharp Sorry, still working on this... not much free time lately.

@airthomas
Copy link

I have applied pager with ajax, after that how can I setup the tbody td alignment ? without ajax, I can apply etc, many thanks.

@Mottie
Copy link
Owner

Mottie commented Mar 30, 2015

Hi @airthomas!

Have you looked at the code examples for the ajaxProcessing callback function?

Here is a full working example.

@airthomas
Copy link

i got it, thanks Mottie, will you consider to add this feature to tablesorter such as tbodyAlignment etc instead of by ajaxProcessing. Many thanks.

@Mottie
Copy link
Owner

Mottie commented Mar 30, 2015

I don't understand what you mean by tbody alignment? And how would it be different from ajaxProcessing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants