mirror of
https://github.com/DataTables/DataTables.git
synced 2024-12-01 13:24:10 +01:00
New: data
and render
options for columns support function notation
- As part of completing the planning development for reading data, I've added support for calling functions from the string defined in `data` and `render` column options. So you can now do something like: `render: 'name()'` rather than needing to use an anon function and calling name() in that. This is useful for cases where you want to give DataTables an array of Javascript instances, rather than objects or arrays (see example below). It also fully supports the continuation of the dotted notation DataTables supports, so you could use `name().first` if `name()` returns an object. Again to make it easier than needed to define a function. - Documentation for `data` and `render` updated to reflect this abilities - Unit tests for this still to come - There is one backwards incompatiblity that should be noted - although I think this is a real edge case and I just can't see it being an issue. If before, you had `data:null` without `render` or `defaultContent` specified, DataTables would have output an empty cell. Now it will output the original data source object. Can't see this being an issue since, why would you have a column empty cells? If this is an issue, then you simply need to add `defaultContent:''` now. - Example use case, using Javascript instances: $(document).ready(function() { var z = function (i) { this.a = function (set) { if ( set ) { return this; } return i+'-0'; }; this.b = function (set) { if ( set ) { return this; } return i+'-1'; }; this.c = function (set) { if ( set ) { return this; } return i+'-2'; }; this.d = function (set) { if ( set ) { return this; } return i+'-3'; }; this.e = function (set) { if ( set ) { return this; } return { q: i+'-4q', w: i+'-4w' }; }; }; window.dataset = [ new z(0), new z(1), new z(2), new z(3), new z(4), new z(5) ]; $('#example').dataTable( { columns: [ { data: null, /*render: 'a()'*/ }, { data: 'b()' }, { data: 'c' }, { data: 'd()' }, { data: 'e().q' } ], data: dataset } ); } );
This commit is contained in:
parent
8dcd96f300
commit
b2de50229e
@ -187,17 +187,17 @@ function _fnGetCellData( oSettings, iRow, iCol, sSpecific )
|
||||
}
|
||||
|
||||
/* When the data source is null, we can use default column data */
|
||||
if ( sData === null && oCol.sDefaultContent !== null )
|
||||
if ( (sData === oData || sData === null) && oCol.sDefaultContent !== null )
|
||||
{
|
||||
sData = oCol.sDefaultContent;
|
||||
}
|
||||
else if ( typeof sData === 'function' )
|
||||
{
|
||||
/* If the data source is a function, then we run it and use the return */
|
||||
// If the data source is a function, then we run it and use the return
|
||||
return sData();
|
||||
}
|
||||
|
||||
if ( sSpecific == 'display' && sData === null )
|
||||
if ( sData === null && sSpecific == 'display' )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
@ -222,8 +222,9 @@ function _fnSetCellData( oSettings, iRow, iCol, val )
|
||||
}
|
||||
|
||||
|
||||
// Private variable that is used to match array syntax in the data property object
|
||||
// Private variable that is used to match action syntax in the data property object
|
||||
var __reArray = /\[.*?\]$/;
|
||||
var __reFn = /\(\)$/;
|
||||
|
||||
/**
|
||||
* Return a function that can be used to get data from a source object, taking
|
||||
@ -238,7 +239,7 @@ function _fnGetObjectDataFn( mSource )
|
||||
{
|
||||
/* Give an empty string for rendering / sorting etc */
|
||||
return function (data, type) {
|
||||
return null;
|
||||
return data;
|
||||
};
|
||||
}
|
||||
else if ( typeof mSource === 'function' )
|
||||
@ -247,9 +248,10 @@ function _fnGetObjectDataFn( mSource )
|
||||
return mSource( data, type, extra );
|
||||
};
|
||||
}
|
||||
else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 || mSource.indexOf('[') !== -1) )
|
||||
else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
|
||||
mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
|
||||
{
|
||||
/* If there is a . in the source string then the data source is in a
|
||||
/* If there is a . in the source string then the data source is in a
|
||||
* nested object so we loop over the data for each level to get the next
|
||||
* level down. On each loop we test for undefined, and if found immediately
|
||||
* return. This allows entire objects to be missing and sDefaultContent to
|
||||
@ -257,16 +259,19 @@ function _fnGetObjectDataFn( mSource )
|
||||
*/
|
||||
var fetchData = function (data, type, src) {
|
||||
var a = src.split('.');
|
||||
var arrayNotation, out, innerSrc;
|
||||
var arrayNotation, funcNotation, out, innerSrc;
|
||||
|
||||
if ( src !== "" )
|
||||
{
|
||||
for ( var i=0, iLen=a.length ; i<iLen ; i++ )
|
||||
{
|
||||
// Check if we are dealing with an array notation request
|
||||
// Check if we are dealing with special notation
|
||||
arrayNotation = a[i].match(__reArray);
|
||||
funcNotation = a[i].match(__reFn);
|
||||
|
||||
if ( arrayNotation ) {
|
||||
if ( arrayNotation )
|
||||
{
|
||||
// Array notation
|
||||
a[i] = a[i].replace(__reArray, '');
|
||||
|
||||
// Condition allows simply [] to be passed in
|
||||
@ -293,6 +298,13 @@ function _fnGetObjectDataFn( mSource )
|
||||
// of the source requested, so we exit from the loop
|
||||
break;
|
||||
}
|
||||
else if ( funcNotation )
|
||||
{
|
||||
// Function call
|
||||
a[i] = a[i].replace(__reFn, '');
|
||||
data = data[ a[i] ]();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( data === null || data[ a[i] ] === undefined )
|
||||
{
|
||||
@ -313,7 +325,7 @@ function _fnGetObjectDataFn( mSource )
|
||||
{
|
||||
/* Array or flat object mapping */
|
||||
return function (data, type) {
|
||||
return data[mSource];
|
||||
return data[mSource];
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -339,17 +351,20 @@ function _fnSetObjectDataFn( mSource )
|
||||
mSource( data, 'set', val );
|
||||
};
|
||||
}
|
||||
else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 || mSource.indexOf('[') !== -1) )
|
||||
else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
|
||||
mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
|
||||
{
|
||||
/* Like the get, we need to get data from a nested object */
|
||||
var setData = function (data, val, src) {
|
||||
var a = src.split('.'), b;
|
||||
var arrayNotation, o, innerSrc;
|
||||
var aLast = a[a.length-1];
|
||||
var arrayNotation, funcNotation, o, innerSrc;
|
||||
|
||||
for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
|
||||
{
|
||||
// Check if we are dealing with an array notation request
|
||||
arrayNotation = a[i].match(__reArray);
|
||||
funcNotation = a[i].match(__reFn);
|
||||
|
||||
if ( arrayNotation )
|
||||
{
|
||||
@ -373,6 +388,12 @@ function _fnSetObjectDataFn( mSource )
|
||||
// of the source and has set the data, thus we can exit here
|
||||
return;
|
||||
}
|
||||
else if ( funcNotation )
|
||||
{
|
||||
// Function call
|
||||
a[i] = a[i].replace(__reFn, '');
|
||||
data = data[ a[i] ]( val );
|
||||
}
|
||||
|
||||
// If the nested object doesn't currently exist - since we are
|
||||
// trying to set the value - create it
|
||||
@ -383,9 +404,18 @@ function _fnSetObjectDataFn( mSource )
|
||||
data = data[ a[i] ];
|
||||
}
|
||||
|
||||
// If array notation is used, we just want to strip it and use the property name
|
||||
// and assign the value. If it isn't used, then we get the result we want anyway
|
||||
data[ a[a.length-1].replace(__reArray, '') ] = val;
|
||||
// Last item in the input - i.e, the actual set
|
||||
if ( aLast.match(__reFn ) )
|
||||
{
|
||||
// Function call
|
||||
data = data[ aLast.replace(__reFn, '') ]( val );
|
||||
}
|
||||
else
|
||||
{
|
||||
// If array notation is used, we just want to strip it and use the property name
|
||||
// and assign the value. If it isn't used, then we get the result we want anyway
|
||||
data[ aLast.replace(__reArray, '') ] = val;
|
||||
}
|
||||
};
|
||||
|
||||
return function (data, val) {
|
||||
@ -396,7 +426,7 @@ function _fnSetObjectDataFn( mSource )
|
||||
{
|
||||
/* Array or flat object mapping */
|
||||
return function (data, val) {
|
||||
data[mSource] = val;
|
||||
data[mSource] = val;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -258,53 +258,116 @@ DataTable.defaults.column = {
|
||||
|
||||
/**
|
||||
* This parameter has been replaced by `data` in DataTables to ensure naming
|
||||
* consistency. `dataProp` can still be used, as there is backwards compatibility
|
||||
* in DataTables for this option, but it is strongly recommended that you use
|
||||
* `data` in preference to `dataProp`.
|
||||
* consistency. `dataProp` can still be used, as there is backwards
|
||||
* compatibility in DataTables for this option, but it is strongly
|
||||
* recommended that you use `data` in preference to `dataProp`.
|
||||
* @name DataTable.defaults.column.dataProp
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* This property can be used to read data from any JSON data source property,
|
||||
* This property can be used to read data from any data source property,
|
||||
* including deeply nested objects / properties. `data` can be given in a
|
||||
* number of different ways which effect its behaviour:
|
||||
*
|
||||
* * integer - treated as an array index for the data source. This is the
|
||||
* * `integer` - treated as an array index for the data source. This is the
|
||||
* default that DataTables uses (incrementally increased for each column).
|
||||
* * string - read an object property from the data source. Note that you can
|
||||
* use Javascript dotted notation to read deep properties / arrays from the
|
||||
* data source.
|
||||
* * null - the sDefaultContent option will be used for the cell (null
|
||||
* by default, so you will need to specify the default content you want -
|
||||
* typically an empty string). This can be useful on generated columns such
|
||||
* as edit / delete action columns.
|
||||
* * function - the function given will be executed whenever DataTables
|
||||
* needs to set or get the data for a cell in the column. The function
|
||||
* * `string` - read an object property from the data source. There are
|
||||
* three 'special' options that can be used in the string to alter how
|
||||
* DataTables reads the data from the source object:
|
||||
* * `.` - Dotted Javascript notation. Just as you use a `.` in
|
||||
* Javascript to read from nested objects, so to can the options
|
||||
* specified in `data`. For example: `browser.version` or
|
||||
* `browser.name`.
|
||||
* * `[]` - Array notation. DataTables can automatically combine data
|
||||
* from and array source, joining the data with the characters provided
|
||||
* between the two brackets. For example: `name[, ]` would provide a
|
||||
* comma-space separated list from the source array. If no characters
|
||||
* are provided between the brackets, the original array source is
|
||||
* returned.
|
||||
* * `()` - Function notation. Adding `()` to the end of a parameter will
|
||||
* execute a function of the name given. For example: `browser()` for a
|
||||
* simple function on the data source, `browser.version()` for a
|
||||
* function in a nested property or even `browser().version` to get an
|
||||
* object property if the function called returns an object. Note that
|
||||
* function notation is recommended for use in `render` rather than
|
||||
* `data` as it is much simpler to use as a renderer.
|
||||
* * `null` - use the original data source for the row rather than plucking
|
||||
* data directly from it. This action has effects on two other
|
||||
* initialisation options:
|
||||
* * `defaultContent` - When null is given as the `data` option and
|
||||
* `defaultContent` is specified for the column, the value defined by
|
||||
* `defaultContent` will be used for the cell.
|
||||
* * `render` - When null is used for the `data` option and the `render`
|
||||
* option is specified for the column, the whole data source for the
|
||||
* row is used for the renderer.
|
||||
* * `function` - the function given will be executed whenever DataTables
|
||||
* needs to set or get the data for a cell in the column. The function
|
||||
* takes three parameters:
|
||||
* * {array|object} The data source for the row
|
||||
* * {string} The type call data requested - this will be 'set' when
|
||||
* setting data or 'filter', 'display', 'type', 'sort' or undefined when
|
||||
* gathering data. Note that when `undefined` is given for the type
|
||||
* DataTables expects to get the raw data for the object back<
|
||||
* * {*} Data to set when the second parameter is 'set'.
|
||||
* * The return value from the function is not required when 'set' is the type
|
||||
* of call, but otherwise the return is what will be used for the data
|
||||
* requested.
|
||||
* * Parameters:
|
||||
* * `{array|object}` The data source for the row
|
||||
* * `{string}` The type call data requested - this will be 'set' when
|
||||
* setting data or 'filter', 'display', 'type', 'sort' or undefined
|
||||
* when gathering data. Note that when `undefined` is given for the
|
||||
* type DataTables expects to get the raw data for the object back<
|
||||
* * `{*}` Data to set when the second parameter is 'set'.
|
||||
* * Return:
|
||||
* * The return value from the function is not required when 'set' is
|
||||
* the type of call, but otherwise the return is what will be used
|
||||
* for the data requested.
|
||||
*
|
||||
* Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The name change
|
||||
* reflects the flexibility of this property and is consistent with the naming of
|
||||
* mRender. If 'mDataProp' is given, then it will still be used by DataTables, as
|
||||
* it automatically maps the old name to the new if required.
|
||||
* Note that `data` is a getter and setter option. If you just require
|
||||
* formatting of data for output, you will likely want to use `render` which
|
||||
* is simply a getter and thus simpler to use.
|
||||
*
|
||||
* Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
|
||||
* name change reflects the flexibility of this property and is consistent
|
||||
* with the naming of mRender. If 'mDataProp' is given, then it will still
|
||||
* be used by DataTables, as it automatically maps the old name to the new
|
||||
* if required.
|
||||
*
|
||||
* @type string|int|function|null
|
||||
* @default null <i>Use automatically calculated column index</i>
|
||||
*
|
||||
* @name DataTable.defaults.column.data
|
||||
* @dtopt Columns
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* // Read table data from objects
|
||||
* // JSON structure for each row:
|
||||
* // {
|
||||
* // "engine": {value},
|
||||
* // "browser": {value},
|
||||
* // "platform": {value},
|
||||
* // "version": {value},
|
||||
* // "grade": {value}
|
||||
* // }
|
||||
* $(document).ready( function() {
|
||||
* $('#example').dataTable( {
|
||||
* "ajaxSource": "sources/objects.txt",
|
||||
* "columns": [
|
||||
* { "data": "engine" },
|
||||
* { "data": "browser" },
|
||||
* { "data": "platform" },
|
||||
* { "data": "version" },
|
||||
* { "data": "grade" }
|
||||
* ]
|
||||
* } );
|
||||
* } );
|
||||
*
|
||||
* @example
|
||||
* // Read information from deeply nested objects
|
||||
* // JSON structure for each row:
|
||||
* // {
|
||||
* // "engine": {value},
|
||||
* // "browser": {value},
|
||||
* // "platform": {
|
||||
* // "inner": {value}
|
||||
* // },
|
||||
* // "details": [
|
||||
* // {value}, {value}
|
||||
* // ]
|
||||
* // }
|
||||
* $(document).ready( function() {
|
||||
* $('#example').dataTable( {
|
||||
* "ajaxSource": "sources/deep.txt",
|
||||
@ -317,7 +380,7 @@ DataTable.defaults.column = {
|
||||
* ]
|
||||
* } );
|
||||
* } );
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* // Using `data` as a function to provide different information for
|
||||
* // sorting, filtering and display. In this case, currency (price)
|
||||
@ -345,38 +408,75 @@ DataTable.defaults.column = {
|
||||
* } ]
|
||||
* } );
|
||||
* } );
|
||||
*
|
||||
* @example
|
||||
* // Using default content
|
||||
* $(document).ready( function() {
|
||||
* $('#example').dataTable( {
|
||||
* "columnDefs": [ {
|
||||
* "targets": [ 0 ],
|
||||
* "data": null,
|
||||
* "defaultContent": "Click to edit"
|
||||
* } ]
|
||||
* } );
|
||||
* } );
|
||||
*
|
||||
* @example
|
||||
* // Using array notation - outputting a list from an array
|
||||
* $(document).ready( function() {
|
||||
* $('#example').dataTable( {
|
||||
* "columnDefs": [ {
|
||||
* "targets": [ 0 ],
|
||||
* "data": "name[, ]"
|
||||
* } ]
|
||||
* } );
|
||||
* } );
|
||||
*
|
||||
*/
|
||||
"mData": null,
|
||||
|
||||
|
||||
/**
|
||||
* This property is the rendering partner to `data` and it is suggested that
|
||||
* when you want to manipulate data for display (including filtering, sorting etc)
|
||||
* but not altering the underlying data for the table, use this property. `data`
|
||||
* can actually do everything this property can and more, but this parameter is
|
||||
* easier to use since there is no 'set' option. Like `data` this can be given
|
||||
* in a number of different ways to effect its behaviour, with the addition of
|
||||
* supporting array syntax for easy outputting of arrays (including arrays of
|
||||
* objects):
|
||||
* when you want to manipulate data for display (including filtering,
|
||||
* sorting etc) but not altering the underlying data for the table, use this
|
||||
* property. `data` can actually do everything this property can and more,
|
||||
* but this parameter is much easier to use as there is no 'set' option.
|
||||
* Like `data` this option can be given in a number of different ways to
|
||||
* effect its behaviour:
|
||||
*
|
||||
* * integer - treated as an array index for the data source. This is the
|
||||
* * `integer` - treated as an array index for the data source. This is the
|
||||
* default that DataTables uses (incrementally increased for each column).
|
||||
* * string - read an object property from the data source. Note that you can
|
||||
* use Javascript dotted notation to read deep properties / arrays from the
|
||||
* data source and also array brackets to indicate that the data reader should
|
||||
* loop over the data source array. When characters are given between the array
|
||||
* brackets, these characters are used to join the data source array together.
|
||||
* For example: "accounts[, ].name" would result in a comma separated list with
|
||||
* the 'name' value from the 'accounts' array of objects.
|
||||
* * function - the function given will be executed whenever DataTables
|
||||
* needs to set or get the data for a cell in the column. The function
|
||||
* * `string` - read an object property from the data source. There are
|
||||
* three 'special' options that can be used in the string to alter how
|
||||
* DataTables reads the data from the source object:
|
||||
* * `.` - Dotted Javascript notation. Just as you use a `.` in
|
||||
* Javascript to read from nested objects, so to can the options
|
||||
* specified in `data`. For example: `browser.version` or
|
||||
* `browser.name`.
|
||||
* * `[]` - Array notation. DataTables can automatically combine data
|
||||
* from and array source, joining the data with the characters provided
|
||||
* between the two brackets. For example: `name[, ]` would provide a
|
||||
* comma-space separated list from the source array. If no characters
|
||||
* are provided between the brackets, the original array source is
|
||||
* returned.
|
||||
* * `()` - Function notation. Adding `()` to the end of a parameter will
|
||||
* execute a function of the name given. For example: `browser()` for a
|
||||
* simple function on the data source, `browser.version()` for a
|
||||
* function in a nested property or even `browser().version` to get an
|
||||
* object property if the function called returns an object.
|
||||
* * `function` - the function given will be executed whenever DataTables
|
||||
* needs to set or get the data for a cell in the column. The function
|
||||
* takes three parameters:
|
||||
* * {array|object} The data source for the row (based on `data`)
|
||||
* * {string} The type call data requested - this will be 'filter', 'display',
|
||||
* 'type' or 'sort'.
|
||||
* * {array|object} The full data source for the row (not based on `data`)
|
||||
* * The return value from the function is what will be used for the data
|
||||
* requested.
|
||||
* * Parameters:
|
||||
* * {array|object} The data source for the row (based on `data`)
|
||||
* * {string} The type call data requested - this will be 'filter',
|
||||
* 'display', 'type' or 'sort'.
|
||||
* * {array|object} The full data source for the row (not based on
|
||||
* `data`)
|
||||
* * Return:
|
||||
* * The return value from the function is what will be used for the
|
||||
* data requested.
|
||||
*
|
||||
* @type string|int|function|null
|
||||
* @default null _Use `data`_
|
||||
@ -401,6 +501,18 @@ DataTable.defaults.column = {
|
||||
* } );
|
||||
*
|
||||
* @example
|
||||
* // Execute a function to obtain data
|
||||
* $(document).ready( function() {
|
||||
* $('#example').dataTable( {
|
||||
* "columnDefs": [ {
|
||||
* "targets": [ 0 ],
|
||||
* "data": null, // Use the full data source object for the renderer's source
|
||||
* "render": "browserName()"
|
||||
* } ]
|
||||
* } );
|
||||
* } );
|
||||
*
|
||||
* @example
|
||||
* // Use as a function to create a link from the data source
|
||||
* $(document).ready( function() {
|
||||
* $('#example').dataTable( {
|
||||
|
Loading…
Reference in New Issue
Block a user