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:
<script type="text/javascript" src="/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="/js/dataTables.fnGetHiddenNodes.js"></script>
<script type="text/javascript" src="/js/dataTables.fnGetFilteredNodes.js"></script>
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:
$.fn.dataTableExt.oApi.fnGetFilteredNodes = function ( oSettings )
{
var anRows = [];
for ( var i=0, iLen=oSettings.aiDisplay.length ; i<iLen ; i++ )
{
var nRow = oSettings.aoData[ oSettings.aiDisplay[i] ].nTr;
anRows.push( nRow );
}
return anRows;
};
copy the above into a new file and save it as dataTables.fnGetFilteredNodes.js and follow the inclusion instructions previously mentioned.
fnGetHiddenNodes is available in the API documentation, but here it is anyway for convenience:
$.fn.dataTableExt.oApi.fnGetHiddenNodes = function ( oSettings )
{
/* Note the use of a DataTables 'private' function thought the 'oApi' object */
var anNodes = this.oApi._fnGetTrNodes( oSettings );
var anDisplay = $('tbody tr', oSettings.nTable);
/* Remove nodes which are being displayed */
for ( var i=0 ; i<anDisplay.length ; i++ )
{
var iIndex = jQuery.inArray( anDisplay[i], anNodes );
if ( iIndex != -1 )
{
anNodes.splice( iIndex, 1 );
}
}
/* Fire back the array to the caller */
return anNodes;
};
Now, in order to implement the "check all" feature, you'll need an input in your dataTable output - there's a million different ways to do this, but here's the code I use:
<input name="Custodians" type="checkbox" value="All" class="checkall">
This input (which you can put in the TH section of your TABLE) will be what the user will click on to select all the checkboxes in the data set (visible or not, filtered or not).
Here's the script that initializes your dataTable, and also implements the check all feature, and the calls to ensure the checked fields (whether hidden, filtered, or not) are passed to your form:
$(document).ready(function () {
oTable = $('#LHQResponses').dataTable();
} );
$('form[name=yourformsnameattribute]').submit(function(){ //replace 'yourformsnameattribute' with the name of your form
$(oTable.fnGetHiddenNodes()).find('input:checked').appendTo(this); //this is what passes any hidden nodes to your form when a user clicks SUBMIT on your FORM
} );
$('.checkall').click( function() { //this is the function that will mark all your checkboxes when the input with the .checkall class is clicked
$('input', oTable.fnGetFilteredNodes()).attr('checked',this.checked); //note it's calling fnGetFilteredNodes() - this is so it will mark all nodes whether they are filtered or not
} );
Assuming your FORM is wrapped around your TABLE in your HTML output, this should work with no problems. Please note the fields are submitted when a user clicks on your FORM's SUBMIT button, after they have clicked on at least one checkbox in your TABLE output or the checkbox to select all checkboxes.
Huge thanks to everyone (especially Allan) who contributed portions of the above solution, and I hope posting it here all together helps others and saves time!