mirror of
https://github.com/DataTables/DataTables.git
synced 2024-12-01 13:24:10 +01:00
New - rows().cells(), columns.cells() API methods.
- row options for column selector - Selectors (table, rows and columns) now held in a single file, sharing structure. A more unified API is used, with row options also being allow for columns, through the use of the second parameter for the columns() method, which will effect how a column function can act upon rows (for example, the order of the rows when getting data or nodes). - Dev: tables() is no longer an iterator - using an `iterator()` method with options which are suitable for the different types of iteration the API needs.
This commit is contained in:
parent
638a1f6225
commit
68ea9af828
@ -1,16 +1,50 @@
|
||||
|
||||
|
||||
|
||||
var _pluck = function ( a, prop ) {
|
||||
var _pluck = function ( a, prop, prop2 ) {
|
||||
var out = [];
|
||||
var i=0, ien=a.length;
|
||||
|
||||
for ( var i=0, ien=a.length ; i<ien ; i++ ) {
|
||||
out.push( a[i][ prop ] );
|
||||
// Could have the test in the loop for slightly smaller code, but speed
|
||||
// is essential here
|
||||
if ( prop2 !== undefined ) {
|
||||
for ( ; i<ien ; i++ ) {
|
||||
out.push( a[i][ prop ][ prop2 ] );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( ; i<ien ; i++ ) {
|
||||
out.push( a[i][ prop ] );
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
// Basically the same as _pluck, but rather than looping over `a` we use `order`
|
||||
// as the indexes to pick from `a`
|
||||
var _pluck_order = function ( a, order, prop, prop2 )
|
||||
{
|
||||
var out = [];
|
||||
var i=0, ien=order.length;
|
||||
|
||||
// Could have the test in the loop for slightly smaller code, but speed
|
||||
// is essential here
|
||||
if ( prop2 !== undefined ) {
|
||||
for ( ; i<ien ; i++ ) {
|
||||
out.push( a[ order[i] ][ prop ][ prop2 ] );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( ; i<ien ; i++ ) {
|
||||
out.push( a[ order[i] ][ prop ] );
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
|
||||
var _intVal = function ( s ) {
|
||||
var integer = parseInt( s, 10 );
|
||||
return !isNaN(integer) && isFinite(s) ? integer : null;
|
||||
@ -21,7 +55,7 @@ var _selector_run = function ( selector, select )
|
||||
var
|
||||
out = [], res,
|
||||
a, i, ien, j, jen;
|
||||
|
||||
|
||||
if ( ! $.isArray( selector ) ) {
|
||||
selector = [ selector ];
|
||||
}
|
||||
@ -43,6 +77,30 @@ var _selector_run = function ( selector, select )
|
||||
return out;
|
||||
};
|
||||
|
||||
var _selector_opts = function ( opts )
|
||||
{
|
||||
if ( ! opts ) {
|
||||
opts = {};
|
||||
}
|
||||
|
||||
return {
|
||||
filter: opts.filter || 'none',
|
||||
order: opts.order || 'current',
|
||||
page: opts.page || 'all'
|
||||
};
|
||||
};
|
||||
|
||||
var _range = function ( len )
|
||||
{
|
||||
var out = [];
|
||||
|
||||
for ( var i=0 ; i<len ; i++ ) {
|
||||
out.push( i );
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Tables
|
||||
@ -100,14 +158,10 @@ var _row_selector_indexes = function ( settings, opts )
|
||||
displayFiltered = settings.aiDisplay,
|
||||
displayMaster = settings.aiDisplayMaster;
|
||||
|
||||
if ( ! opts ) {
|
||||
opts = {};
|
||||
}
|
||||
|
||||
var
|
||||
filter = opts.filter || 'none', // none, applied, removed
|
||||
order = opts.order || 'current', // current, original
|
||||
page = opts.page || 'all'; // all, page
|
||||
filter = opts.filter, // none, applied, removed
|
||||
order = opts.order, // current, index (original - compatibility with 1.9)
|
||||
page = opts.page; // all, page
|
||||
|
||||
// Current page implies that order=current and fitler=applied, since it is
|
||||
// fairly senseless otherwise, regardless of what order and filter actually
|
||||
@ -127,7 +181,7 @@ var _row_selector_indexes = function ( settings, opts )
|
||||
return $.inArray( el, displayFiltered ) === -1 ? el : null;
|
||||
} );
|
||||
}
|
||||
else if ( order == 'original' ) {
|
||||
else if ( order == 'index' || order == 'original' ) {
|
||||
for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
|
||||
if ( filter == 'none' ) {
|
||||
a.push( i );
|
||||
@ -150,15 +204,6 @@ var _row_selector_indexes = function ( settings, opts )
|
||||
|
||||
var _row_selector = function ( settings, selector, opts )
|
||||
{
|
||||
// argument shifting
|
||||
if ( selector === undefined ) {
|
||||
selector = '';
|
||||
}
|
||||
else if ( $.isPlainObject( selector ) ) {
|
||||
opts = selector;
|
||||
selector = '';
|
||||
}
|
||||
|
||||
return _selector_run( selector, function ( sel ) {
|
||||
var selInt = _intVal( sel );
|
||||
|
||||
@ -180,7 +225,7 @@ var _row_selector = function ( settings, selector, opts )
|
||||
return [ selInt ];
|
||||
}
|
||||
|
||||
// Get nodes in the order from the `rows` array (can't use `pluck`)
|
||||
// Get nodes in the order from the `rows` array (can't use `pluck`) @todo - use pluck_order
|
||||
var nodes = [];
|
||||
for ( var i=0, ien=rows.length ; i<ien ; i++ ) {
|
||||
nodes.push( settings.aoData[ rows[i] ].nTr );
|
||||
@ -224,7 +269,7 @@ var _row_selector = function ( settings, selector, opts )
|
||||
|
||||
var _re_column_selector = /^(.*):(jq|visIdx)$/;
|
||||
|
||||
var _column_selector = function ( settings, selector )
|
||||
var _column_selector = function ( settings, selector, opts )
|
||||
{
|
||||
var
|
||||
columns = settings.aoColumns,
|
||||
@ -234,7 +279,12 @@ var _column_selector = function ( settings, selector )
|
||||
return _selector_run( selector, function ( s ) {
|
||||
var selInt = _intVal( s );
|
||||
|
||||
if ( selInt !== null ) {
|
||||
if ( s === '' ) {
|
||||
// All columns
|
||||
return _range( settings.aoColumns.length );
|
||||
}
|
||||
else if ( selInt !== null ) {
|
||||
// Integer selector
|
||||
return [ selInt ];
|
||||
}
|
||||
else {
|
||||
|
@ -57,7 +57,7 @@ _Api.register( 'ajax.json()', function () {
|
||||
* @returns {DataTables.Api} this
|
||||
*/
|
||||
_Api.register( 'ajax.reload()', function ( resetPaging ) {
|
||||
return this.tables( function (settings) {
|
||||
return this.iterator( 'table', function (settings) {
|
||||
_reload( settings, resetPaging===false );
|
||||
} );
|
||||
} );
|
||||
@ -93,7 +93,7 @@ _Api.register( 'ajax.url()', function ( url ) {
|
||||
}
|
||||
|
||||
// set
|
||||
return this.tables( function ( settings ) {
|
||||
return this.iterator( 'table', function ( settings ) {
|
||||
if ( $.isPlainObject( settings.ajax ) ) {
|
||||
settings.ajax.url = url;
|
||||
}
|
||||
@ -119,7 +119,7 @@ _Api.register( 'ajax.url()', function ( url ) {
|
||||
_Api.register( 'ajax.url().load()', function () {
|
||||
// Same as a reload, but makes sense to present it for easy access after a
|
||||
// url change
|
||||
return this.tables( _reload );
|
||||
return this.iterator( 'table', _reload );
|
||||
} );
|
||||
|
||||
|
||||
|
@ -6,21 +6,48 @@ var _api = DataTable.Api;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
_api.register( 'columns()', function ( selector ) {
|
||||
return this.tables( function ( settings ) {
|
||||
return _column_selector( settings, selector );
|
||||
_api.register( 'columns()', function ( selector, opts ) {
|
||||
// argument shifting
|
||||
if ( selector === undefined ) {
|
||||
selector = '';
|
||||
}
|
||||
else if ( $.isPlainObject( selector ) ) {
|
||||
opts = selector;
|
||||
selector = '';
|
||||
}
|
||||
|
||||
opts = _selector_opts( opts );
|
||||
|
||||
var inst = this.iterator( 'table', function ( settings ) {
|
||||
return _column_selector( settings, selector, opts );
|
||||
} );
|
||||
|
||||
// Want argument shifting here and in _row_selector?
|
||||
inst.selector.cols = selector;
|
||||
inst.selector.opts = opts;
|
||||
|
||||
return inst;
|
||||
} );
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
_api.register( 'columns().header()', function ( selector, opts ) {
|
||||
return this.iterator( 'column', function ( settings, column ) {
|
||||
return settings.aoColumns[column].nTh;
|
||||
} );
|
||||
} );
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
_api.register( 'columns().header()', function ( selector, opts ) {
|
||||
return this.iterator( function ( settings, el ) {
|
||||
return settings.aoColumns[ el ].nTh;
|
||||
_api.register( 'columns().cells()', function () {
|
||||
return this.iterator( true, 'column-rows', function ( settings, column, i, j, rows ) {
|
||||
return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
|
||||
} );
|
||||
} );
|
||||
|
||||
|
@ -240,6 +240,13 @@ DataTable.Api = _Api = function ( context, data )
|
||||
this.push.apply( this, data );
|
||||
}
|
||||
|
||||
// selector
|
||||
this.selector = {
|
||||
rows: null,
|
||||
cols: null,
|
||||
opts: null
|
||||
};
|
||||
|
||||
_Api.extend( this, this, _apiStruct );
|
||||
};
|
||||
|
||||
@ -312,19 +319,48 @@ _Api.prototype = /** @lends DataTables.Api */{
|
||||
},
|
||||
|
||||
// Internal only at the moment - relax?
|
||||
iterator: function ( fn ) {
|
||||
iterator: function ( flatten, type, fn ) {
|
||||
var
|
||||
a = [], ret,
|
||||
i, ien, j, jen, k, ken,
|
||||
i, ien, j, jen,
|
||||
context = this.context,
|
||||
items;
|
||||
rows, items,
|
||||
selector = this.selector;
|
||||
|
||||
// Argument shifting
|
||||
if ( typeof flatten === 'string' ) {
|
||||
fn = type;
|
||||
type = flatten;
|
||||
flatten = false;
|
||||
}
|
||||
|
||||
for ( i=0, ien=context.length ; i<ien ; i++ ) {
|
||||
for( j=0, jen=this.length ; j<jen ; j++ ) {
|
||||
if ( type === 'table' ) {
|
||||
ret = fn( context[i] );
|
||||
|
||||
if ( ret !== undefined ) {
|
||||
a.push( ret );
|
||||
}
|
||||
}
|
||||
else if ( type === 'columns' || type === 'rows' ) {
|
||||
// this has same length as context - one entry for each table
|
||||
ret = fn( context[i], this[i] );
|
||||
|
||||
if ( ret !== undefined ) {
|
||||
a.push( ret );
|
||||
}
|
||||
}
|
||||
else if ( type === 'column' || type === 'column-rows' || type === 'row' ) {
|
||||
// columns and rows share the same structure.
|
||||
// 'this' is an array of column indexes for each context
|
||||
items = this[i];
|
||||
|
||||
for ( k=0, ken=items.length ; k<ken ; k++ ) {
|
||||
ret = fn( context[i], items[k], i, j, k );
|
||||
if ( type === 'column-rows' ) {
|
||||
rows = _row_selector_indexes( context[i], selector.opts );
|
||||
}
|
||||
|
||||
for ( j=0, jen=items.length ; j<jen ; j++ ) {
|
||||
ret = fn( context[i], items[j], i, j, rows );
|
||||
|
||||
if ( ret !== undefined ) {
|
||||
a.push( ret );
|
||||
@ -333,9 +369,15 @@ _Api.prototype = /** @lends DataTables.Api */{
|
||||
}
|
||||
}
|
||||
|
||||
return a.length ?
|
||||
new _Api( context, a ) :
|
||||
this;
|
||||
if ( a.length ) {
|
||||
var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
|
||||
var apiSelector = api.selector;
|
||||
apiSelector.rows = selector.rows;
|
||||
apiSelector.cols = selector.cols;
|
||||
apiSelector.opts = selector.opts;
|
||||
return api;
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
@ -436,6 +478,10 @@ _Api.prototype = /** @lends DataTables.Api */{
|
||||
reverse: _arrayProto.reverse,
|
||||
|
||||
|
||||
// Object with rows, columns and opts
|
||||
selector: null,
|
||||
|
||||
|
||||
shift: _arrayProto.shift,
|
||||
|
||||
|
||||
|
@ -14,7 +14,7 @@ var _api = DataTable.Api;
|
||||
* @returns {DataTables.Api} this
|
||||
*/
|
||||
_api.register( 'draw()', function ( resetPaging ) {
|
||||
return this.tables( function ( settings ) {
|
||||
return this.iterator( 'table', function ( settings ) {
|
||||
_fnReDraw( settings, resetPaging===false );
|
||||
} );
|
||||
} );
|
||||
|
@ -54,8 +54,8 @@ _Api.register( 'order()', function ( order, dir ) {
|
||||
}
|
||||
// otherwise a 2D array was passed in
|
||||
|
||||
return this.tables( function ( settings ) {
|
||||
settings.aaSorting = order;
|
||||
return this.iterator( 'table', function ( settings ) {
|
||||
settings.aaSorting = order.slice();
|
||||
} );
|
||||
} );
|
||||
|
||||
@ -71,7 +71,7 @@ _Api.register( 'order()', function ( order, dir ) {
|
||||
* @returns {DataTables.Api} this
|
||||
*/
|
||||
_Api.register( 'order.listener()', function ( node, column, callback ) {
|
||||
return this.tables( function ( settings ) {
|
||||
return this.iterator( 'table', function ( settings ) {
|
||||
_fnSortAttachListener( settings, node, column, callback );
|
||||
} );
|
||||
} );
|
||||
|
@ -30,7 +30,7 @@ _Api.register( 'page()', function ( action ) {
|
||||
}
|
||||
|
||||
// else, have an action to take on all tables
|
||||
return this.tables( function ( settings ) {
|
||||
return this.iterator( 'table', function ( settings ) {
|
||||
_fnPageChange( settings, action );
|
||||
} );
|
||||
} );
|
||||
@ -100,7 +100,7 @@ _Api.register( 'page.len()', function ( len ) {
|
||||
}
|
||||
|
||||
// else, set the page length
|
||||
return this.tables( function ( settings ) {
|
||||
return this.iterator( 'table', function ( settings ) {
|
||||
_fnLengthChange( settings, len );
|
||||
} );
|
||||
} );
|
||||
|
@ -9,25 +9,50 @@ var _api = DataTable.Api;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
_api.register( 'rows()', function ( selector, opts ) {
|
||||
return this.tables( function ( settings ) {
|
||||
// argument shifting
|
||||
if ( selector === undefined ) {
|
||||
selector = '';
|
||||
}
|
||||
else if ( $.isPlainObject( selector ) ) {
|
||||
opts = selector;
|
||||
selector = '';
|
||||
}
|
||||
|
||||
opts = _selector_opts( opts );
|
||||
|
||||
var inst = this.iterator( 'table', function ( settings ) {
|
||||
return _row_selector( settings, selector, opts );
|
||||
} );
|
||||
|
||||
// Want argument shifting here and in _row_selector?
|
||||
inst.selector.rows = selector;
|
||||
inst.selector.opts = opts;
|
||||
|
||||
return inst;
|
||||
} );
|
||||
|
||||
|
||||
_api.register( 'rows().nodes()', function () {
|
||||
return this.iterator( function ( settings, el ) {
|
||||
return settings.aoData[ el ].nTr || undefined;
|
||||
return this.iterator( 'row', function ( settings, row ) {
|
||||
// use pluck order on an array rather - rows gives an array, row gives it individually
|
||||
return settings.aoData[ row ].nTr || undefined;
|
||||
} );
|
||||
} );
|
||||
|
||||
|
||||
_api.register( 'rows().cells()', function () {
|
||||
return this.iterator( true, 'row', function ( settings, row ) {
|
||||
return settings.aoData[ row ].anCells || undefined;
|
||||
} );
|
||||
} );
|
||||
|
||||
|
||||
_api.register( 'rows().data()', function ( data ) {
|
||||
return this.iterator( function ( settings, el ) {
|
||||
return settings.aoData[ el ]._aData;
|
||||
return this.iterator( true, 'rows', function ( settings, rows ) {
|
||||
return _pluck_order( settings.aoData, rows, '_aData' );
|
||||
} );
|
||||
} );
|
||||
|
||||
|
@ -6,52 +6,21 @@ var _Api = DataTable.Api;
|
||||
|
||||
|
||||
/**
|
||||
* Context selector and iterator for the API's context (i.e. the tables the
|
||||
* API instance refers to.
|
||||
* Context selector for the API's context (i.e. the tables the API instance
|
||||
* refers to.
|
||||
*
|
||||
* @name DataTable.Api#tables
|
||||
* @param {string|integer} [selector] Selector to pick which tables the iterator
|
||||
* should operate on. If not given, all tables in the current context are
|
||||
* used. This can be given as a jQuery selector (for example `':gt(0)'`) to
|
||||
* select multiple tables or as an integer to select a single table.
|
||||
* @param {function} [fn] Iterator function. Will be called for every table in
|
||||
* the current context (once the selector has been applied, if one is given).
|
||||
* The function is passed two parameters: 1. the DataTables settings object
|
||||
* for the table in question and 2. the index of that table in the current
|
||||
* context. The execution scope of the function is the API instance.
|
||||
* @returns {DataTable.Api} Returns a new API instance if a selector is given,
|
||||
* or the callback function returns information from each loop. The
|
||||
* information, if returned, is assigned to the API instance. Otherwise the
|
||||
* original API instance is returned for chaining.
|
||||
* @returns {DataTable.Api} Returns a new API instance if a selector is given.
|
||||
*/
|
||||
_Api.register( 'tables()', function ( selector, fn ) {
|
||||
// Argument shifting
|
||||
if ( typeof selector === 'function' ) {
|
||||
fn = selector;
|
||||
selector = undefined;
|
||||
}
|
||||
|
||||
var a = [];
|
||||
var context = selector ?
|
||||
_table_selector( selector, this.context ) :
|
||||
this.context;
|
||||
|
||||
if ( fn ) {
|
||||
for ( var i=0, ien=context.length ; i<ien ; i++ ) {
|
||||
var ret = fn.call( this, context[i], i );
|
||||
if ( ret !== undefined ) {
|
||||
a.push( ret );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A new instance is created if there was a selector specified, or if
|
||||
// data was returned from the callback
|
||||
var api = selector || a.length ?
|
||||
new _Api( context, a ) :
|
||||
_Api.register( 'tables()', function ( selector ) {
|
||||
// A new instance is created if there was a selector specified
|
||||
return selector ?
|
||||
new _Api( _table_selector( selector, this.context ) ) :
|
||||
this;
|
||||
|
||||
return api;
|
||||
} );
|
||||
|
||||
|
||||
@ -61,7 +30,7 @@ _Api.register( 'tables()', function ( selector, fn ) {
|
||||
* tables.
|
||||
*/
|
||||
_Api.register( 'tables().nodes()', function () {
|
||||
return this.tables( function ( settings, i ) {
|
||||
return this.iterator( 'table', function ( settings, i ) {
|
||||
return settings.nTable;
|
||||
} );
|
||||
} );
|
||||
|
@ -578,6 +578,7 @@ function _fnAddOptionsHtml ( oSettings )
|
||||
/* End container div */
|
||||
nInsertNode = nInsertNode.parentNode;
|
||||
}
|
||||
// @todo Move options into their own plugins?
|
||||
else if ( cOption == 'l' && oSettings.oFeatures.bPaginate && oSettings.oFeatures.bLengthChange )
|
||||
{
|
||||
/* Length */
|
||||
|
Loading…
Reference in New Issue
Block a user