[COMPLETE SOLUTION] - Passing Filtered and/or Paginated Form Fields with Optional Check All Feature

[COMPLETE SOLUTION] - Passing Filtered and/or Paginated Form Fields with Optional Check All Feature

JoyrexJoyrex Posts: 92Questions: 14Answers: 3
edited February 2019 in DataTables 1.9
I'm posting this "complete solution" (hopefully it is for the vast majority of you) of how to handle passing form fields that are visible or hidden (due to pagination or filtering) and optionally, having a "check all" checkbox. I spent the last few days culling together various bits to come to this complete solution that met all my needs - hopefully it will save others time in future and possibly help less experienced users understand what is possible with the power of dataTables. Let's get started.

PROBLEM: You need to pass form fields (usually in the form of a checkbox) from rows in your dataTable to another script via a FORM. You need to account for not only form fields that are not visible (say due to pagination or filtering), but also the visible fields as well. A "check all" feature would aid users with large datasets if they wanted to do a "check all", filtering or not.

It's important to understand dataTables removes hidden nodes (aka rows in your dataTable) from the DOM, so simply wrapping a FORM around your dataTable will NOT pass all the checkboxes that are there - it will only pass the visible ones (visible because of the current page in the pagination set you are viewing, or due to filtering of the dataset, or a combination of both).

