1
0
mirror of https://github.com/DataTables/DataTables.git synced 2025-01-30 23:52:11 +01:00

New: eq() API method to reduce an API instance to just a single context

and result set for the plural methods.

Fix: Row details events were itterating over non-DataTables rows
creating a Javascript error

Fix: Example - Server-side processing row details example updated to be
able to restore the details row on a redraw.

Update: Documentation - Most examples which used `flatten()` are more
correct to use the new `eq()` method, so they have been updated.

- This set of changes is based on the discussion in thread 19377. While
  working on the fix, I realised that the use of flatten() is too broad,
  so the new `eq()` function is introduced. It is similar to the jQuery
  eq() method in that it reduces the instance to just the selected
  index, although in DataTables this is both the context and the result
  set. Its a small addition, but I think it will provide to be very
  useful
This commit is contained in:
Allan Jardine 2014-02-11 11:04:50 +00:00
parent 71849cc321
commit 7f9f954d99
5 changed files with 102 additions and 22 deletions

View File

@ -1 +1 @@
848be40591690163c03003346ee3748aec1b0006 19a4f46a4f58fd7d24197f3ab6b550a4fd29dcae

View File

@ -36,7 +36,7 @@ $(document).ready(function() {
var dt = $('#example').DataTable( { var dt = $('#example').DataTable( {
"processing": true, "processing": true,
"serverSide": true, "serverSide": true,
"ajax": "scripts/objects.php", "ajax": "scripts/ids-objects.php",
"columns": [ "columns": [
{ {
"class": "details-control", "class": "details-control",
@ -52,18 +52,37 @@ $(document).ready(function() {
"order": [[1, 'asc']] "order": [[1, 'asc']]
} ); } );
// Array to track the ids of the details displayed rows
var detailRows = [];
$('#example tbody').on( 'click', 'tr td:first-child', function () { $('#example tbody').on( 'click', 'tr td:first-child', function () {
var tr = $(this).parents('tr'); var tr = $(this).parents('tr');
var row = dt.row( tr ); var row = dt.row( tr );
var idx = $.inArray( tr.attr('id'), detailRows );
if ( row.child.isShown() ) { if ( row.child.isShown() ) {
tr.removeClass( 'details' ); tr.removeClass( 'details' );
row.child.hide(); row.child.hide();
// Remove from the 'open' array
detailRows.splice( idx, 1 );
} }
else { else {
tr.addClass( 'details' ); tr.addClass( 'details' );
row.child( format( row.data() ) ).show(); row.child( format( row.data() ) ).show();
// Add to the 'open' array
if ( idx === -1 ) {
detailRows.push( tr.attr('id') );
} }
}
} );
// On each draw, loop over the `detailRows` array and show any child rows
dt.on( 'draw', function () {
$.each( detailRows, function ( i, id ) {
$('#'+id+' td:first-child').trigger( 'click' );
} );
} ); } );
} ); } );
@ -97,6 +116,12 @@ $(document).ready(function() {
information to show. Note that the format details function has access to the full data source object information to show. Note that the format details function has access to the full data source object
for the row, including information that is not actually shown in the table (the salary parameter for for the row, including information that is not actually shown in the table (the salary parameter for
example).</p> example).</p>
<p>Furthermore, this example shows a small difference from the <a href=
"../api/row_details.html">client-side row details example</a> in that to have rows automatically reopen
when the table is redrawn, we need to track a unique identifier for each row - in this case the row
<code>id</code>. This is required because in server-side processing mode rows are automatically
destroyed and recreated on each draw.</p>
</div> </div>
<table id="example" class="display" cellspacing="0" width="100%"> <table id="example" class="display" cellspacing="0" width="100%">
@ -142,7 +167,7 @@ $(document).ready(function() {
var dt = $('#example').DataTable( { var dt = $('#example').DataTable( {
&quot;processing&quot;: true, &quot;processing&quot;: true,
&quot;serverSide&quot;: true, &quot;serverSide&quot;: true,
&quot;ajax&quot;: &quot;scripts/objects.php&quot;, &quot;ajax&quot;: &quot;scripts/ids-objects.php&quot;,
&quot;columns&quot;: [ &quot;columns&quot;: [
{ {
&quot;class&quot;: &quot;details-control&quot;, &quot;class&quot;: &quot;details-control&quot;,
@ -158,18 +183,37 @@ $(document).ready(function() {
&quot;order&quot;: [[1, 'asc']] &quot;order&quot;: [[1, 'asc']]
} ); } );
// Array to track the ids of the details displayed rows
var detailRows = [];
$('#example tbody').on( 'click', 'tr td:first-child', function () { $('#example tbody').on( 'click', 'tr td:first-child', function () {
var tr = $(this).parents('tr'); var tr = $(this).parents('tr');
var row = dt.row( tr ); var row = dt.row( tr );
var idx = $.inArray( tr.attr('id'), detailRows );
if ( row.child.isShown() ) { if ( row.child.isShown() ) {
tr.removeClass( 'details' ); tr.removeClass( 'details' );
row.child.hide(); row.child.hide();
// Remove from the 'open' array
detailRows.splice( idx, 1 );
} }
else { else {
tr.addClass( 'details' ); tr.addClass( 'details' );
row.child( format( row.data() ) ).show(); row.child( format( row.data() ) ).show();
// Add to the 'open' array
if ( idx === -1 ) {
detailRows.push( tr.attr('id') );
} }
}
} );
// On each draw, loop over the `detailRows` array and show any child rows
dt.on( 'draw', function () {
$.each( detailRows, function ( i, id ) {
$('#'+id+' td:first-child').trigger( 'click' );
} );
} ); } );
} );</code> } );</code>

View File

@ -29,7 +29,16 @@ $primaryKey = 'id';
// parameter represents the DataTables column identifier. In this case simple // parameter represents the DataTables column identifier. In this case simple
// indexes + the primary key column for the id // indexes + the primary key column for the id
$columns = array( $columns = array(
array( 'db' => 'id', 'dt' => 'DT_RowId' ), array(
'db' => 'id',
'dt' => 'DT_RowId',
'formatter' => function( $d, $row ) {
// Technically a DOM id cannot start with an integer, so we prefix
// a string. This can also be useful if you have multiple tables
// to ensure that the id is unique with a different prefix
return 'row_'.$d;
}
),
array( 'db' => 'first_name', 'dt' => 0 ), array( 'db' => 'first_name', 'dt' => 0 ),
array( 'db' => 'last_name', 'dt' => 1 ), array( 'db' => 'last_name', 'dt' => 1 ),
array( 'db' => 'position', 'dt' => 2 ), array( 'db' => 'position', 'dt' => 2 ),

View File

@ -29,7 +29,16 @@ $primaryKey = 'id';
// parameter represents the DataTables column identifier - in this case object // parameter represents the DataTables column identifier - in this case object
// parameter names // parameter names
$columns = array( $columns = array(
array( 'db' => 'id', 'dt' => 'DT_RowId' ), array(
'db' => 'id',
'dt' => 'DT_RowId',
'formatter' => function( $d, $row ) {
// Technically a DOM id cannot start with an integer, so we prefix
// a string. This can also be useful if you have multiple tables
// to ensure that the id is unique with a different prefix
return 'row_'.$d;
}
),
array( 'db' => 'first_name', 'dt' => 'first_name' ), array( 'db' => 'first_name', 'dt' => 'first_name' ),
array( 'db' => 'last_name', 'dt' => 'last_name' ), array( 'db' => 'last_name', 'dt' => 'last_name' ),
array( 'db' => 'position', 'dt' => 'position' ), array( 'db' => 'position', 'dt' => 'position' ),

View File

@ -6596,6 +6596,16 @@
}, },
eq: function ( idx )
{
var ctx = this.context;
return ctx.length > idx ?
new _Api( ctx[idx], this[idx] ) :
null;
},
filter: function ( fn ) filter: function ( fn )
{ {
var a = []; var a = [];
@ -7413,11 +7423,19 @@
order = opts.order, // applied, current, index (original - compatibility with 1.9) order = opts.order, // applied, current, index (original - compatibility with 1.9)
page = opts.page; // all, current page = opts.page; // all, current
if ( _fnDataSource( settings ) == 'ssp' ) {
// In server-side processing mode, most options are irrelevant since
// rows not shown don't exist and the index order is the applied order
// Removed is a special case - for consistency just return an empty
// array
return search === 'removed' ?
[] :
_range( 0, displayMaster.length );
}
else if ( page == 'current' ) {
// Current page implies that order=current and fitler=applied, since it is // Current page implies that order=current and fitler=applied, since it is
// fairly senseless otherwise, regardless of what order and search actually // fairly senseless otherwise, regardless of what order and search actually
// are // are
if ( page == 'current' )
{
for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) { for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
a.push( displayFiltered[i] ); a.push( displayFiltered[i] );
} }
@ -7749,28 +7767,28 @@
var __details_events = function ( settings ) var __details_events = function ( settings )
{ {
var table = $(settings.nTable); var api = new _Api( settings );
var namespace = '.dt.DT_details'; var namespace = '.dt.DT_details';
var drawEvent = 'draw'+namespace;
var colvisEvent = 'column-visibility'+namespace;
table.off('draw'+namespace); api.off( drawEvent +' '+ colvisEvent );
table.off('column-visibility'+namespace);
if ( _pluck( settings.aoData, '_details' ).length > 0 ) { if ( _pluck( settings.aoData, '_details' ).length > 0 ) {
// On each draw, insert the required elements into the document // On each draw, insert the required elements into the document
table.on('draw'+namespace, function () { api.on( drawEvent, function () {
table.find('tbody tr').each( function () { api.rows( {page:'current'} ).eq(0).each( function (idx) {
// Look up the row index for each row and append open row // Internal data grab
var rowIdx = _fnNodeToDataIndex( settings, this ); var row = settings.aoData[ idx ];
var row = settings.aoData[ rowIdx ];
if ( row._detailsShow ) { if ( row._detailsShow ) {
row._details.insertAfter( this ); row._details.insertAfter( row.nTr );
} }
} ); } );
} ); } );
// Column visibility change - update the colspan // Column visibility change - update the colspan
table.on( 'column-visibility'+namespace, function ( e, settings, idx, vis ) { api.on( colvisEvent, function ( e, settings, idx, vis ) {
// Update the colspan for the details rows (note, only if it already has // Update the colspan for the details rows (note, only if it already has
// a colspan) // a colspan)
var row, visible = _fnVisbleColumns( settings ); var row, visible = _fnVisbleColumns( settings );