1
0
mirror of https://github.com/DataTables/DataTables.git synced 2025-02-20 18:54:15 +01:00

New: Invalidation and data set methods.

- New API methods:
  - rows().invalidate() - Invalidate the matched rows
  - row().invalidate() - Invalidate the matched row
  - row().data( set ) - Set the data to use for the matched row

- This involves building upon the invalidation work done in the last few
  commits and creating an invalidation function. This new function will
  mark the cached data as invalid for re-reading by the sort and
  filtering methods (this will need to be abstracted into modules in
  1.11, but there is no infrastructure for that yet - that's what 1.11
  is all about). Additionally the invalidation method will update either
  the data held by DataTables (read from the DOM), or update the DOM if
  the data source was not the DOM. A flag allows an override to state
  the direction, although I think that generally speaking you might not
  want to use the override (you might nuke parts of your data source
  object if you read from the dom for example).
This commit is contained in:
Allan Jardine 2013-05-18 11:49:48 +01:00
parent fbc28624ac
commit d7b12bd83b
6 changed files with 116 additions and 45 deletions

View File

@ -40,18 +40,29 @@ _api.register( 'row().data()', function ( data ) {
var ctx = this.context;
if ( ctx.length && this.length ) {
// Get
return ctx[0].aoData[ this[0] ]._aData;
}
// return undefined;
// @todo - Set operator
// Set
ctx[0].aoData[ this[0] ]._aData = data;
// Invalidate the row
// Automatically invalidate
_fnInvalidateRow( ctx[0], this[0], 'data' );
return this;
} );
// Should row object have an invalidated flag? Scan the array before doing
// anything with the data? or better to update at the invalidation point
_api.register( 'row().invalidate()', function ( src ) {
var ctx = this.context;
if ( ctx.length && this.length ) {
_fnInvalidateRow( ctx[0], this[0], src );
}
return this;
} );
_api.register( 'row().index()', function () {

View File

@ -57,13 +57,16 @@ _api.register( 'rows().data()', function ( data ) {
} );
_api.register( 'rows().invalidate()', function ( src ) {
return this.iterator( true, 'row', function ( settings, row ) {
_fnInvalidateRow( settings, row, src );
} );
} );
_api.register( 'rows().remove()', function () {
var that = this;
// Needs either a corrector to correct for deleted row indexes, or
// need to order and reverse so indexing is maintained for the row
// indexes. Damn
// @todo
return this.iterator( true, 'row', function ( settings, row, thatIdx ) {
var data = settings.aoData;
@ -83,7 +86,7 @@ _api.register( 'rows().remove()', function () {
// Delete from the display arrays
_fnDeleteIndex( settings.aiDisplayMaster, row );
_fnDeleteIndex( settings.aiDisplay, row );
_fnDeleteIndex( that[ thatIdx ], row, false );
_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
// Check for an 'overflow' they case for displaying the table
_fnLengthOverflow( settings );

View File

@ -14,11 +14,13 @@
function _fnAddData ( oSettings, aDataIn, nTr, anTds )
{
var oCol;
/* Create the object for storing information about this new row */
var iRow = oSettings.aoData.length;
var oData = $.extend( true, {}, DataTable.models.oRow );
var oData = $.extend( true, {}, DataTable.models.oRow, {
src: nTr ? 'dom' : 'data'
} );
oData._aData = aDataIn;
oSettings.aoData.push( oData );
@ -75,30 +77,16 @@ function _fnAddData ( oSettings, aDataIn, nTr, anTds )
*/
function _fnAddTr( oSettings, trs )
{
var row;
// Allow an individual node to be passed in
if ( ! (trs instanceof $) ) {
trs = $(trs);
}
trs.each( function () {
var
d = [],
tds = [],
td = this.firstChild,
name;
while ( td )
{
name = td.nodeName.toUpperCase();
if ( name == "TD" || name == "TH" )
{
d.push( $.trim(td.innerHTML) );
tds.push( td );
}
td = td.nextSibling;
}
_fnAddData( oSettings, d, this, tds );
row = _fnGetRowData( this );
_fnAddData( oSettings, row.data, this, row.cells );
} );
}
@ -511,3 +499,74 @@ function _fnDeleteIndex( a, iTarget, splice )
}
}
/**
* Mark cached data as invalid such that a re-read of the data will occur when
* the cached data is next requested. Also update from the data source object.
*
* @param {object} settings DataTables settings object
* @param {int} rowIdx Row index to invalidate
* @memberof DataTable#oApi
*
* @todo For the modularisation of v1.11 this will need to become a callback, so
* the sort and filter methods can subscribe to it. That will required
* initialisation options for sorting, which is why it is not already baked in
*/
function _fnInvalidateRow( settings, rowIdx, src )
{
var row = settings.aoData[ rowIdx ];
// Are we reading last data from DOM or the data object?
if ( src === 'dom' || (! src && row.src === 'dom') ) {
// Read the data from the DOM
row._aData = _fnGetRowData( row.nTr ).data;
}
else {
// Reading from data object, update the DOM
var cells = row.anCells;
for ( var i=0, ien=cells.length ; i<ien ; i++ ) {
cells[i].innerHTML = _fnGetCellData( settings, rowIdx, i, 'display' );
}
}
row._aSortData = null;
row._aFilterData = null;
}
/**
* Build a data source object from an HTML row, reading the contents of the
* cells that are in the row.
*
* @param {node} TR element from which to read data
* @returns {object} Object with two parameters: `data` the data read, in
* document order, and `cells` and array of nodes (they can be useful to the
* caller, so rather than needing a second traversal to get them, just return
* them from here).
* @memberof DataTable#oApi
*/
function _fnGetRowData( row )
{
var
d = [],
tds = [],
td = row.firstChild,
name;
while ( td ) {
name = td.nodeName.toUpperCase();
if ( name == "TD" || name == "TH" ) {
d.push( $.trim(td.innerHTML) );
tds.push( td );
}
td = td.nextSibling;
}
return {
data: d,
cells: tds
};
}

View File

@ -393,10 +393,3 @@ function _fnFilterData ( settings )
}
}
function _fnFilterInvalidate( settings, row )
{
row._aFilterData = null;
}

View File

@ -417,9 +417,3 @@ function _fnSortData( settings, idx )
}
}
function _fnSortInvalidate( settings, row )
{
row._aSortData = false;
}

View File

@ -65,5 +65,16 @@ DataTable.models.oRow = {
* @default <i>Empty string</i>
* @private
*/
"_sRowStripe": ""
"_sRowStripe": "",
/**
* Denote if the original data source was from the DOM, or the data source
* object. This is used for invalidating data, so DataTables can
* automatically read data from the original source, unless uninstructed
* otherwise.
* @type string
* @default null
* @private
*/
"src": null
};