By including two plugins (one of which is detailed in the dataTables API) (http://datatables.net/plug-ins/api), we can solve these issues.

To include these plugins, you must save the following code to a .js file, or include them BEFORE you initialize the dataTable (e.g.: before the $('yourtable').dataTable() in your script block). If you are including them as a file, they must come AFTER jQuery, and AFTER the dataTables JS script includes. For example:


```html



```

Notice the two filenames - fnGetHiddenNodes and fnGetFilteredNodes - each one handles different aspects of our problem, and as you might surmise, the fnGetHiddenNodes handles any nodes that are hidden (by pagination), and fnGetFilteredNodes handles any nodes that are filtered (whether they are hidden by pagination or not).

Since fnGetFilteredNodes is not in the API Documentation (the link I provided above), here is the script:


```js
$.fn.dataTableExt.oApi.fnGetFilteredNodes = function ( oSettings )
{
var anRows = [];
for ( var i=0, iLen=oSettings.aiDisplay.length ; i

Replies

  • allanallan Posts: 63,602Questions: 1Answers: 10,486 Site admin
    Fantastic - thanks for compiling this information and putting it all together. I'm sure it will benefit a number of others!

    Regards,
    Allan
  • HaruyaHaruya Posts: 2Questions: 1Answers: 0

    Hi Joyrex..

    I've read the instruction above, and seems like i cannot get the code to run properly..

    the code still send the current page value, i'm trying to insert the checked value to database, but my code seems like only send the first page of the tables.

  • RolloutRollout Posts: 1Questions: 0Answers: 0
    edited September 2014

    Hi, I am trying to get a "Check All" checkbox in the the DataTables TH area to check all the boxes in all the rows - WHEN using pagination. Presently, it checks all the boxes in the current page, but not subsequent pages (page 2, 3, etc). I am using the following initialization code:

    $(document).ready(function () { var table = $('#tblDisplay').DataTable({ scrollX: true, paging: true, bFilter: false, ordering: false, pagingType: 'full_numbers', }); new $.fn.dataTable.FixedColumns(table, { leftColumns: 5, }); });

    Any idea how I can extend this code to include page 2, 3, etc?

  • perelliperelli Posts: 3Questions: 1Answers: 0
    edited February 2015

    Very nice :)

    I have a question - do you know how to make this work when "bDeferRender": true is set? When this is set, only items on first page is selected.

  • allanallan Posts: 63,602Questions: 1Answers: 10,486 Site admin

    The whole point of deferRender is that the nodes aren't created until they are needed (i.e. drawn on the page). So simply put the solution above is not compatible with deferred rendering since it requires the nodes to be available.

    Allan

  • kshitijahujakshitijahuja Posts: 4Questions: 1Answers: 0

    Hey Guys,

    Some nice work there. Does this applies to the newer versions of DataTables (1.10 onwards)? I am using sbadmin2 with datatables the above code doesnt seems to work for me.

    Any suggestions?

    Thanks!

  • JoyrexJoyrex Posts: 92Questions: 14Answers: 3
    edited July 2015

    No, the API for DataTables 1.10 is different - it's actually a lot simpler as you don't need the functions anymore mentioned above as the new API can handle things. For instance:

    This is the update version of the check all (filtered, paginated or both) script:

    $('#emailMembers #check_all').change(function() {
    
        var checked = $(this).is(":checked");
    
        $("input", table.rows({search:'applied'}).nodes()).each(function(){
            if(checked){
                $(this).attr("checked", true);
            }
            else {
                $(this).attr("checked", false);
            }
        });
    
    });
    

    Just make sure when you initialize the DataTable, you are using DataTable() versus dataTable (note the uppercase "D") - that will invoke the new API.

  • allanallan Posts: 63,602Questions: 1Answers: 10,486 Site admin
    edited September 2015

    I would even simplify that:

    $('#emailMembers #check_all').change(function() {
        var checked = $(this).is(":checked");
    
        $("input", table.rows({search:'applied'}).nodes()).prop( 'checked', checked );
    } );
    

    No need for the loop, since jQuery will do that for you :-). Also you don't need the if statement for a boolean setting, since you already have the boolean value you want to set.

    Allan

  • JoyrexJoyrex Posts: 92Questions: 14Answers: 3

    @Allan: Nice! Learn something new every day! Thanks!

  • ViniciusMachadoViniciusMachado Posts: 10Questions: 1Answers: 0
    edited August 2015

    Hi Joyrex, I'm having problem with the input and select fields. I tried to use your solution but I could'nt. I'm using the new version of Datatables any clue for me? The data still not sending from the form via post. When I submit I got nothing.

    Regards,

  • JoyrexJoyrex Posts: 92Questions: 14Answers: 3

    @ViniciusMachado: Not sure quite what you mean about the input and select fields - can you make a JSFiddle or DataTables Live of your code?

  • ViniciusMachadoViniciusMachado Posts: 10Questions: 1Answers: 0

    Hi @Joyrex thanks for the response but I've just realized I was making a stupid mistake ;(

    There was a tag not closed at my code. Regards

  • JoyrexJoyrex Posts: 92Questions: 14Answers: 3

    Ah, good! Glad you got it sorted out!

  • noguer19noguer19 Posts: 2Questions: 0Answers: 0
    edited September 2015

    @Allan, I´m using your code but i don´t know why it only works twice. I mean, i click the select all checkbox the first time and it chek them all, then i click it again and it uncheck them all too, but if i want to check them all again it does not work anymore. Can you suggest something? this is the code i´m using:

    <script>
        $(function () {
            var table = $('#MyTable').DataTable({
                "lengthMenu": [[5, 10, 20, -1], [5, 10, 20, "All"]]
            });
    
            $("#check_all").change(function () {
                var checked = $(this).is(":checked");
                alert(checked);
                $("input", table.rows({ search: 'applied' }).nodes()).attr('checked', checked);
    
            });
        });
    </script> 
    
    then into the thead i´ve got this:  <input name="checkboxname" type="checkbox" value="All" id="check_all">&nbsp; <label>Select All</label>
    
  • noguer19noguer19 Posts: 2Questions: 0Answers: 0
    edited September 2015

    Well i found the solution in stackoverflow and it´s just using the prop() method instead of attr(). not so sure what the difference is but now it works fine..

  • allanallan Posts: 63,602Questions: 1Answers: 10,486 Site admin
    edited September 2015

    Yes - $().prop() is the correct method to use here, not $().attr(). I've updated my post. Thanks for pointing this out.

    Allan

This discussion has been closed.