Advertisement
Guest User

Untitled

a guest
Sep 30th, 2018
341
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 437.47 KB | None | 0 0
  1. /*! DataTables 1.10.4
  2. * ©2008-2014 SpryMedia Ltd - datatables.net/license
  3. */
  4.  
  5. /**
  6. * @summary DataTables
  7. * @description Paginate, search and order HTML tables
  8. * @version 1.10.4
  9. * @file jquery.dataTables.js
  10. * @author SpryMedia Ltd (www.sprymedia.co.uk)
  11. * @contact www.sprymedia.co.uk/contact
  12. * @copyright Copyright 2008-2014 SpryMedia Ltd.
  13. *
  14. * This source file is free software, available under the following license:
  15. * MIT license - http://datatables.net/license
  16. *
  17. * This source file is distributed in the hope that it will be useful, but
  18. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  19. * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
  20. *
  21. * For details please refer to: http://www.datatables.net
  22. */
  23.  
  24. /*jslint evil: true, undef: true, browser: true */
  25. /*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnScrollBarWidth,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/
  26.  
  27. (/** @lends <global> */function( window, document, undefined ) {
  28.  
  29. (function( factory ) {
  30. "use strict";
  31.  
  32. if ( typeof define === 'function' && define.amd ) {
  33. // Define as an AMD module if possible
  34. define( 'datatables', ['jquery'], factory );
  35. }
  36. else if ( typeof exports === 'object' ) {
  37. // Node/CommonJS
  38. factory( require( 'jquery' ) );
  39. }
  40. else if ( jQuery && !jQuery.fn.dataTable ) {
  41. // Define using browser globals otherwise
  42. // Prevent multiple instantiations if the script is loaded twice
  43. factory( jQuery );
  44. }
  45. }
  46. (/** @lends <global> */function( $ ) {
  47. "use strict";
  48.  
  49. /**
  50. * DataTables is a plug-in for the jQuery Javascript library. It is a highly
  51. * flexible tool, based upon the foundations of progressive enhancement,
  52. * which will add advanced interaction controls to any HTML table. For a
  53. * full list of features please refer to
  54. * [DataTables.net](href="http://datatables.net).
  55. *
  56. * Note that the `DataTable` object is not a global variable but is aliased
  57. * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
  58. * be accessed.
  59. *
  60. * @class
  61. * @param {object} [init={}] Configuration object for DataTables. Options
  62. * are defined by {@link DataTable.defaults}
  63. * @requires jQuery 1.7+
  64. *
  65. * @example
  66. * // Basic initialisation
  67. * $(document).ready( function {
  68. * $('#example').dataTable();
  69. * } );
  70. *
  71. * @example
  72. * // Initialisation with configuration options - in this case, disable
  73. * // pagination and sorting.
  74. * $(document).ready( function {
  75. * $('#example').dataTable( {
  76. * "paginate": false,
  77. * "sort": false
  78. * } );
  79. * } );
  80. */
  81. var DataTable;
  82.  
  83.  
  84. /*
  85. * It is useful to have variables which are scoped locally so only the
  86. * DataTables functions can access them and they don't leak into global space.
  87. * At the same time these functions are often useful over multiple files in the
  88. * core and API, so we list, or at least document, all variables which are used
  89. * by DataTables as private variables here. This also ensures that there is no
  90. * clashing of variable names and that they can easily referenced for reuse.
  91. */
  92.  
  93.  
  94. // Defined else where
  95. // _selector_run
  96. // _selector_opts
  97. // _selector_first
  98. // _selector_row_indexes
  99.  
  100. var _ext; // DataTable.ext
  101. var _Api; // DataTable.Api
  102. var _api_register; // DataTable.Api.register
  103. var _api_registerPlural; // DataTable.Api.registerPlural
  104.  
  105. var _re_dic = {};
  106. var _re_new_lines = /[\r\n]/g;
  107. var _re_html = /<.*?>/g;
  108. var _re_date_start = /^[\w\+\-]/;
  109. var _re_date_end = /[\w\+\-]$/;
  110.  
  111. // Escape regular expression special characters
  112. var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' );
  113.  
  114. // U+2009 is thin space and U+202F is narrow no-break space, both used in many
  115. // standards as thousands separators
  116. var _re_formatted_numeric = /[',$£€¥%\u2009\u202F]/g;
  117.  
  118.  
  119. var _empty = function ( d ) {
  120. return !d || d === true || d === '-' ? true : false;
  121. };
  122.  
  123.  
  124. var _intVal = function ( s ) {
  125. var integer = parseInt( s, 10 );
  126. return !isNaN(integer) && isFinite(s) ? integer : null;
  127. };
  128.  
  129. // Convert from a formatted number with characters other than `.` as the
  130. // decimal place, to a Javascript number
  131. var _numToDecimal = function ( num, decimalPoint ) {
  132. // Cache created regular expressions for speed as this function is called often
  133. if ( ! _re_dic[ decimalPoint ] ) {
  134. _re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );
  135. }
  136. return typeof num === 'string' && decimalPoint !== '.' ?
  137. num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :
  138. num;
  139. };
  140.  
  141.  
  142. var _isNumber = function ( d, decimalPoint, formatted ) {
  143. var strType = typeof d === 'string';
  144.  
  145. if ( decimalPoint && strType ) {
  146. d = _numToDecimal( d, decimalPoint );
  147. }
  148.  
  149. if ( formatted && strType ) {
  150. d = d.replace( _re_formatted_numeric, '' );
  151. }
  152.  
  153. return _empty( d ) || (!isNaN( parseFloat(d) ) && isFinite( d ));
  154. };
  155.  
  156.  
  157. // A string without HTML in it can be considered to be HTML still
  158. var _isHtml = function ( d ) {
  159. return _empty( d ) || typeof d === 'string';
  160. };
  161.  
  162.  
  163. var _htmlNumeric = function ( d, decimalPoint, formatted ) {
  164. if ( _empty( d ) ) {
  165. return true;
  166. }
  167.  
  168. var html = _isHtml( d );
  169. return ! html ?
  170. null :
  171. _isNumber( _stripHtml( d ), decimalPoint, formatted ) ?
  172. true :
  173. null;
  174. };
  175.  
  176.  
  177. var _pluck = function ( a, prop, prop2 ) {
  178. var out = [];
  179. var i=0, ien=a.length;
  180.  
  181. // Could have the test in the loop for slightly smaller code, but speed
  182. // is essential here
  183. if ( prop2 !== undefined ) {
  184. for ( ; i<ien ; i++ ) {
  185. if ( a[i] && a[i][ prop ] ) {
  186. out.push( a[i][ prop ][ prop2 ] );
  187. }
  188. }
  189. }
  190. else {
  191. for ( ; i<ien ; i++ ) {
  192. if ( a[i] ) {
  193. out.push( a[i][ prop ] );
  194. }
  195. }
  196. }
  197.  
  198. return out;
  199. };
  200.  
  201.  
  202. // Basically the same as _pluck, but rather than looping over `a` we use `order`
  203. // as the indexes to pick from `a`
  204. var _pluck_order = function ( a, order, prop, prop2 )
  205. {
  206. var out = [];
  207. var i=0, ien=order.length;
  208.  
  209. // Could have the test in the loop for slightly smaller code, but speed
  210. // is essential here
  211. if ( prop2 !== undefined ) {
  212. for ( ; i<ien ; i++ ) {
  213. if ( a[ order[i] ][ prop ] ) {
  214. out.push( a[ order[i] ][ prop ][ prop2 ] );
  215. }
  216. }
  217. }
  218. else {
  219. for ( ; i<ien ; i++ ) {
  220. out.push( a[ order[i] ][ prop ] );
  221. }
  222. }
  223.  
  224. return out;
  225. };
  226.  
  227.  
  228. var _range = function ( len, start )
  229. {
  230. var out = [];
  231. var end;
  232.  
  233. if ( start === undefined ) {
  234. start = 0;
  235. end = len;
  236. }
  237. else {
  238. end = start;
  239. start = len;
  240. }
  241.  
  242. for ( var i=start ; i<end ; i++ ) {
  243. out.push( i );
  244. }
  245.  
  246. return out;
  247. };
  248.  
  249.  
  250. var _removeEmpty = function ( a )
  251. {
  252. var out = [];
  253.  
  254. for ( var i=0, ien=a.length ; i<ien ; i++ ) {
  255. if ( a[i] ) { // careful - will remove all falsy values!
  256. out.push( a[i] );
  257. }
  258. }
  259.  
  260. return out;
  261. };
  262.  
  263.  
  264. var _stripHtml = function ( d ) {
  265. return d.replace( _re_html, '' );
  266. };
  267.  
  268.  
  269. /**
  270. * Find the unique elements in a source array.
  271. *
  272. * @param {array} src Source array
  273. * @return {array} Array of unique items
  274. * @ignore
  275. */
  276. var _unique = function ( src )
  277. {
  278. // A faster unique method is to use object keys to identify used values,
  279. // but this doesn't work with arrays or objects, which we must also
  280. // consider. See jsperf.com/compare-array-unique-versions/4 for more
  281. // information.
  282. var
  283. out = [],
  284. val,
  285. i, ien=src.length,
  286. j, k=0;
  287.  
  288. again: for ( i=0 ; i<ien ; i++ ) {
  289. val = src[i];
  290.  
  291. for ( j=0 ; j<k ; j++ ) {
  292. if ( out[j] === val ) {
  293. continue again;
  294. }
  295. }
  296.  
  297. out.push( val );
  298. k++;
  299. }
  300.  
  301. return out;
  302. };
  303.  
  304.  
  305.  
  306. /**
  307. * Create a mapping object that allows camel case parameters to be looked up
  308. * for their Hungarian counterparts. The mapping is stored in a private
  309. * parameter called `_hungarianMap` which can be accessed on the source object.
  310. * @param {object} o
  311. * @memberof DataTable#oApi
  312. */
  313. function _fnHungarianMap ( o )
  314. {
  315. var
  316. hungarian = 'a aa ai ao as b fn i m o s ',
  317. match,
  318. newKey,
  319. map = {};
  320.  
  321. $.each( o, function (key, val) {
  322. match = key.match(/^([^A-Z]+?)([A-Z])/);
  323.  
  324. if ( match && hungarian.indexOf(match[1]+' ') !== -1 )
  325. {
  326. newKey = key.replace( match[0], match[2].toLowerCase() );
  327. map[ newKey ] = key;
  328.  
  329. if ( match[1] === 'o' )
  330. {
  331. _fnHungarianMap( o[key] );
  332. }
  333. }
  334. } );
  335.  
  336. o._hungarianMap = map;
  337. }
  338.  
  339.  
  340. /**
  341. * Convert from camel case parameters to Hungarian, based on a Hungarian map
  342. * created by _fnHungarianMap.
  343. * @param {object} src The model object which holds all parameters that can be
  344. * mapped.
  345. * @param {object} user The object to convert from camel case to Hungarian.
  346. * @param {boolean} force When set to `true`, properties which already have a
  347. * Hungarian value in the `user` object will be overwritten. Otherwise they
  348. * won't be.
  349. * @memberof DataTable#oApi
  350. */
  351. function _fnCamelToHungarian ( src, user, force )
  352. {
  353. if ( ! src._hungarianMap ) {
  354. _fnHungarianMap( src );
  355. }
  356.  
  357. var hungarianKey;
  358.  
  359. $.each( user, function (key, val) {
  360. hungarianKey = src._hungarianMap[ key ];
  361.  
  362. if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )
  363. {
  364. // For objects, we need to buzz down into the object to copy parameters
  365. if ( hungarianKey.charAt(0) === 'o' )
  366. {
  367. // Copy the camelCase options over to the hungarian
  368. if ( ! user[ hungarianKey ] ) {
  369. user[ hungarianKey ] = {};
  370. }
  371. $.extend( true, user[hungarianKey], user[key] );
  372.  
  373. _fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );
  374. }
  375. else {
  376. user[hungarianKey] = user[ key ];
  377. }
  378. }
  379. } );
  380. }
  381.  
  382.  
  383. /**
  384. * Language compatibility - when certain options are given, and others aren't, we
  385. * need to duplicate the values over, in order to provide backwards compatibility
  386. * with older language files.
  387. * @param {object} oSettings dataTables settings object
  388. * @memberof DataTable#oApi
  389. */
  390. function _fnLanguageCompat( lang )
  391. {
  392. var defaults = DataTable.defaults.oLanguage;
  393. var zeroRecords = lang.sZeroRecords;
  394.  
  395. /* Backwards compatibility - if there is no sEmptyTable given, then use the same as
  396. * sZeroRecords - assuming that is given.
  397. */
  398. if ( ! lang.sEmptyTable && zeroRecords &&
  399. defaults.sEmptyTable === "No data available in table" )
  400. {
  401. _fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
  402. }
  403.  
  404. /* Likewise with loading records */
  405. if ( ! lang.sLoadingRecords && zeroRecords &&
  406. defaults.sLoadingRecords === "Loading..." )
  407. {
  408. _fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
  409. }
  410.  
  411. // Old parameter name of the thousands separator mapped onto the new
  412. if ( lang.sInfoThousands ) {
  413. lang.sThousands = lang.sInfoThousands;
  414. }
  415.  
  416. var decimal = lang.sDecimal;
  417. if ( decimal ) {
  418. _addNumericSort( decimal );
  419. }
  420. }
  421.  
  422.  
  423. /**
  424. * Map one parameter onto another
  425. * @param {object} o Object to map
  426. * @param {*} knew The new parameter name
  427. * @param {*} old The old parameter name
  428. */
  429. var _fnCompatMap = function ( o, knew, old ) {
  430. if ( o[ knew ] !== undefined ) {
  431. o[ old ] = o[ knew ];
  432. }
  433. };
  434.  
  435.  
  436. /**
  437. * Provide backwards compatibility for the main DT options. Note that the new
  438. * options are mapped onto the old parameters, so this is an external interface
  439. * change only.
  440. * @param {object} init Object to map
  441. */
  442. function _fnCompatOpts ( init )
  443. {
  444. _fnCompatMap( init, 'ordering', 'bSort' );
  445. _fnCompatMap( init, 'orderMulti', 'bSortMulti' );
  446. _fnCompatMap( init, 'orderClasses', 'bSortClasses' );
  447. _fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );
  448. _fnCompatMap( init, 'order', 'aaSorting' );
  449. _fnCompatMap( init, 'orderFixed', 'aaSortingFixed' );
  450. _fnCompatMap( init, 'paging', 'bPaginate' );
  451. _fnCompatMap( init, 'pagingType', 'sPaginationType' );
  452. _fnCompatMap( init, 'pageLength', 'iDisplayLength' );
  453. _fnCompatMap( init, 'searching', 'bFilter' );
  454.  
  455. // Column search objects are in an array, so it needs to be converted
  456. // element by element
  457. var searchCols = init.aoSearchCols;
  458.  
  459. if ( searchCols ) {
  460. for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {
  461. if ( searchCols[i] ) {
  462. _fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );
  463. }
  464. }
  465. }
  466. }
  467.  
  468.  
  469. /**
  470. * Provide backwards compatibility for column options. Note that the new options
  471. * are mapped onto the old parameters, so this is an external interface change
  472. * only.
  473. * @param {object} init Object to map
  474. */
  475. function _fnCompatCols ( init )
  476. {
  477. _fnCompatMap( init, 'orderable', 'bSortable' );
  478. _fnCompatMap( init, 'orderData', 'aDataSort' );
  479. _fnCompatMap( init, 'orderSequence', 'asSorting' );
  480. _fnCompatMap( init, 'orderDataType', 'sortDataType' );
  481. }
  482.  
  483.  
  484. /**
  485. * Browser feature detection for capabilities, quirks
  486. * @param {object} settings dataTables settings object
  487. * @memberof DataTable#oApi
  488. */
  489. function _fnBrowserDetect( settings )
  490. {
  491. var browser = settings.oBrowser;
  492.  
  493. // Scrolling feature / quirks detection
  494. var n = $('<div/>')
  495. .css( {
  496. position: 'absolute',
  497. top: 0,
  498. left: 0,
  499. height: 1,
  500. width: 1,
  501. overflow: 'hidden'
  502. } )
  503. .append(
  504. $('<div/>')
  505. .css( {
  506. position: 'absolute',
  507. top: 1,
  508. left: 1,
  509. width: 100,
  510. overflow: 'scroll'
  511. } )
  512. .append(
  513. $('<div class="test"/>')
  514. .css( {
  515. width: '100%',
  516. height: 10
  517. } )
  518. )
  519. )
  520. .appendTo( 'body' );
  521.  
  522. var test = n.find('.test');
  523.  
  524. // IE6/7 will oversize a width 100% element inside a scrolling element, to
  525. // include the width of the scrollbar, while other browsers ensure the inner
  526. // element is contained without forcing scrolling
  527. browser.bScrollOversize = test[0].offsetWidth === 100;
  528.  
  529. // In rtl text layout, some browsers (most, but not all) will place the
  530. // scrollbar on the left, rather than the right.
  531. browser.bScrollbarLeft = test.offset().left !== 1;
  532.  
  533. n.remove();
  534. }
  535.  
  536.  
  537. /**
  538. * Array.prototype reduce[Right] method, used for browsers which don't support
  539. * JS 1.6. Done this way to reduce code size, since we iterate either way
  540. * @param {object} settings dataTables settings object
  541. * @memberof DataTable#oApi
  542. */
  543. function _fnReduce ( that, fn, init, start, end, inc )
  544. {
  545. var
  546. i = start,
  547. value,
  548. isSet = false;
  549.  
  550. if ( init !== undefined ) {
  551. value = init;
  552. isSet = true;
  553. }
  554.  
  555. while ( i !== end ) {
  556. if ( ! that.hasOwnProperty(i) ) {
  557. continue;
  558. }
  559.  
  560. value = isSet ?
  561. fn( value, that[i], i, that ) :
  562. that[i];
  563.  
  564. isSet = true;
  565. i += inc;
  566. }
  567.  
  568. return value;
  569. }
  570.  
  571. /**
  572. * Add a column to the list used for the table with default values
  573. * @param {object} oSettings dataTables settings object
  574. * @param {node} nTh The th element for this column
  575. * @memberof DataTable#oApi
  576. */
  577. function _fnAddColumn( oSettings, nTh )
  578. {
  579. // Add column to aoColumns array
  580. var oDefaults = DataTable.defaults.column;
  581. var iCol = oSettings.aoColumns.length;
  582. var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
  583. "nTh": nTh ? nTh : document.createElement('th'),
  584. "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',
  585. "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
  586. "mData": oDefaults.mData ? oDefaults.mData : iCol,
  587. idx: iCol
  588. } );
  589. oSettings.aoColumns.push( oCol );
  590.  
  591. // Add search object for column specific search. Note that the `searchCols[ iCol ]`
  592. // passed into extend can be undefined. This allows the user to give a default
  593. // with only some of the parameters defined, and also not give a default
  594. var searchCols = oSettings.aoPreSearchCols;
  595. searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );
  596.  
  597. // Use the default column options function to initialise classes etc
  598. _fnColumnOptions( oSettings, iCol, null );
  599. }
  600.  
  601.  
  602. /**
  603. * Apply options for a column
  604. * @param {object} oSettings dataTables settings object
  605. * @param {int} iCol column index to consider
  606. * @param {object} oOptions object with sType, bVisible and bSearchable etc
  607. * @memberof DataTable#oApi
  608. */
  609. function _fnColumnOptions( oSettings, iCol, oOptions )
  610. {
  611. var oCol = oSettings.aoColumns[ iCol ];
  612. var oClasses = oSettings.oClasses;
  613. var th = $(oCol.nTh);
  614.  
  615. // Try to get width information from the DOM. We can't get it from CSS
  616. // as we'd need to parse the CSS stylesheet. `width` option can override
  617. if ( ! oCol.sWidthOrig ) {
  618. // Width attribute
  619. oCol.sWidthOrig = th.attr('width') || null;
  620.  
  621. // Style attribute
  622. var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
  623. if ( t ) {
  624. oCol.sWidthOrig = t[1];
  625. }
  626. }
  627.  
  628. /* User specified column options */
  629. if ( oOptions !== undefined && oOptions !== null )
  630. {
  631. // Backwards compatibility
  632. _fnCompatCols( oOptions );
  633.  
  634. // Map camel case parameters to their Hungarian counterparts
  635. _fnCamelToHungarian( DataTable.defaults.column, oOptions );
  636.  
  637. /* Backwards compatibility for mDataProp */
  638. if ( oOptions.mDataProp !== undefined && !oOptions.mData )
  639. {
  640. oOptions.mData = oOptions.mDataProp;
  641. }
  642.  
  643. if ( oOptions.sType )
  644. {
  645. oCol._sManualType = oOptions.sType;
  646. }
  647.  
  648. // `class` is a reserved word in Javascript, so we need to provide
  649. // the ability to use a valid name for the camel case input
  650. if ( oOptions.className && ! oOptions.sClass )
  651. {
  652. oOptions.sClass = oOptions.className;
  653. }
  654.  
  655. $.extend( oCol, oOptions );
  656. _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
  657.  
  658. /* iDataSort to be applied (backwards compatibility), but aDataSort will take
  659. * priority if defined
  660. */
  661. if ( typeof oOptions.iDataSort === 'number' )
  662. {
  663. oCol.aDataSort = [ oOptions.iDataSort ];
  664. }
  665. _fnMap( oCol, oOptions, "aDataSort" );
  666. }
  667.  
  668. /* Cache the data get and set functions for speed */
  669. var mDataSrc = oCol.mData;
  670. var mData = _fnGetObjectDataFn( mDataSrc );
  671. var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
  672.  
  673. var attrTest = function( src ) {
  674. return typeof src === 'string' && src.indexOf('@') !== -1;
  675. };
  676. oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (
  677. attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
  678. );
  679.  
  680. oCol.fnGetData = function (rowData, type, meta) {
  681. var innerData = mData( rowData, type, undefined, meta );
  682.  
  683. return mRender && type ?
  684. mRender( innerData, type, rowData, meta ) :
  685. innerData;
  686. };
  687. oCol.fnSetData = function ( rowData, val, meta ) {
  688. return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );
  689. };
  690.  
  691. // Indicate if DataTables should read DOM data as an object or array
  692. // Used in _fnGetRowElements
  693. if ( typeof mDataSrc !== 'number' ) {
  694. oSettings._rowReadObject = true;
  695. }
  696.  
  697. /* Feature sorting overrides column specific when off */
  698. if ( !oSettings.oFeatures.bSort )
  699. {
  700. oCol.bSortable = false;
  701. th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called
  702. }
  703.  
  704. /* Check that the class assignment is correct for sorting */
  705. var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
  706. var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
  707. if ( !oCol.bSortable || (!bAsc && !bDesc) )
  708. {
  709. oCol.sSortingClass = oClasses.sSortableNone;
  710. oCol.sSortingClassJUI = "";
  711. }
  712. else if ( bAsc && !bDesc )
  713. {
  714. oCol.sSortingClass = oClasses.sSortableAsc;
  715. oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
  716. }
  717. else if ( !bAsc && bDesc )
  718. {
  719. oCol.sSortingClass = oClasses.sSortableDesc;
  720. oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
  721. }
  722. else
  723. {
  724. oCol.sSortingClass = oClasses.sSortable;
  725. oCol.sSortingClassJUI = oClasses.sSortJUI;
  726. }
  727. }
  728.  
  729.  
  730. /**
  731. * Adjust the table column widths for new data. Note: you would probably want to
  732. * do a redraw after calling this function!
  733. * @param {object} settings dataTables settings object
  734. * @memberof DataTable#oApi
  735. */
  736. function _fnAdjustColumnSizing ( settings )
  737. {
  738. /* Not interested in doing column width calculation if auto-width is disabled */
  739. if ( settings.oFeatures.bAutoWidth !== false )
  740. {
  741. var columns = settings.aoColumns;
  742.  
  743. _fnCalculateColumnWidths( settings );
  744. for ( var i=0 , iLen=columns.length ; i<iLen ; i++ )
  745. {
  746. columns[i].nTh.style.width = columns[i].sWidth;
  747. }
  748. }
  749.  
  750. var scroll = settings.oScroll;
  751. if ( scroll.sY !== '' || scroll.sX !== '')
  752. {
  753. _fnScrollDraw( settings );
  754. }
  755.  
  756. _fnCallbackFire( settings, null, 'column-sizing', [settings] );
  757. }
  758.  
  759.  
  760. /**
  761. * Covert the index of a visible column to the index in the data array (take account
  762. * of hidden columns)
  763. * @param {object} oSettings dataTables settings object
  764. * @param {int} iMatch Visible column index to lookup
  765. * @returns {int} i the data index
  766. * @memberof DataTable#oApi
  767. */
  768. function _fnVisibleToColumnIndex( oSettings, iMatch )
  769. {
  770. var aiVis = _fnGetColumns( oSettings, 'bVisible' );
  771.  
  772. return typeof aiVis[iMatch] === 'number' ?
  773. aiVis[iMatch] :
  774. null;
  775. }
  776.  
  777.  
  778. /**
  779. * Covert the index of an index in the data array and convert it to the visible
  780. * column index (take account of hidden columns)
  781. * @param {int} iMatch Column index to lookup
  782. * @param {object} oSettings dataTables settings object
  783. * @returns {int} i the data index
  784. * @memberof DataTable#oApi
  785. */
  786. function _fnColumnIndexToVisible( oSettings, iMatch )
  787. {
  788. var aiVis = _fnGetColumns( oSettings, 'bVisible' );
  789. var iPos = $.inArray( iMatch, aiVis );
  790.  
  791. return iPos !== -1 ? iPos : null;
  792. }
  793.  
  794.  
  795. /**
  796. * Get the number of visible columns
  797. * @param {object} oSettings dataTables settings object
  798. * @returns {int} i the number of visible columns
  799. * @memberof DataTable#oApi
  800. */
  801. function _fnVisbleColumns( oSettings )
  802. {
  803. return _fnGetColumns( oSettings, 'bVisible' ).length;
  804. }
  805.  
  806.  
  807. /**
  808. * Get an array of column indexes that match a given property
  809. * @param {object} oSettings dataTables settings object
  810. * @param {string} sParam Parameter in aoColumns to look for - typically
  811. * bVisible or bSearchable
  812. * @returns {array} Array of indexes with matched properties
  813. * @memberof DataTable#oApi
  814. */
  815. function _fnGetColumns( oSettings, sParam )
  816. {
  817. var a = [];
  818.  
  819. $.map( oSettings.aoColumns, function(val, i) {
  820. if ( val[sParam] ) {
  821. a.push( i );
  822. }
  823. } );
  824.  
  825. return a;
  826. }
  827.  
  828.  
  829. /**
  830. * Calculate the 'type' of a column
  831. * @param {object} settings dataTables settings object
  832. * @memberof DataTable#oApi
  833. */
  834. function _fnColumnTypes ( settings )
  835. {
  836. var columns = settings.aoColumns;
  837. var data = settings.aoData;
  838. var types = DataTable.ext.type.detect;
  839. var i, ien, j, jen, k, ken;
  840. var col, cell, detectedType, cache;
  841.  
  842. // For each column, spin over the
  843. for ( i=0, ien=columns.length ; i<ien ; i++ ) {
  844. col = columns[i];
  845. cache = [];
  846.  
  847. if ( ! col.sType && col._sManualType ) {
  848. col.sType = col._sManualType;
  849. }
  850. else if ( ! col.sType ) {
  851. for ( j=0, jen=types.length ; j<jen ; j++ ) {
  852. for ( k=0, ken=data.length ; k<ken ; k++ ) {
  853. // Use a cache array so we only need to get the type data
  854. // from the formatter once (when using multiple detectors)
  855. if ( cache[k] === undefined ) {
  856. cache[k] = _fnGetCellData( settings, k, i, 'type' );
  857. }
  858.  
  859. detectedType = types[j]( cache[k], settings );
  860.  
  861. // If null, then this type can't apply to this column, so
  862. // rather than testing all cells, break out. There is an
  863. // exception for the last type which is `html`. We need to
  864. // scan all rows since it is possible to mix string and HTML
  865. // types
  866. if ( ! detectedType && j !== types.length-1 ) {
  867. break;
  868. }
  869.  
  870. // Only a single match is needed for html type since it is
  871. // bottom of the pile and very similar to string
  872. if ( detectedType === 'html' ) {
  873. break;
  874. }
  875. }
  876.  
  877. // Type is valid for all data points in the column - use this
  878. // type
  879. if ( detectedType ) {
  880. col.sType = detectedType;
  881. break;
  882. }
  883. }
  884.  
  885. // Fall back - if no type was detected, always use string
  886. if ( ! col.sType ) {
  887. col.sType = 'string';
  888. }
  889. }
  890. }
  891. }
  892.  
  893.  
  894. /**
  895. * Take the column definitions and static columns arrays and calculate how
  896. * they relate to column indexes. The callback function will then apply the
  897. * definition found for a column to a suitable configuration object.
  898. * @param {object} oSettings dataTables settings object
  899. * @param {array} aoColDefs The aoColumnDefs array that is to be applied
  900. * @param {array} aoCols The aoColumns array that defines columns individually
  901. * @param {function} fn Callback function - takes two parameters, the calculated
  902. * column index and the definition for that column.
  903. * @memberof DataTable#oApi
  904. */
  905. function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
  906. {
  907. var i, iLen, j, jLen, k, kLen, def;
  908. var columns = oSettings.aoColumns;
  909.  
  910. // Column definitions with aTargets
  911. if ( aoColDefs )
  912. {
  913. /* Loop over the definitions array - loop in reverse so first instance has priority */
  914. for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
  915. {
  916. def = aoColDefs[i];
  917.  
  918. /* Each definition can target multiple columns, as it is an array */
  919. var aTargets = def.targets !== undefined ?
  920. def.targets :
  921. def.aTargets;
  922.  
  923. if ( ! $.isArray( aTargets ) )
  924. {
  925. aTargets = [ aTargets ];
  926. }
  927.  
  928. for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
  929. {
  930. if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
  931. {
  932. /* Add columns that we don't yet know about */
  933. while( columns.length <= aTargets[j] )
  934. {
  935. _fnAddColumn( oSettings );
  936. }
  937.  
  938. /* Integer, basic index */
  939. fn( aTargets[j], def );
  940. }
  941. else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
  942. {
  943. /* Negative integer, right to left column counting */
  944. fn( columns.length+aTargets[j], def );
  945. }
  946. else if ( typeof aTargets[j] === 'string' )
  947. {
  948. /* Class name matching on TH element */
  949. for ( k=0, kLen=columns.length ; k<kLen ; k++ )
  950. {
  951. if ( aTargets[j] == "_all" ||
  952. $(columns[k].nTh).hasClass( aTargets[j] ) )
  953. {
  954. fn( k, def );
  955. }
  956. }
  957. }
  958. }
  959. }
  960. }
  961.  
  962. // Statically defined columns array
  963. if ( aoCols )
  964. {
  965. for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
  966. {
  967. fn( i, aoCols[i] );
  968. }
  969. }
  970. }
  971.  
  972. /**
  973. * Add a data array to the table, creating DOM node etc. This is the parallel to
  974. * _fnGatherData, but for adding rows from a Javascript source, rather than a
  975. * DOM source.
  976. * @param {object} oSettings dataTables settings object
  977. * @param {array} aData data array to be added
  978. * @param {node} [nTr] TR element to add to the table - optional. If not given,
  979. * DataTables will create a row automatically
  980. * @param {array} [anTds] Array of TD|TH elements for the row - must be given
  981. * if nTr is.
  982. * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
  983. * @memberof DataTable#oApi
  984. */
  985. function _fnAddData ( oSettings, aDataIn, nTr, anTds )
  986. {
  987. /* Create the object for storing information about this new row */
  988. var iRow = oSettings.aoData.length;
  989. var oData = $.extend( true, {}, DataTable.models.oRow, {
  990. src: nTr ? 'dom' : 'data'
  991. } );
  992.  
  993. oData._aData = aDataIn;
  994. oSettings.aoData.push( oData );
  995.  
  996. /* Create the cells */
  997. var nTd, sThisType;
  998. var columns = oSettings.aoColumns;
  999. for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
  1000. {
  1001. // When working with a row, the data source object must be populated. In
  1002. // all other cases, the data source object is already populated, so we
  1003. // don't overwrite it, which might break bindings etc
  1004. if ( nTr ) {
  1005. _fnSetCellData( oSettings, iRow, i, _fnGetCellData( oSettings, iRow, i ) );
  1006. }
  1007. columns[i].sType = null;
  1008. }
  1009.  
  1010. /* Add to the display array */
  1011. oSettings.aiDisplayMaster.push( iRow );
  1012.  
  1013. /* Create the DOM information, or register it if already present */
  1014. if ( nTr || ! oSettings.oFeatures.bDeferRender )
  1015. {
  1016. _fnCreateTr( oSettings, iRow, nTr, anTds );
  1017. }
  1018.  
  1019. return iRow;
  1020. }
  1021.  
  1022.  
  1023. /**
  1024. * Add one or more TR elements to the table. Generally we'd expect to
  1025. * use this for reading data from a DOM sourced table, but it could be
  1026. * used for an TR element. Note that if a TR is given, it is used (i.e.
  1027. * it is not cloned).
  1028. * @param {object} settings dataTables settings object
  1029. * @param {array|node|jQuery} trs The TR element(s) to add to the table
  1030. * @returns {array} Array of indexes for the added rows
  1031. * @memberof DataTable#oApi
  1032. */
  1033. function _fnAddTr( settings, trs )
  1034. {
  1035. var row;
  1036.  
  1037. // Allow an individual node to be passed in
  1038. if ( ! (trs instanceof $) ) {
  1039. trs = $(trs);
  1040. }
  1041.  
  1042. return trs.map( function (i, el) {
  1043. row = _fnGetRowElements( settings, el );
  1044. return _fnAddData( settings, row.data, el, row.cells );
  1045. } );
  1046. }
  1047.  
  1048.  
  1049. /**
  1050. * Take a TR element and convert it to an index in aoData
  1051. * @param {object} oSettings dataTables settings object
  1052. * @param {node} n the TR element to find
  1053. * @returns {int} index if the node is found, null if not
  1054. * @memberof DataTable#oApi
  1055. */
  1056. function _fnNodeToDataIndex( oSettings, n )
  1057. {
  1058. return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
  1059. }
  1060.  
  1061.  
  1062. /**
  1063. * Take a TD element and convert it into a column data index (not the visible index)
  1064. * @param {object} oSettings dataTables settings object
  1065. * @param {int} iRow The row number the TD/TH can be found in
  1066. * @param {node} n The TD/TH element to find
  1067. * @returns {int} index if the node is found, -1 if not
  1068. * @memberof DataTable#oApi
  1069. */
  1070. function _fnNodeToColumnIndex( oSettings, iRow, n )
  1071. {
  1072. return $.inArray( n, oSettings.aoData[ iRow ].anCells );
  1073. }
  1074.  
  1075.  
  1076. /**
  1077. * Get the data for a given cell from the internal cache, taking into account data mapping
  1078. * @param {object} settings dataTables settings object
  1079. * @param {int} rowIdx aoData row id
  1080. * @param {int} colIdx Column index
  1081. * @param {string} type data get type ('display', 'type' 'filter' 'sort')
  1082. * @returns {*} Cell data
  1083. * @memberof DataTable#oApi
  1084. */
  1085. function _fnGetCellData( settings, rowIdx, colIdx, type )
  1086. {
  1087. var draw = settings.iDraw;
  1088. var col = settings.aoColumns[colIdx];
  1089. var rowData = settings.aoData[rowIdx]._aData;
  1090. var defaultContent = col.sDefaultContent;
  1091. var cellData = col.fnGetData( rowData, type, {
  1092. settings: settings,
  1093. row: rowIdx,
  1094. col: colIdx
  1095. } );
  1096.  
  1097. if ( cellData === undefined ) {
  1098. if ( settings.iDrawError != draw && defaultContent === null ) {
  1099. _fnLog( settings, 0, "Requested unknown parameter "+
  1100. (typeof col.mData=='function' ? '{function}' : "'"+col.mData+"'")+
  1101. " for row "+rowIdx, 4 );
  1102. settings.iDrawError = draw;
  1103. }
  1104. return defaultContent;
  1105. }
  1106.  
  1107. /* When the data source is null, we can use default column data */
  1108. if ( (cellData === rowData || cellData === null) && defaultContent !== null ) {
  1109. cellData = defaultContent;
  1110. }
  1111. else if ( typeof cellData === 'function' ) {
  1112. // If the data source is a function, then we run it and use the return,
  1113. // executing in the scope of the data object (for instances)
  1114. return cellData.call( rowData );
  1115. }
  1116.  
  1117. if ( cellData === null && type == 'display' ) {
  1118. return '';
  1119. }
  1120. return cellData;
  1121. }
  1122.  
  1123.  
  1124. /**
  1125. * Set the value for a specific cell, into the internal data cache
  1126. * @param {object} settings dataTables settings object
  1127. * @param {int} rowIdx aoData row id
  1128. * @param {int} colIdx Column index
  1129. * @param {*} val Value to set
  1130. * @memberof DataTable#oApi
  1131. */
  1132. function _fnSetCellData( settings, rowIdx, colIdx, val )
  1133. {
  1134. var col = settings.aoColumns[colIdx];
  1135. var rowData = settings.aoData[rowIdx]._aData;
  1136.  
  1137. col.fnSetData( rowData, val, {
  1138. settings: settings,
  1139. row: rowIdx,
  1140. col: colIdx
  1141. } );
  1142. }
  1143.  
  1144.  
  1145. // Private variable that is used to match action syntax in the data property object
  1146. var __reArray = /\[.*?\]$/;
  1147. var __reFn = /\(\)$/;
  1148.  
  1149. /**
  1150. * Split string on periods, taking into account escaped periods
  1151. * @param {string} str String to split
  1152. * @return {array} Split string
  1153. */
  1154. function _fnSplitObjNotation( str )
  1155. {
  1156. return $.map( str.match(/(\\.|[^\.])+/g), function ( s ) {
  1157. return s.replace(/\\./g, '.');
  1158. } );
  1159. }
  1160.  
  1161.  
  1162. /**
  1163. * Return a function that can be used to get data from a source object, taking
  1164. * into account the ability to use nested objects as a source
  1165. * @param {string|int|function} mSource The data source for the object
  1166. * @returns {function} Data get function
  1167. * @memberof DataTable#oApi
  1168. */
  1169. function _fnGetObjectDataFn( mSource )
  1170. {
  1171. if ( $.isPlainObject( mSource ) )
  1172. {
  1173. /* Build an object of get functions, and wrap them in a single call */
  1174. var o = {};
  1175. $.each( mSource, function (key, val) {
  1176. if ( val ) {
  1177. o[key] = _fnGetObjectDataFn( val );
  1178. }
  1179. } );
  1180.  
  1181. return function (data, type, row, meta) {
  1182. var t = o[type] || o._;
  1183. return t !== undefined ?
  1184. t(data, type, row, meta) :
  1185. data;
  1186. };
  1187. }
  1188. else if ( mSource === null )
  1189. {
  1190. /* Give an empty string for rendering / sorting etc */
  1191. return function (data) { // type, row and meta also passed, but not used
  1192. return data;
  1193. };
  1194. }
  1195. else if ( typeof mSource === 'function' )
  1196. {
  1197. return function (data, type, row, meta) {
  1198. return mSource( data, type, row, meta );
  1199. };
  1200. }
  1201. else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
  1202. mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
  1203. {
  1204. /* If there is a . in the source string then the data source is in a
  1205. * nested object so we loop over the data for each level to get the next
  1206. * level down. On each loop we test for undefined, and if found immediately
  1207. * return. This allows entire objects to be missing and sDefaultContent to
  1208. * be used if defined, rather than throwing an error
  1209. */
  1210. var fetchData = function (data, type, src) {
  1211. var arrayNotation, funcNotation, out, innerSrc;
  1212.  
  1213. if ( src !== "" )
  1214. {
  1215. var a = _fnSplitObjNotation( src );
  1216.  
  1217. for ( var i=0, iLen=a.length ; i<iLen ; i++ )
  1218. {
  1219. // Check if we are dealing with special notation
  1220. arrayNotation = a[i].match(__reArray);
  1221. funcNotation = a[i].match(__reFn);
  1222.  
  1223. if ( arrayNotation )
  1224. {
  1225. // Array notation
  1226. a[i] = a[i].replace(__reArray, '');
  1227.  
  1228. // Condition allows simply [] to be passed in
  1229. if ( a[i] !== "" ) {
  1230. data = data[ a[i] ];
  1231. }
  1232. out = [];
  1233.  
  1234. // Get the remainder of the nested object to get
  1235. a.splice( 0, i+1 );
  1236. innerSrc = a.join('.');
  1237.  
  1238. // Traverse each entry in the array getting the properties requested
  1239. for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
  1240. out.push( fetchData( data[j], type, innerSrc ) );
  1241. }
  1242.  
  1243. // If a string is given in between the array notation indicators, that
  1244. // is used to join the strings together, otherwise an array is returned
  1245. var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
  1246. data = (join==="") ? out : out.join(join);
  1247.  
  1248. // The inner call to fetchData has already traversed through the remainder
  1249. // of the source requested, so we exit from the loop
  1250. break;
  1251. }
  1252. else if ( funcNotation )
  1253. {
  1254. // Function call
  1255. a[i] = a[i].replace(__reFn, '');
  1256. data = data[ a[i] ]();
  1257. continue;
  1258. }
  1259.  
  1260. if ( data === null || data[ a[i] ] === undefined )
  1261. {
  1262. return undefined;
  1263. }
  1264. data = data[ a[i] ];
  1265. }
  1266. }
  1267.  
  1268. return data;
  1269. };
  1270.  
  1271. return function (data, type) { // row and meta also passed, but not used
  1272. return fetchData( data, type, mSource );
  1273. };
  1274. }
  1275. else
  1276. {
  1277. /* Array or flat object mapping */
  1278. return function (data, type) { // row and meta also passed, but not used
  1279. return data[mSource];
  1280. };
  1281. }
  1282. }
  1283.  
  1284.  
  1285. /**
  1286. * Return a function that can be used to set data from a source object, taking
  1287. * into account the ability to use nested objects as a source
  1288. * @param {string|int|function} mSource The data source for the object
  1289. * @returns {function} Data set function
  1290. * @memberof DataTable#oApi
  1291. */
  1292. function _fnSetObjectDataFn( mSource )
  1293. {
  1294. if ( $.isPlainObject( mSource ) )
  1295. {
  1296. /* Unlike get, only the underscore (global) option is used for for
  1297. * setting data since we don't know the type here. This is why an object
  1298. * option is not documented for `mData` (which is read/write), but it is
  1299. * for `mRender` which is read only.
  1300. */
  1301. return _fnSetObjectDataFn( mSource._ );
  1302. }
  1303. else if ( mSource === null )
  1304. {
  1305. /* Nothing to do when the data source is null */
  1306. return function () {};
  1307. }
  1308. else if ( typeof mSource === 'function' )
  1309. {
  1310. return function (data, val, meta) {
  1311. mSource( data, 'set', val, meta );
  1312. };
  1313. }
  1314. else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
  1315. mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
  1316. {
  1317. /* Like the get, we need to get data from a nested object */
  1318. var setData = function (data, val, src) {
  1319. var a = _fnSplitObjNotation( src ), b;
  1320. var aLast = a[a.length-1];
  1321. var arrayNotation, funcNotation, o, innerSrc;
  1322.  
  1323. for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
  1324. {
  1325. // Check if we are dealing with an array notation request
  1326. arrayNotation = a[i].match(__reArray);
  1327. funcNotation = a[i].match(__reFn);
  1328.  
  1329. if ( arrayNotation )
  1330. {
  1331. a[i] = a[i].replace(__reArray, '');
  1332. data[ a[i] ] = [];
  1333.  
  1334. // Get the remainder of the nested object to set so we can recurse
  1335. b = a.slice();
  1336. b.splice( 0, i+1 );
  1337. innerSrc = b.join('.');
  1338.  
  1339. // Traverse each entry in the array setting the properties requested
  1340. for ( var j=0, jLen=val.length ; j<jLen ; j++ )
  1341. {
  1342. o = {};
  1343. setData( o, val[j], innerSrc );
  1344. data[ a[i] ].push( o );
  1345. }
  1346.  
  1347. // The inner call to setData has already traversed through the remainder
  1348. // of the source and has set the data, thus we can exit here
  1349. return;
  1350. }
  1351. else if ( funcNotation )
  1352. {
  1353. // Function call
  1354. a[i] = a[i].replace(__reFn, '');
  1355. data = data[ a[i] ]( val );
  1356. }
  1357.  
  1358. // If the nested object doesn't currently exist - since we are
  1359. // trying to set the value - create it
  1360. if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
  1361. {
  1362. data[ a[i] ] = {};
  1363. }
  1364. data = data[ a[i] ];
  1365. }
  1366.  
  1367. // Last item in the input - i.e, the actual set
  1368. if ( aLast.match(__reFn ) )
  1369. {
  1370. // Function call
  1371. data = data[ aLast.replace(__reFn, '') ]( val );
  1372. }
  1373. else
  1374. {
  1375. // If array notation is used, we just want to strip it and use the property name
  1376. // and assign the value. If it isn't used, then we get the result we want anyway
  1377. data[ aLast.replace(__reArray, '') ] = val;
  1378. }
  1379. };
  1380.  
  1381. return function (data, val) { // meta is also passed in, but not used
  1382. return setData( data, val, mSource );
  1383. };
  1384. }
  1385. else
  1386. {
  1387. /* Array or flat object mapping */
  1388. return function (data, val) { // meta is also passed in, but not used
  1389. data[mSource] = val;
  1390. };
  1391. }
  1392. }
  1393.  
  1394.  
  1395. /**
  1396. * Return an array with the full table data
  1397. * @param {object} oSettings dataTables settings object
  1398. * @returns array {array} aData Master data array
  1399. * @memberof DataTable#oApi
  1400. */
  1401. function _fnGetDataMaster ( settings )
  1402. {
  1403. return _pluck( settings.aoData, '_aData' );
  1404. }
  1405.  
  1406.  
  1407. /**
  1408. * Nuke the table
  1409. * @param {object} oSettings dataTables settings object
  1410. * @memberof DataTable#oApi
  1411. */
  1412. function _fnClearTable( settings )
  1413. {
  1414. settings.aoData.length = 0;
  1415. settings.aiDisplayMaster.length = 0;
  1416. settings.aiDisplay.length = 0;
  1417. }
  1418.  
  1419.  
  1420. /**
  1421. * Take an array of integers (index array) and remove a target integer (value - not
  1422. * the key!)
  1423. * @param {array} a Index array to target
  1424. * @param {int} iTarget value to find
  1425. * @memberof DataTable#oApi
  1426. */
  1427. function _fnDeleteIndex( a, iTarget, splice )
  1428. {
  1429. var iTargetIndex = -1;
  1430.  
  1431. for ( var i=0, iLen=a.length ; i<iLen ; i++ )
  1432. {
  1433. if ( a[i] == iTarget )
  1434. {
  1435. iTargetIndex = i;
  1436. }
  1437. else if ( a[i] > iTarget )
  1438. {
  1439. a[i]--;
  1440. }
  1441. }
  1442.  
  1443. if ( iTargetIndex != -1 && splice === undefined )
  1444. {
  1445. a.splice( iTargetIndex, 1 );
  1446. }
  1447. }
  1448.  
  1449.  
  1450. /**
  1451. * Mark cached data as invalid such that a re-read of the data will occur when
  1452. * the cached data is next requested. Also update from the data source object.
  1453. *
  1454. * @param {object} settings DataTables settings object
  1455. * @param {int} rowIdx Row index to invalidate
  1456. * @param {string} [src] Source to invalidate from: undefined, 'auto', 'dom'
  1457. * or 'data'
  1458. * @param {int} [colIdx] Column index to invalidate. If undefined the whole
  1459. * row will be invalidated
  1460. * @memberof DataTable#oApi
  1461. *
  1462. * @todo For the modularisation of v1.11 this will need to become a callback, so
  1463. * the sort and filter methods can subscribe to it. That will required
  1464. * initialisation options for sorting, which is why it is not already baked in
  1465. */
  1466. function _fnInvalidate( settings, rowIdx, src, colIdx )
  1467. {
  1468. var row = settings.aoData[ rowIdx ];
  1469. var i, ien;
  1470. var cellWrite = function ( cell, col ) {
  1471. // This is very frustrating, but in IE if you just write directly
  1472. // to innerHTML, and elements that are overwritten are GC'ed,
  1473. // even if there is a reference to them elsewhere
  1474. while ( cell.childNodes.length ) {
  1475. cell.removeChild( cell.firstChild );
  1476. }
  1477.  
  1478. cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );
  1479. };
  1480.  
  1481. // Are we reading last data from DOM or the data object?
  1482. if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {
  1483. // Read the data from the DOM
  1484. row._aData = _fnGetRowElements(
  1485. settings, row, colIdx, colIdx === undefined ? undefined : row._aData
  1486. )
  1487. .data;
  1488. }
  1489. else {
  1490. // Reading from data object, update the DOM
  1491. var cells = row.anCells;
  1492.  
  1493. if ( cells ) {
  1494. if ( colIdx !== undefined ) {
  1495. cellWrite( cells[colIdx], colIdx );
  1496. }
  1497. else {
  1498. for ( i=0, ien=cells.length ; i<ien ; i++ ) {
  1499. cellWrite( cells[i], i );
  1500. }
  1501. }
  1502. }
  1503. }
  1504.  
  1505. // For both row and cell invalidation, the cached data for sorting and
  1506. // filtering is nulled out
  1507. row._aSortData = null;
  1508. row._aFilterData = null;
  1509.  
  1510. // Invalidate the type for a specific column (if given) or all columns since
  1511. // the data might have changed
  1512. var cols = settings.aoColumns;
  1513. if ( colIdx !== undefined ) {
  1514. cols[ colIdx ].sType = null;
  1515. }
  1516. else {
  1517. for ( i=0, ien=cols.length ; i<ien ; i++ ) {
  1518. cols[i].sType = null;
  1519. }
  1520.  
  1521. // Update DataTables special `DT_*` attributes for the row
  1522. _fnRowAttributes( row );
  1523. }
  1524. }
  1525.  
  1526.  
  1527. /**
  1528. * Build a data source object from an HTML row, reading the contents of the
  1529. * cells that are in the row.
  1530. *
  1531. * @param {object} settings DataTables settings object
  1532. * @param {node|object} TR element from which to read data or existing row
  1533. * object from which to re-read the data from the cells
  1534. * @param {int} [colIdx] Optional column index
  1535. * @param {array|object} [d] Data source object. If `colIdx` is given then this
  1536. * parameter should also be given and will be used to write the data into.
  1537. * Only the column in question will be written
  1538. * @returns {object} Object with two parameters: `data` the data read, in
  1539. * document order, and `cells` and array of nodes (they can be useful to the
  1540. * caller, so rather than needing a second traversal to get them, just return
  1541. * them from here).
  1542. * @memberof DataTable#oApi
  1543. */
  1544. function _fnGetRowElements( settings, row, colIdx, d )
  1545. {
  1546. var
  1547. tds = [],
  1548. td = row.firstChild,
  1549. name, col, o, i=0, contents,
  1550. columns = settings.aoColumns,
  1551. objectRead = settings._rowReadObject;
  1552.  
  1553. // Allow the data object to be passed in, or construct
  1554. d = d || objectRead ? {} : [];
  1555.  
  1556. var attr = function ( str, td ) {
  1557. if ( typeof str === 'string' ) {
  1558. var idx = str.indexOf('@');
  1559.  
  1560. if ( idx !== -1 ) {
  1561. var attr = str.substring( idx+1 );
  1562. var setter = _fnSetObjectDataFn( str );
  1563. setter( d, td.getAttribute( attr ) );
  1564. }
  1565. }
  1566. };
  1567.  
  1568. // Read data from a cell and store into the data object
  1569. var cellProcess = function ( cell ) {
  1570. if ( colIdx === undefined || colIdx === i ) {
  1571. col = columns[i];
  1572. contents = $.trim(cell.innerHTML);
  1573.  
  1574. if ( col && col._bAttrSrc ) {
  1575. var setter = _fnSetObjectDataFn( col.mData._ );
  1576. setter( d, contents );
  1577.  
  1578. attr( col.mData.sort, cell );
  1579. attr( col.mData.type, cell );
  1580. attr( col.mData.filter, cell );
  1581. }
  1582. else {
  1583. // Depending on the `data` option for the columns the data can
  1584. // be read to either an object or an array.
  1585. if ( objectRead ) {
  1586. if ( ! col._setter ) {
  1587. // Cache the setter function
  1588. col._setter = _fnSetObjectDataFn( col.mData );
  1589. }
  1590. col._setter( d, contents );
  1591. }
  1592. else {
  1593. d[i] = contents;
  1594. }
  1595. }
  1596. }
  1597.  
  1598. i++;
  1599. };
  1600.  
  1601. if ( td ) {
  1602. // `tr` element was passed in
  1603. while ( td ) {
  1604. name = td.nodeName.toUpperCase();
  1605.  
  1606. if ( name == "TD" || name == "TH" ) {
  1607. cellProcess( td );
  1608. tds.push( td );
  1609. }
  1610.  
  1611. td = td.nextSibling;
  1612. }
  1613. }
  1614. else {
  1615. // Existing row object passed in
  1616. tds = row.anCells;
  1617.  
  1618. for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
  1619. cellProcess( tds[j] );
  1620. }
  1621. }
  1622.  
  1623. return {
  1624. data: d,
  1625. cells: tds
  1626. };
  1627. }
  1628. /**
  1629. * Create a new TR element (and it's TD children) for a row
  1630. * @param {object} oSettings dataTables settings object
  1631. * @param {int} iRow Row to consider
  1632. * @param {node} [nTrIn] TR element to add to the table - optional. If not given,
  1633. * DataTables will create a row automatically
  1634. * @param {array} [anTds] Array of TD|TH elements for the row - must be given
  1635. * if nTr is.
  1636. * @memberof DataTable#oApi
  1637. */
  1638. function _fnCreateTr ( oSettings, iRow, nTrIn, anTds )
  1639. {
  1640. var
  1641. row = oSettings.aoData[iRow],
  1642. rowData = row._aData,
  1643. cells = [],
  1644. nTr, nTd, oCol,
  1645. i, iLen;
  1646.  
  1647. if ( row.nTr === null )
  1648. {
  1649. nTr = nTrIn || document.createElement('tr');
  1650.  
  1651. row.nTr = nTr;
  1652. row.anCells = cells;
  1653.  
  1654. /* Use a private property on the node to allow reserve mapping from the node
  1655. * to the aoData array for fast look up
  1656. */
  1657. nTr._DT_RowIndex = iRow;
  1658.  
  1659. /* Special parameters can be given by the data source to be used on the row */
  1660. _fnRowAttributes( row );
  1661.  
  1662. /* Process each column */
  1663. for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  1664. {
  1665. oCol = oSettings.aoColumns[i];
  1666.  
  1667. nTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );
  1668. cells.push( nTd );
  1669.  
  1670. // Need to create the HTML if new, or if a rendering function is defined
  1671. if ( !nTrIn || oCol.mRender || oCol.mData !== i )
  1672. {
  1673. nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
  1674. }
  1675.  
  1676. /* Add user defined class */
  1677. if ( oCol.sClass )
  1678. {
  1679. nTd.className += ' '+oCol.sClass;
  1680. }
  1681.  
  1682. // Visibility - add or remove as required
  1683. if ( oCol.bVisible && ! nTrIn )
  1684. {
  1685. nTr.appendChild( nTd );
  1686. }
  1687. else if ( ! oCol.bVisible && nTrIn )
  1688. {
  1689. nTd.parentNode.removeChild( nTd );
  1690. }
  1691.  
  1692. if ( oCol.fnCreatedCell )
  1693. {
  1694. oCol.fnCreatedCell.call( oSettings.oInstance,
  1695. nTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i
  1696. );
  1697. }
  1698. }
  1699.  
  1700. _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );
  1701. }
  1702.  
  1703. // Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
  1704. // and deployed
  1705. row.nTr.setAttribute( 'role', 'row' );
  1706. }
  1707.  
  1708.  
  1709. /**
  1710. * Add attributes to a row based on the special `DT_*` parameters in a data
  1711. * source object.
  1712. * @param {object} DataTables row object for the row to be modified
  1713. * @memberof DataTable#oApi
  1714. */
  1715. function _fnRowAttributes( row )
  1716. {
  1717. var tr = row.nTr;
  1718. var data = row._aData;
  1719.  
  1720. if ( tr ) {
  1721. if ( data.DT_RowId ) {
  1722. tr.id = data.DT_RowId;
  1723. }
  1724.  
  1725. if ( data.DT_RowClass ) {
  1726. // Remove any classes added by DT_RowClass before
  1727. var a = data.DT_RowClass.split(' ');
  1728. row.__rowc = row.__rowc ?
  1729. _unique( row.__rowc.concat( a ) ) :
  1730. a;
  1731.  
  1732. $(tr)
  1733. .removeClass( row.__rowc.join(' ') )
  1734. .addClass( data.DT_RowClass );
  1735. }
  1736.  
  1737. if ( data.DT_RowData ) {
  1738. $(tr).data( data.DT_RowData );
  1739. }
  1740. }
  1741. }
  1742.  
  1743.  
  1744. /**
  1745. * Create the HTML header for the table
  1746. * @param {object} oSettings dataTables settings object
  1747. * @memberof DataTable#oApi
  1748. */
  1749. function _fnBuildHead( oSettings )
  1750. {
  1751. var i, ien, cell, row, column;
  1752. var thead = oSettings.nTHead;
  1753. var tfoot = oSettings.nTFoot;
  1754. var createHeader = $('th, td', thead).length === 0;
  1755. var classes = oSettings.oClasses;
  1756. var columns = oSettings.aoColumns;
  1757.  
  1758. if ( createHeader ) {
  1759. row = $('<tr/>').appendTo( thead );
  1760. }
  1761.  
  1762. for ( i=0, ien=columns.length ; i<ien ; i++ ) {
  1763. column = columns[i];
  1764. cell = $( column.nTh ).addClass( column.sClass );
  1765.  
  1766. if ( createHeader ) {
  1767. cell.appendTo( row );
  1768. }
  1769.  
  1770. // 1.11 move into sorting
  1771. if ( oSettings.oFeatures.bSort ) {
  1772. cell.addClass( column.sSortingClass );
  1773.  
  1774. if ( column.bSortable !== false ) {
  1775. cell
  1776. .attr( 'tabindex', oSettings.iTabIndex )
  1777. .attr( 'aria-controls', oSettings.sTableId );
  1778.  
  1779. _fnSortAttachListener( oSettings, column.nTh, i );
  1780. }
  1781. }
  1782.  
  1783. if ( column.sTitle != cell.html() ) {
  1784. cell.html( column.sTitle );
  1785. }
  1786.  
  1787. _fnRenderer( oSettings, 'header' )(
  1788. oSettings, cell, column, classes
  1789. );
  1790. }
  1791.  
  1792. if ( createHeader ) {
  1793. _fnDetectHeader( oSettings.aoHeader, thead );
  1794. }
  1795.  
  1796. /* ARIA role for the rows */
  1797. $(thead).find('>tr').attr('role', 'row');
  1798.  
  1799. /* Deal with the footer - add classes if required */
  1800. $(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );
  1801. $(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );
  1802.  
  1803. // Cache the footer cells. Note that we only take the cells from the first
  1804. // row in the footer. If there is more than one row the user wants to
  1805. // interact with, they need to use the table().foot() method. Note also this
  1806. // allows cells to be used for multiple columns using colspan
  1807. if ( tfoot !== null ) {
  1808. var cells = oSettings.aoFooter[0];
  1809.  
  1810. for ( i=0, ien=cells.length ; i<ien ; i++ ) {
  1811. column = columns[i];
  1812. column.nTf = cells[i].cell;
  1813.  
  1814. if ( column.sClass ) {
  1815. $(column.nTf).addClass( column.sClass );
  1816. }
  1817. }
  1818. }
  1819. }
  1820.  
  1821.  
  1822. /**
  1823. * Draw the header (or footer) element based on the column visibility states. The
  1824. * methodology here is to use the layout array from _fnDetectHeader, modified for
  1825. * the instantaneous column visibility, to construct the new layout. The grid is
  1826. * traversed over cell at a time in a rows x columns grid fashion, although each
  1827. * cell insert can cover multiple elements in the grid - which is tracks using the
  1828. * aApplied array. Cell inserts in the grid will only occur where there isn't
  1829. * already a cell in that position.
  1830. * @param {object} oSettings dataTables settings object
  1831. * @param array {objects} aoSource Layout array from _fnDetectHeader
  1832. * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
  1833. * @memberof DataTable#oApi
  1834. */
  1835. function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
  1836. {
  1837. var i, iLen, j, jLen, k, kLen, n, nLocalTr;
  1838. var aoLocal = [];
  1839. var aApplied = [];
  1840. var iColumns = oSettings.aoColumns.length;
  1841. var iRowspan, iColspan;
  1842.  
  1843. if ( ! aoSource )
  1844. {
  1845. return;
  1846. }
  1847.  
  1848. if ( bIncludeHidden === undefined )
  1849. {
  1850. bIncludeHidden = false;
  1851. }
  1852.  
  1853. /* Make a copy of the master layout array, but without the visible columns in it */
  1854. for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
  1855. {
  1856. aoLocal[i] = aoSource[i].slice();
  1857. aoLocal[i].nTr = aoSource[i].nTr;
  1858.  
  1859. /* Remove any columns which are currently hidden */
  1860. for ( j=iColumns-1 ; j>=0 ; j-- )
  1861. {
  1862. if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
  1863. {
  1864. aoLocal[i].splice( j, 1 );
  1865. }
  1866. }
  1867.  
  1868. /* Prep the applied array - it needs an element for each row */
  1869. aApplied.push( [] );
  1870. }
  1871.  
  1872. for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
  1873. {
  1874. nLocalTr = aoLocal[i].nTr;
  1875.  
  1876. /* All cells are going to be replaced, so empty out the row */
  1877. if ( nLocalTr )
  1878. {
  1879. while( (n = nLocalTr.firstChild) )
  1880. {
  1881. nLocalTr.removeChild( n );
  1882. }
  1883. }
  1884.  
  1885. for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
  1886. {
  1887. iRowspan = 1;
  1888. iColspan = 1;
  1889.  
  1890. /* Check to see if there is already a cell (row/colspan) covering our target
  1891. * insert point. If there is, then there is nothing to do.
  1892. */
  1893. if ( aApplied[i][j] === undefined )
  1894. {
  1895. nLocalTr.appendChild( aoLocal[i][j].cell );
  1896. aApplied[i][j] = 1;
  1897.  
  1898. /* Expand the cell to cover as many rows as needed */
  1899. while ( aoLocal[i+iRowspan] !== undefined &&
  1900. aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
  1901. {
  1902. aApplied[i+iRowspan][j] = 1;
  1903. iRowspan++;
  1904. }
  1905.  
  1906. /* Expand the cell to cover as many columns as needed */
  1907. while ( aoLocal[i][j+iColspan] !== undefined &&
  1908. aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
  1909. {
  1910. /* Must update the applied array over the rows for the columns */
  1911. for ( k=0 ; k<iRowspan ; k++ )
  1912. {
  1913. aApplied[i+k][j+iColspan] = 1;
  1914. }
  1915. iColspan++;
  1916. }
  1917.  
  1918. /* Do the actual expansion in the DOM */
  1919. $(aoLocal[i][j].cell)
  1920. .attr('rowspan', iRowspan)
  1921. .attr('colspan', iColspan);
  1922. }
  1923. }
  1924. }
  1925. }
  1926.  
  1927.  
  1928. /**
  1929. * Insert the required TR nodes into the table for display
  1930. * @param {object} oSettings dataTables settings object
  1931. * @memberof DataTable#oApi
  1932. */
  1933. function _fnDraw( oSettings )
  1934. {
  1935. /* Provide a pre-callback function which can be used to cancel the draw is false is returned */
  1936. var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
  1937. if ( $.inArray( false, aPreDraw ) !== -1 )
  1938. {
  1939. _fnProcessingDisplay( oSettings, false );
  1940. return;
  1941. }
  1942.  
  1943. var i, iLen, n;
  1944. var anRows = [];
  1945. var iRowCount = 0;
  1946. var asStripeClasses = oSettings.asStripeClasses;
  1947. var iStripes = asStripeClasses.length;
  1948. var iOpenRows = oSettings.aoOpenRows.length;
  1949. var oLang = oSettings.oLanguage;
  1950. var iInitDisplayStart = oSettings.iInitDisplayStart;
  1951. var bServerSide = _fnDataSource( oSettings ) == 'ssp';
  1952. var aiDisplay = oSettings.aiDisplay;
  1953.  
  1954. oSettings.bDrawing = true;
  1955.  
  1956. /* Check and see if we have an initial draw position from state saving */
  1957. if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )
  1958. {
  1959. oSettings._iDisplayStart = bServerSide ?
  1960. iInitDisplayStart :
  1961. iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
  1962. 0 :
  1963. iInitDisplayStart;
  1964.  
  1965. oSettings.iInitDisplayStart = -1;
  1966. }
  1967.  
  1968. var iDisplayStart = oSettings._iDisplayStart;
  1969. var iDisplayEnd = oSettings.fnDisplayEnd();
  1970.  
  1971. /* Server-side processing draw intercept */
  1972. if ( oSettings.bDeferLoading )
  1973. {
  1974. oSettings.bDeferLoading = false;
  1975. oSettings.iDraw++;
  1976. _fnProcessingDisplay( oSettings, false );
  1977. }
  1978. else if ( !bServerSide )
  1979. {
  1980. oSettings.iDraw++;
  1981. }
  1982. else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
  1983. {
  1984. return;
  1985. }
  1986.  
  1987. if ( aiDisplay.length !== 0 )
  1988. {
  1989. var iStart = bServerSide ? 0 : iDisplayStart;
  1990. var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
  1991.  
  1992. for ( var j=iStart ; j<iEnd ; j++ )
  1993. {
  1994. var iDataIndex = aiDisplay[j];
  1995. var aoData = oSettings.aoData[ iDataIndex ];
  1996. if ( aoData.nTr === null )
  1997. {
  1998. _fnCreateTr( oSettings, iDataIndex );
  1999. }
  2000.  
  2001. var nRow = aoData.nTr;
  2002.  
  2003. /* Remove the old striping classes and then add the new one */
  2004. if ( iStripes !== 0 )
  2005. {
  2006. var sStripe = asStripeClasses[ iRowCount % iStripes ];
  2007. if ( aoData._sRowStripe != sStripe )
  2008. {
  2009. $(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
  2010. aoData._sRowStripe = sStripe;
  2011. }
  2012. }
  2013.  
  2014. // Row callback functions - might want to manipulate the row
  2015. // iRowCount and j are not currently documented. Are they at all
  2016. // useful?
  2017. _fnCallbackFire( oSettings, 'aoRowCallback', null,
  2018. [nRow, aoData._aData, iRowCount, j] );
  2019.  
  2020. anRows.push( nRow );
  2021. iRowCount++;
  2022. }
  2023. }
  2024. else
  2025. {
  2026. /* Table is empty - create a row with an empty message in it */
  2027. var sZero = oLang.sZeroRecords;
  2028. if ( oSettings.iDraw == 1 && _fnDataSource( oSettings ) == 'ajax' )
  2029. {
  2030. sZero = oLang.sLoadingRecords;
  2031. }
  2032. else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
  2033. {
  2034. sZero = oLang.sEmptyTable;
  2035. }
  2036.  
  2037. anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )
  2038. .append( $('<td />', {
  2039. 'valign': 'top',
  2040. 'colSpan': _fnVisbleColumns( oSettings ),
  2041. 'class': oSettings.oClasses.sRowEmpty
  2042. } ).html( sZero ) )[0];
  2043. }
  2044.  
  2045. /* Header and footer callbacks */
  2046. _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
  2047. _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
  2048.  
  2049. _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
  2050. _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
  2051.  
  2052. var body = $(oSettings.nTBody);
  2053.  
  2054. body.children().detach();
  2055. body.append( $(anRows) );
  2056.  
  2057. /* Call all required callback functions for the end of a draw */
  2058. _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
  2059.  
  2060. /* Draw is complete, sorting and filtering must be as well */
  2061. oSettings.bSorted = false;
  2062. oSettings.bFiltered = false;
  2063. oSettings.bDrawing = false;
  2064. }
  2065.  
  2066.  
  2067. /**
  2068. * Redraw the table - taking account of the various features which are enabled
  2069. * @param {object} oSettings dataTables settings object
  2070. * @param {boolean} [holdPosition] Keep the current paging position. By default
  2071. * the paging is reset to the first page
  2072. * @memberof DataTable#oApi
  2073. */
  2074. function _fnReDraw( settings, holdPosition )
  2075. {
  2076. var
  2077. features = settings.oFeatures,
  2078. sort = features.bSort,
  2079. filter = features.bFilter;
  2080.  
  2081. if ( sort ) {
  2082. _fnSort( settings );
  2083. }
  2084.  
  2085. if ( filter ) {
  2086. _fnFilterComplete( settings, settings.oPreviousSearch );
  2087. }
  2088. else {
  2089. // No filtering, so we want to just use the display master
  2090. settings.aiDisplay = settings.aiDisplayMaster.slice();
  2091. }
  2092.  
  2093. if ( holdPosition !== true ) {
  2094. settings._iDisplayStart = 0;
  2095. }
  2096.  
  2097. // Let any modules know about the draw hold position state (used by
  2098. // scrolling internally)
  2099. settings._drawHold = holdPosition;
  2100.  
  2101. _fnDraw( settings );
  2102.  
  2103. settings._drawHold = false;
  2104. }
  2105.  
  2106.  
  2107. /**
  2108. * Add the options to the page HTML for the table
  2109. * @param {object} oSettings dataTables settings object
  2110. * @memberof DataTable#oApi
  2111. */
  2112. function _fnAddOptionsHtml ( oSettings )
  2113. {
  2114. var classes = oSettings.oClasses;
  2115. var table = $(oSettings.nTable);
  2116. var holding = $('<div/>').insertBefore( table ); // Holding element for speed
  2117. var features = oSettings.oFeatures;
  2118.  
  2119. // All DataTables are wrapped in a div
  2120. var insert = $('<div/>', {
  2121. id: oSettings.sTableId+'_wrapper',
  2122. 'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)
  2123. } );
  2124.  
  2125. oSettings.nHolding = holding[0];
  2126. oSettings.nTableWrapper = insert[0];
  2127. oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
  2128.  
  2129. /* Loop over the user set positioning and place the elements as needed */
  2130. var aDom = oSettings.sDom.split('');
  2131. var featureNode, cOption, nNewNode, cNext, sAttr, j;
  2132. for ( var i=0 ; i<aDom.length ; i++ )
  2133. {
  2134. featureNode = null;
  2135. cOption = aDom[i];
  2136.  
  2137. if ( cOption == '<' )
  2138. {
  2139. /* New container div */
  2140. nNewNode = $('<div/>')[0];
  2141.  
  2142. /* Check to see if we should append an id and/or a class name to the container */
  2143. cNext = aDom[i+1];
  2144. if ( cNext == "'" || cNext == '"' )
  2145. {
  2146. sAttr = "";
  2147. j = 2;
  2148. while ( aDom[i+j] != cNext )
  2149. {
  2150. sAttr += aDom[i+j];
  2151. j++;
  2152. }
  2153.  
  2154. /* Replace jQuery UI constants @todo depreciated */
  2155. if ( sAttr == "H" )
  2156. {
  2157. sAttr = classes.sJUIHeader;
  2158. }
  2159. else if ( sAttr == "F" )
  2160. {
  2161. sAttr = classes.sJUIFooter;
  2162. }
  2163.  
  2164. /* The attribute can be in the format of "#id.class", "#id" or "class" This logic
  2165. * breaks the string into parts and applies them as needed
  2166. */
  2167. if ( sAttr.indexOf('.') != -1 )
  2168. {
  2169. var aSplit = sAttr.split('.');
  2170. nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
  2171. nNewNode.className = aSplit[1];
  2172. }
  2173. else if ( sAttr.charAt(0) == "#" )
  2174. {
  2175. nNewNode.id = sAttr.substr(1, sAttr.length-1);
  2176. }
  2177. else
  2178. {
  2179. nNewNode.className = sAttr;
  2180. }
  2181.  
  2182. i += j; /* Move along the position array */
  2183. }
  2184.  
  2185. insert.append( nNewNode );
  2186. insert = $(nNewNode);
  2187. }
  2188. else if ( cOption == '>' )
  2189. {
  2190. /* End container div */
  2191. insert = insert.parent();
  2192. }
  2193. // @todo Move options into their own plugins?
  2194. else if ( cOption == 'l' && features.bPaginate && features.bLengthChange )
  2195. {
  2196. /* Length */
  2197. featureNode = _fnFeatureHtmlLength( oSettings );
  2198. }
  2199. else if ( cOption == 'f' && features.bFilter )
  2200. {
  2201. /* Filter */
  2202. featureNode = _fnFeatureHtmlFilter( oSettings );
  2203. }
  2204. else if ( cOption == 'r' && features.bProcessing )
  2205. {
  2206. /* pRocessing */
  2207. featureNode = _fnFeatureHtmlProcessing( oSettings );
  2208. }
  2209. else if ( cOption == 't' )
  2210. {
  2211. /* Table */
  2212. featureNode = _fnFeatureHtmlTable( oSettings );
  2213. }
  2214. else if ( cOption == 'i' && features.bInfo )
  2215. {
  2216. /* Info */
  2217. featureNode = _fnFeatureHtmlInfo( oSettings );
  2218. }
  2219. else if ( cOption == 'p' && features.bPaginate )
  2220. {
  2221. /* Pagination */
  2222. featureNode = _fnFeatureHtmlPaginate( oSettings );
  2223. }
  2224. else if ( DataTable.ext.feature.length !== 0 )
  2225. {
  2226. /* Plug-in features */
  2227. var aoFeatures = DataTable.ext.feature;
  2228. for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
  2229. {
  2230. if ( cOption == aoFeatures[k].cFeature )
  2231. {
  2232. featureNode = aoFeatures[k].fnInit( oSettings );
  2233. break;
  2234. }
  2235. }
  2236. }
  2237.  
  2238. /* Add to the 2D features array */
  2239. if ( featureNode )
  2240. {
  2241. var aanFeatures = oSettings.aanFeatures;
  2242.  
  2243. if ( ! aanFeatures[cOption] )
  2244. {
  2245. aanFeatures[cOption] = [];
  2246. }
  2247.  
  2248. aanFeatures[cOption].push( featureNode );
  2249. insert.append( featureNode );
  2250. }
  2251. }
  2252.  
  2253. /* Built our DOM structure - replace the holding div with what we want */
  2254. holding.replaceWith( insert );
  2255. }
  2256.  
  2257.  
  2258. /**
  2259. * Use the DOM source to create up an array of header cells. The idea here is to
  2260. * create a layout grid (array) of rows x columns, which contains a reference
  2261. * to the cell that that point in the grid (regardless of col/rowspan), such that
  2262. * any column / row could be removed and the new grid constructed
  2263. * @param array {object} aLayout Array to store the calculated layout in
  2264. * @param {node} nThead The header/footer element for the table
  2265. * @memberof DataTable#oApi
  2266. */
  2267. function _fnDetectHeader ( aLayout, nThead )
  2268. {
  2269. var nTrs = $(nThead).children('tr');
  2270. var nTr, nCell;
  2271. var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
  2272. var bUnique;
  2273. var fnShiftCol = function ( a, i, j ) {
  2274. var k = a[i];
  2275. while ( k[j] ) {
  2276. j++;
  2277. }
  2278. return j;
  2279. };
  2280.  
  2281. aLayout.splice( 0, aLayout.length );
  2282.  
  2283. /* We know how many rows there are in the layout - so prep it */
  2284. for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
  2285. {
  2286. aLayout.push( [] );
  2287. }
  2288.  
  2289. /* Calculate a layout array */
  2290. for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
  2291. {
  2292. nTr = nTrs[i];
  2293. iColumn = 0;
  2294.  
  2295. /* For every cell in the row... */
  2296. nCell = nTr.firstChild;
  2297. while ( nCell ) {
  2298. if ( nCell.nodeName.toUpperCase() == "TD" ||
  2299. nCell.nodeName.toUpperCase() == "TH" )
  2300. {
  2301. /* Get the col and rowspan attributes from the DOM and sanitise them */
  2302. iColspan = nCell.getAttribute('colspan') * 1;
  2303. iRowspan = nCell.getAttribute('rowspan') * 1;
  2304. iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
  2305. iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
  2306.  
  2307. /* There might be colspan cells already in this row, so shift our target
  2308. * accordingly
  2309. */
  2310. iColShifted = fnShiftCol( aLayout, i, iColumn );
  2311.  
  2312. /* Cache calculation for unique columns */
  2313. bUnique = iColspan === 1 ? true : false;
  2314.  
  2315. /* If there is col / rowspan, copy the information into the layout grid */
  2316. for ( l=0 ; l<iColspan ; l++ )
  2317. {
  2318. for ( k=0 ; k<iRowspan ; k++ )
  2319. {
  2320. aLayout[i+k][iColShifted+l] = {
  2321. "cell": nCell,
  2322. "unique": bUnique
  2323. };
  2324. aLayout[i+k].nTr = nTr;
  2325. }
  2326. }
  2327. }
  2328. nCell = nCell.nextSibling;
  2329. }
  2330. }
  2331. }
  2332.  
  2333.  
  2334. /**
  2335. * Get an array of unique th elements, one for each column
  2336. * @param {object} oSettings dataTables settings object
  2337. * @param {node} nHeader automatically detect the layout from this node - optional
  2338. * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
  2339. * @returns array {node} aReturn list of unique th's
  2340. * @memberof DataTable#oApi
  2341. */
  2342. function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
  2343. {
  2344. var aReturn = [];
  2345. if ( !aLayout )
  2346. {
  2347. aLayout = oSettings.aoHeader;
  2348. if ( nHeader )
  2349. {
  2350. aLayout = [];
  2351. _fnDetectHeader( aLayout, nHeader );
  2352. }
  2353. }
  2354.  
  2355. for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
  2356. {
  2357. for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
  2358. {
  2359. if ( aLayout[i][j].unique &&
  2360. (!aReturn[j] || !oSettings.bSortCellsTop) )
  2361. {
  2362. aReturn[j] = aLayout[i][j].cell;
  2363. }
  2364. }
  2365. }
  2366.  
  2367. return aReturn;
  2368. }
  2369.  
  2370.  
  2371.  
  2372. /**
  2373. * Create an Ajax call based on the table's settings, taking into account that
  2374. * parameters can have multiple forms, and backwards compatibility.
  2375. *
  2376. * @param {object} oSettings dataTables settings object
  2377. * @param {array} data Data to send to the server, required by
  2378. * DataTables - may be augmented by developer callbacks
  2379. * @param {function} fn Callback function to run when data is obtained
  2380. */
  2381. function _fnBuildAjax( oSettings, data, fn )
  2382. {
  2383. // Compatibility with 1.9-, allow fnServerData and event to manipulate
  2384. _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
  2385.  
  2386. // Convert to object based for 1.10+ if using the old array scheme which can
  2387. // come from server-side processing or serverParams
  2388. if ( data && $.isArray(data) ) {
  2389. var tmp = {};
  2390. var rbracket = /(.*?)\[\]$/;
  2391.  
  2392. $.each( data, function (key, val) {
  2393. var match = val.name.match(rbracket);
  2394.  
  2395. if ( match ) {
  2396. // Support for arrays
  2397. var name = match[0];
  2398.  
  2399. if ( ! tmp[ name ] ) {
  2400. tmp[ name ] = [];
  2401. }
  2402. tmp[ name ].push( val.value );
  2403. }
  2404. else {
  2405. tmp[val.name] = val.value;
  2406. }
  2407. } );
  2408. data = tmp;
  2409. }
  2410.  
  2411. var ajaxData;
  2412. var ajax = oSettings.ajax;
  2413. var instance = oSettings.oInstance;
  2414.  
  2415. if ( $.isPlainObject( ajax ) && ajax.data )
  2416. {
  2417. ajaxData = ajax.data;
  2418.  
  2419. var newData = $.isFunction( ajaxData ) ?
  2420. ajaxData( data ) : // fn can manipulate data or return an object
  2421. ajaxData; // object or array to merge
  2422.  
  2423. // If the function returned an object, use that alone
  2424. data = $.isFunction( ajaxData ) && newData ?
  2425. newData :
  2426. $.extend( true, data, newData );
  2427.  
  2428. // Remove the data property as we've resolved it already and don't want
  2429. // jQuery to do it again (it is restored at the end of the function)
  2430. delete ajax.data;
  2431. }
  2432.  
  2433. var baseAjax = {
  2434. "data": data,
  2435. "success": function (json) {
  2436. var error = json.error || json.sError;
  2437. if ( error ) {
  2438. oSettings.oApi._fnLog( oSettings, 0, error );
  2439. }
  2440.  
  2441. oSettings.json = json;
  2442. _fnCallbackFire( oSettings, null, 'xhr', [oSettings, json] );
  2443. fn( json );
  2444. },
  2445. "dataType": "json",
  2446. "cache": false,
  2447. "type": oSettings.sServerMethod,
  2448. "error": function (xhr, error, thrown) {
  2449. var log = oSettings.oApi._fnLog;
  2450.  
  2451. if ( error == "parsererror" ) {
  2452. log( oSettings, 0, 'Invalid JSON response', 1 );
  2453. }
  2454. else if ( xhr.readyState === 4 ) {
  2455. log( oSettings, 0, 'Ajax error', 7 );
  2456. }
  2457.  
  2458. _fnProcessingDisplay( oSettings, false );
  2459. }
  2460. };
  2461.  
  2462. // Store the data submitted for the API
  2463. oSettings.oAjaxData = data;
  2464.  
  2465. // Allow plug-ins and external processes to modify the data
  2466. _fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );
  2467.  
  2468. if ( oSettings.fnServerData )
  2469. {
  2470. // DataTables 1.9- compatibility
  2471. oSettings.fnServerData.call( instance,
  2472. oSettings.sAjaxSource,
  2473. $.map( data, function (val, key) { // Need to convert back to 1.9 trad format
  2474. return { name: key, value: val };
  2475. } ),
  2476. fn,
  2477. oSettings
  2478. );
  2479. }
  2480. else if ( oSettings.sAjaxSource || typeof ajax === 'string' )
  2481. {
  2482. // DataTables 1.9- compatibility
  2483. oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
  2484. url: ajax || oSettings.sAjaxSource
  2485. } ) );
  2486. }
  2487. else if ( $.isFunction( ajax ) )
  2488. {
  2489. // Is a function - let the caller define what needs to be done
  2490. oSettings.jqXHR = ajax.call( instance, data, fn, oSettings );
  2491. }
  2492. else
  2493. {
  2494. // Object to extend the base settings
  2495. oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );
  2496.  
  2497. // Restore for next time around
  2498. ajax.data = ajaxData;
  2499. }
  2500. }
  2501.  
  2502.  
  2503. /**
  2504. * Update the table using an Ajax call
  2505. * @param {object} settings dataTables settings object
  2506. * @returns {boolean} Block the table drawing or not
  2507. * @memberof DataTable#oApi
  2508. */
  2509. function _fnAjaxUpdate( settings )
  2510. {
  2511. if ( settings.bAjaxDataGet ) {
  2512. settings.iDraw++;
  2513. _fnProcessingDisplay( settings, true );
  2514.  
  2515. _fnBuildAjax(
  2516. settings,
  2517. _fnAjaxParameters( settings ),
  2518. function(json) {
  2519. _fnAjaxUpdateDraw( settings, json );
  2520. }
  2521. );
  2522.  
  2523. return false;
  2524. }
  2525. return true;
  2526. }
  2527.  
  2528.  
  2529. /**
  2530. * Build up the parameters in an object needed for a server-side processing
  2531. * request. Note that this is basically done twice, is different ways - a modern
  2532. * method which is used by default in DataTables 1.10 which uses objects and
  2533. * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
  2534. * the sAjaxSource option is used in the initialisation, or the legacyAjax
  2535. * option is set.
  2536. * @param {object} oSettings dataTables settings object
  2537. * @returns {bool} block the table drawing or not
  2538. * @memberof DataTable#oApi
  2539. */
  2540. function _fnAjaxParameters( settings )
  2541. {
  2542. var
  2543. columns = settings.aoColumns,
  2544. columnCount = columns.length,
  2545. features = settings.oFeatures,
  2546. preSearch = settings.oPreviousSearch,
  2547. preColSearch = settings.aoPreSearchCols,
  2548. i, data = [], dataProp, column, columnSearch,
  2549. sort = _fnSortFlatten( settings ),
  2550. displayStart = settings._iDisplayStart,
  2551. displayLength = features.bPaginate !== false ?
  2552. settings._iDisplayLength :
  2553. -1;
  2554.  
  2555. var param = function ( name, value ) {
  2556. data.push( { 'name': name, 'value': value } );
  2557. };
  2558.  
  2559. // DataTables 1.9- compatible method
  2560. param( 'sEcho', settings.iDraw );
  2561. param( 'iColumns', columnCount );
  2562. param( 'sColumns', _pluck( columns, 'sName' ).join(',') );
  2563. param( 'iDisplayStart', displayStart );
  2564. param( 'iDisplayLength', displayLength );
  2565.  
  2566. // DataTables 1.10+ method
  2567. var d = {
  2568. draw: settings.iDraw,
  2569. columns: [],
  2570. order: [],
  2571. start: displayStart,
  2572. length: displayLength,
  2573. search: {
  2574. value: preSearch.sSearch,
  2575. regex: preSearch.bRegex
  2576. }
  2577. };
  2578.  
  2579. for ( i=0 ; i<columnCount ; i++ ) {
  2580. column = columns[i];
  2581. columnSearch = preColSearch[i];
  2582. dataProp = typeof column.mData=="function" ? 'function' : column.mData ;
  2583.  
  2584. d.columns.push( {
  2585. data: dataProp,
  2586. name: column.sName,
  2587. searchable: column.bSearchable,
  2588. orderable: column.bSortable,
  2589. search: {
  2590. value: columnSearch.sSearch,
  2591. regex: columnSearch.bRegex
  2592. }
  2593. } );
  2594.  
  2595. param( "mDataProp_"+i, dataProp );
  2596.  
  2597. if ( features.bFilter ) {
  2598. param( 'sSearch_'+i, columnSearch.sSearch );
  2599. param( 'bRegex_'+i, columnSearch.bRegex );
  2600. param( 'bSearchable_'+i, column.bSearchable );
  2601. }
  2602.  
  2603. if ( features.bSort ) {
  2604. param( 'bSortable_'+i, column.bSortable );
  2605. }
  2606. }
  2607.  
  2608. if ( features.bFilter ) {
  2609. param( 'sSearch', preSearch.sSearch );
  2610. param( 'bRegex', preSearch.bRegex );
  2611. }
  2612.  
  2613. if ( features.bSort ) {
  2614. $.each( sort, function ( i, val ) {
  2615. d.order.push( { column: val.col, dir: val.dir } );
  2616.  
  2617. param( 'iSortCol_'+i, val.col );
  2618. param( 'sSortDir_'+i, val.dir );
  2619. } );
  2620.  
  2621. param( 'iSortingCols', sort.length );
  2622. }
  2623.  
  2624. // If the legacy.ajax parameter is null, then we automatically decide which
  2625. // form to use, based on sAjaxSource
  2626. var legacy = DataTable.ext.legacy.ajax;
  2627. if ( legacy === null ) {
  2628. return settings.sAjaxSource ? data : d;
  2629. }
  2630.  
  2631. // Otherwise, if legacy has been specified then we use that to decide on the
  2632. // form
  2633. return legacy ? data : d;
  2634. }
  2635.  
  2636.  
  2637. /**
  2638. * Data the data from the server (nuking the old) and redraw the table
  2639. * @param {object} oSettings dataTables settings object
  2640. * @param {object} json json data return from the server.
  2641. * @param {string} json.sEcho Tracking flag for DataTables to match requests
  2642. * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
  2643. * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
  2644. * @param {array} json.aaData The data to display on this page
  2645. * @param {string} [json.sColumns] Column ordering (sName, comma separated)
  2646. * @memberof DataTable#oApi
  2647. */
  2648. function _fnAjaxUpdateDraw ( settings, json )
  2649. {
  2650. // v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
  2651. // Support both
  2652. var compat = function ( old, modern ) {
  2653. return json[old] !== undefined ? json[old] : json[modern];
  2654. };
  2655.  
  2656. var draw = compat( 'sEcho', 'draw' );
  2657. var recordsTotal = compat( 'iTotalRecords', 'recordsTotal' );
  2658. var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );
  2659.  
  2660. if ( draw ) {
  2661. // Protect against out of sequence returns
  2662. if ( draw*1 < settings.iDraw ) {
  2663. return;
  2664. }
  2665. settings.iDraw = draw * 1;
  2666. }
  2667.  
  2668. _fnClearTable( settings );
  2669. settings._iRecordsTotal = parseInt(recordsTotal, 10);
  2670. settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
  2671.  
  2672. var data = _fnAjaxDataSrc( settings, json );
  2673. for ( var i=0, ien=data.length ; i<ien ; i++ ) {
  2674. _fnAddData( settings, data[i] );
  2675. }
  2676. settings.aiDisplay = settings.aiDisplayMaster.slice();
  2677.  
  2678. settings.bAjaxDataGet = false;
  2679. _fnDraw( settings );
  2680.  
  2681. if ( ! settings._bInitComplete ) {
  2682. _fnInitComplete( settings, json );
  2683. }
  2684.  
  2685. settings.bAjaxDataGet = true;
  2686. _fnProcessingDisplay( settings, false );
  2687. }
  2688.  
  2689.  
  2690. /**
  2691. * Get the data from the JSON data source to use for drawing a table. Using
  2692. * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
  2693. * source object, or from a processing function.
  2694. * @param {object} oSettings dataTables settings object
  2695. * @param {object} json Data source object / array from the server
  2696. * @return {array} Array of data to use
  2697. */
  2698. function _fnAjaxDataSrc ( oSettings, json )
  2699. {
  2700. var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
  2701. oSettings.ajax.dataSrc :
  2702. oSettings.sAjaxDataProp; // Compatibility with 1.9-.
  2703.  
  2704. // Compatibility with 1.9-. In order to read from aaData, check if the
  2705. // default has been changed, if not, check for aaData
  2706. if ( dataSrc === 'data' ) {
  2707. return json.aaData || json[dataSrc];
  2708. }
  2709.  
  2710. return dataSrc !== "" ?
  2711. _fnGetObjectDataFn( dataSrc )( json ) :
  2712. json;
  2713. }
  2714.  
  2715.  
  2716. /**
  2717. * Generate the node required for filtering text
  2718. * @returns {node} Filter control element
  2719. * @param {object} oSettings dataTables settings object
  2720. * @memberof DataTable#oApi
  2721. */
  2722. function _fnFeatureHtmlFilter ( settings )
  2723. {
  2724. var classes = settings.oClasses;
  2725. var tableId = settings.sTableId;
  2726. var language = settings.oLanguage;
  2727. var previousSearch = settings.oPreviousSearch;
  2728. var features = settings.aanFeatures;
  2729. var input = '';
  2730.  
  2731. var str = language.sSearch;
  2732. str = str.match(/_INPUT_/) ?
  2733. str.replace('_INPUT_', input) :
  2734. str+input;
  2735.  
  2736. var filter = $('<div/>', {
  2737. 'id': ! features.f ? tableId+'_filter' : null,
  2738. 'class': classes.sFilter
  2739. } )
  2740. .append( $('<label/>' ).append( str ) );
  2741.  
  2742.  
  2743.  
  2744.  
  2745. }
  2746.  
  2747. /**
  2748. * Filter the table using both the global filter and column based filtering
  2749. * @param {object} oSettings dataTables settings object
  2750. * @param {object} oSearch search information
  2751. * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
  2752. * @memberof DataTable#oApi
  2753. */
  2754. function _fnFilterComplete ( oSettings, oInput, iForce )
  2755. {
  2756. var oPrevSearch = oSettings.oPreviousSearch;
  2757. var aoPrevSearch = oSettings.aoPreSearchCols;
  2758. var fnSaveFilter = function ( oFilter ) {
  2759. /* Save the filtering values */
  2760. oPrevSearch.sSearch = oFilter.sSearch;
  2761. oPrevSearch.bRegex = oFilter.bRegex;
  2762. oPrevSearch.bSmart = oFilter.bSmart;
  2763. oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
  2764. };
  2765. var fnRegex = function ( o ) {
  2766. // Backwards compatibility with the bEscapeRegex option
  2767. return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
  2768. };
  2769.  
  2770. // Resolve any column types that are unknown due to addition or invalidation
  2771. // @todo As per sort - can this be moved into an event handler?
  2772. _fnColumnTypes( oSettings );
  2773.  
  2774. /* In server-side processing all filtering is done by the server, so no point hanging around here */
  2775. if ( _fnDataSource( oSettings ) != 'ssp' )
  2776. {
  2777. /* Global filter */
  2778. _fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );
  2779. fnSaveFilter( oInput );
  2780.  
  2781. /* Now do the individual column filter */
  2782. for ( var i=0 ; i<aoPrevSearch.length ; i++ )
  2783. {
  2784. _fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
  2785. aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
  2786. }
  2787.  
  2788. /* Custom filtering */
  2789. _fnFilterCustom( oSettings );
  2790. }
  2791. else
  2792. {
  2793. fnSaveFilter( oInput );
  2794. }
  2795.  
  2796. /* Tell the draw function we have been filtering */
  2797. oSettings.bFiltered = true;
  2798. _fnCallbackFire( oSettings, null, 'search', [oSettings] );
  2799. }
  2800.  
  2801.  
  2802. /**
  2803. * Apply custom filtering functions
  2804. * @param {object} oSettings dataTables settings object
  2805. * @memberof DataTable#oApi
  2806. */
  2807. function _fnFilterCustom( settings )
  2808. {
  2809. var filters = DataTable.ext.search;
  2810. var displayRows = settings.aiDisplay;
  2811. var row, rowIdx;
  2812.  
  2813. for ( var i=0, ien=filters.length ; i<ien ; i++ ) {
  2814. var rows = [];
  2815.  
  2816. // Loop over each row and see if it should be included
  2817. for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {
  2818. rowIdx = displayRows[ j ];
  2819. row = settings.aoData[ rowIdx ];
  2820.  
  2821. if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {
  2822. rows.push( rowIdx );
  2823. }
  2824. }
  2825.  
  2826. // So the array reference doesn't break set the results into the
  2827. // existing array
  2828. displayRows.length = 0;
  2829. displayRows.push.apply( displayRows, rows );
  2830. }
  2831. }
  2832.  
  2833.  
  2834. /**
  2835. * Filter the table on a per-column basis
  2836. * @param {object} oSettings dataTables settings object
  2837. * @param {string} sInput string to filter on
  2838. * @param {int} iColumn column to filter
  2839. * @param {bool} bRegex treat search string as a regular expression or not
  2840. * @param {bool} bSmart use smart filtering or not
  2841. * @param {bool} bCaseInsensitive Do case insenstive matching or not
  2842. * @memberof DataTable#oApi
  2843. */
  2844. function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
  2845. {
  2846. if ( searchStr === '' ) {
  2847. return;
  2848. }
  2849.  
  2850. var data;
  2851. var display = settings.aiDisplay;
  2852. var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
  2853.  
  2854. for ( var i=display.length-1 ; i>=0 ; i-- ) {
  2855. data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
  2856.  
  2857. if ( ! rpSearch.test( data ) ) {
  2858. display.splice( i, 1 );
  2859. }
  2860. }
  2861. }
  2862.  
  2863.  
  2864. /**
  2865. * Filter the data table based on user input and draw the table
  2866. * @param {object} settings dataTables settings object
  2867. * @param {string} input string to filter on
  2868. * @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
  2869. * @param {bool} regex treat as a regular expression or not
  2870. * @param {bool} smart perform smart filtering or not
  2871. * @param {bool} caseInsensitive Do case insenstive matching or not
  2872. * @memberof DataTable#oApi
  2873. */
  2874. function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
  2875. {
  2876. var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );
  2877. var prevSearch = settings.oPreviousSearch.sSearch;
  2878. var displayMaster = settings.aiDisplayMaster;
  2879. var display, invalidated, i;
  2880.  
  2881. // Need to take account of custom filtering functions - always filter
  2882. if ( DataTable.ext.search.length !== 0 ) {
  2883. force = true;
  2884. }
  2885.  
  2886. // Check if any of the rows were invalidated
  2887. invalidated = _fnFilterData( settings );
  2888.  
  2889. // If the input is blank - we just want the full data set
  2890. if ( input.length <= 0 ) {
  2891. settings.aiDisplay = displayMaster.slice();
  2892. }
  2893. else {
  2894. // New search - start from the master array
  2895. if ( invalidated ||
  2896. force ||
  2897. prevSearch.length > input.length ||
  2898. input.indexOf(prevSearch) !== 0 ||
  2899. settings.bSorted // On resort, the display master needs to be
  2900. // re-filtered since indexes will have changed
  2901. ) {
  2902. settings.aiDisplay = displayMaster.slice();
  2903. }
  2904.  
  2905. // Search the display array
  2906. display = settings.aiDisplay;
  2907.  
  2908. for ( i=display.length-1 ; i>=0 ; i-- ) {
  2909. if ( ! rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
  2910. display.splice( i, 1 );
  2911. }
  2912. }
  2913. }
  2914. }
  2915.  
  2916.  
  2917. /**
  2918. * Build a regular expression object suitable for searching a table
  2919. * @param {string} sSearch string to search for
  2920. * @param {bool} bRegex treat as a regular expression or not
  2921. * @param {bool} bSmart perform smart filtering or not
  2922. * @param {bool} bCaseInsensitive Do case insensitive matching or not
  2923. * @returns {RegExp} constructed object
  2924. * @memberof DataTable#oApi
  2925. */
  2926. function _fnFilterCreateSearch( search, regex, smart, caseInsensitive )
  2927. {
  2928. search = regex ?
  2929. search :
  2930. _fnEscapeRegex( search );
  2931.  
  2932. if ( smart ) {
  2933. /* For smart filtering we want to allow the search to work regardless of
  2934. * word order. We also want double quoted text to be preserved, so word
  2935. * order is important - a la google. So this is what we want to
  2936. * generate:
  2937. *
  2938. * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
  2939. */
  2940. var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || '', function ( word ) {
  2941. if ( word.charAt(0) === '"' ) {
  2942. var m = word.match( /^"(.*)"$/ );
  2943. word = m ? m[1] : word;
  2944. }
  2945.  
  2946. return word.replace('"', '');
  2947. } );
  2948.  
  2949. search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';
  2950. }
  2951.  
  2952. return new RegExp( search, caseInsensitive ? 'i' : '' );
  2953. }
  2954.  
  2955.  
  2956. /**
  2957. * Escape a string such that it can be used in a regular expression
  2958. * @param {string} sVal string to escape
  2959. * @returns {string} escaped string
  2960. * @memberof DataTable#oApi
  2961. */
  2962. function _fnEscapeRegex ( sVal )
  2963. {
  2964. return sVal.replace( _re_escape_regex, '\\$1' );
  2965. }
  2966.  
  2967.  
  2968.  
  2969. var __filter_div = $('<div>')[0];
  2970. var __filter_div_textContent = __filter_div.textContent !== undefined;
  2971.  
  2972. // Update the filtering data for each row if needed (by invalidation or first run)
  2973. function _fnFilterData ( settings )
  2974. {
  2975. var columns = settings.aoColumns;
  2976. var column;
  2977. var i, j, ien, jen, filterData, cellData, row;
  2978. var fomatters = DataTable.ext.type.search;
  2979. var wasInvalidated = false;
  2980.  
  2981. for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
  2982. row = settings.aoData[i];
  2983.  
  2984. if ( ! row._aFilterData ) {
  2985. filterData = [];
  2986.  
  2987. for ( j=0, jen=columns.length ; j<jen ; j++ ) {
  2988. column = columns[j];
  2989.  
  2990. if ( column.bSearchable ) {
  2991. cellData = _fnGetCellData( settings, i, j, 'filter' );
  2992.  
  2993. if ( fomatters[ column.sType ] ) {
  2994. cellData = fomatters[ column.sType ]( cellData );
  2995. }
  2996.  
  2997. // Search in DataTables 1.10 is string based. In 1.11 this
  2998. // should be altered to also allow strict type checking.
  2999. if ( cellData === null ) {
  3000. cellData = '';
  3001. }
  3002.  
  3003. if ( typeof cellData !== 'string' && cellData.toString ) {
  3004. cellData = cellData.toString();
  3005. }
  3006. }
  3007. else {
  3008. cellData = '';
  3009. }
  3010.  
  3011. // If it looks like there is an HTML entity in the string,
  3012. // attempt to decode it so sorting works as expected. Note that
  3013. // we could use a single line of jQuery to do this, but the DOM
  3014. // method used here is much faster http://jsperf.com/html-decode
  3015. if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {
  3016. __filter_div.innerHTML = cellData;
  3017. cellData = __filter_div_textContent ?
  3018. __filter_div.textContent :
  3019. __filter_div.innerText;
  3020. }
  3021.  
  3022. if ( cellData.replace ) {
  3023. cellData = cellData.replace(/[\r\n]/g, '');
  3024. }
  3025.  
  3026. filterData.push( cellData );
  3027. }
  3028.  
  3029. row._aFilterData = filterData;
  3030. row._sFilterRow = filterData.join(' ');
  3031. wasInvalidated = true;
  3032. }
  3033. }
  3034.  
  3035. return wasInvalidated;
  3036. }
  3037.  
  3038.  
  3039. /**
  3040. * Convert from the internal Hungarian notation to camelCase for external
  3041. * interaction
  3042. * @param {object} obj Object to convert
  3043. * @returns {object} Inverted object
  3044. * @memberof DataTable#oApi
  3045. */
  3046. function _fnSearchToCamel ( obj )
  3047. {
  3048. return {
  3049. search: obj.sSearch,
  3050. smart: obj.bSmart,
  3051. regex: obj.bRegex,
  3052. caseInsensitive: obj.bCaseInsensitive
  3053. };
  3054. }
  3055.  
  3056.  
  3057.  
  3058. /**
  3059. * Convert from camelCase notation to the internal Hungarian. We could use the
  3060. * Hungarian convert function here, but this is cleaner
  3061. * @param {object} obj Object to convert
  3062. * @returns {object} Inverted object
  3063. * @memberof DataTable#oApi
  3064. */
  3065. function _fnSearchToHung ( obj )
  3066. {
  3067. return {
  3068. sSearch: obj.search,
  3069. bSmart: obj.smart,
  3070. bRegex: obj.regex,
  3071. bCaseInsensitive: obj.caseInsensitive
  3072. };
  3073. }
  3074.  
  3075. /**
  3076. * Generate the node required for the info display
  3077. * @param {object} oSettings dataTables settings object
  3078. * @returns {node} Information element
  3079. * @memberof DataTable#oApi
  3080. */
  3081. function _fnFeatureHtmlInfo ( settings )
  3082. {
  3083. var
  3084. tid = settings.sTableId,
  3085. nodes = settings.aanFeatures.i,
  3086. n = $('<div/>', {
  3087. 'class': settings.oClasses.sInfo,
  3088. 'id': ! nodes ? tid+'_info' : null
  3089. } );
  3090.  
  3091. if ( ! nodes ) {
  3092. // Update display on each draw
  3093. settings.aoDrawCallback.push( {
  3094. "fn": _fnUpdateInfo,
  3095. "sName": "information"
  3096. } );
  3097.  
  3098. n
  3099. .attr( 'role', 'status' )
  3100. .attr( 'aria-live', 'polite' );
  3101.  
  3102. // Table is described by our info div
  3103. $(settings.nTable).attr( 'aria-describedby', tid+'_info' );
  3104. }
  3105.  
  3106. return n[0];
  3107. }
  3108.  
  3109.  
  3110. /**
  3111. * Update the information elements in the display
  3112. * @param {object} settings dataTables settings object
  3113. * @memberof DataTable#oApi
  3114. */
  3115. function _fnUpdateInfo ( settings )
  3116. {
  3117. /* Show information about the table */
  3118. var nodes = settings.aanFeatures.i;
  3119. if ( nodes.length === 0 ) {
  3120. return;
  3121. }
  3122.  
  3123. var
  3124. lang = settings.oLanguage,
  3125. start = settings._iDisplayStart+1,
  3126. end = settings.fnDisplayEnd(),
  3127. max = settings.fnRecordsTotal(),
  3128. total = settings.fnRecordsDisplay(),
  3129. out = total ?
  3130. lang.sInfo :
  3131. lang.sInfoEmpty;
  3132.  
  3133. if ( total !== max ) {
  3134. /* Record set after filtering */
  3135. out += ' ' + lang.sInfoFiltered;
  3136. }
  3137.  
  3138. // Convert the macros
  3139. out += lang.sInfoPostFix;
  3140. out = _fnInfoMacros( settings, out );
  3141.  
  3142. var callback = lang.fnInfoCallback;
  3143. if ( callback !== null ) {
  3144. out = callback.call( settings.oInstance,
  3145. settings, start, end, max, total, out
  3146. );
  3147. }
  3148.  
  3149. $(nodes).html( out );
  3150. }
  3151.  
  3152.  
  3153. function _fnInfoMacros ( settings, str )
  3154. {
  3155. // When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
  3156. // internally
  3157. var
  3158. formatter = settings.fnFormatNumber,
  3159. start = settings._iDisplayStart+1,
  3160. len = settings._iDisplayLength,
  3161. vis = settings.fnRecordsDisplay(),
  3162. all = len === -1;
  3163.  
  3164. return str.
  3165. replace(/_START_/g, formatter.call( settings, start ) ).
  3166. replace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ).
  3167. replace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ).
  3168. replace(/_TOTAL_/g, formatter.call( settings, vis ) ).
  3169. replace(/_PAGE_/g, formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).
  3170. replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );
  3171. }
  3172.  
  3173.  
  3174.  
  3175. /**
  3176. * Draw the table for the first time, adding all required features
  3177. * @param {object} settings dataTables settings object
  3178. * @memberof DataTable#oApi
  3179. */
  3180. function _fnInitialise ( settings )
  3181. {
  3182. var i, iLen, iAjaxStart=settings.iInitDisplayStart;
  3183. var columns = settings.aoColumns, column;
  3184. var features = settings.oFeatures;
  3185.  
  3186. /* Ensure that the table data is fully initialised */
  3187. if ( ! settings.bInitialised ) {
  3188. setTimeout( function(){ _fnInitialise( settings ); }, 200 );
  3189. return;
  3190. }
  3191.  
  3192. /* Show the display HTML options */
  3193. _fnAddOptionsHtml( settings );
  3194.  
  3195. /* Build and draw the header / footer for the table */
  3196. _fnBuildHead( settings );
  3197. _fnDrawHead( settings, settings.aoHeader );
  3198. _fnDrawHead( settings, settings.aoFooter );
  3199.  
  3200. /* Okay to show that something is going on now */
  3201. _fnProcessingDisplay( settings, true );
  3202.  
  3203. /* Calculate sizes for columns */
  3204. if ( features.bAutoWidth ) {
  3205. _fnCalculateColumnWidths( settings );
  3206. }
  3207.  
  3208. for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
  3209. column = columns[i];
  3210.  
  3211. if ( column.sWidth ) {
  3212. column.nTh.style.width = _fnStringToCss( column.sWidth );
  3213. }
  3214. }
  3215.  
  3216. // If there is default sorting required - let's do it. The sort function
  3217. // will do the drawing for us. Otherwise we draw the table regardless of the
  3218. // Ajax source - this allows the table to look initialised for Ajax sourcing
  3219. // data (show 'loading' message possibly)
  3220. _fnReDraw( settings );
  3221.  
  3222. // Server-side processing init complete is done by _fnAjaxUpdateDraw
  3223. var dataSrc = _fnDataSource( settings );
  3224. if ( dataSrc != 'ssp' ) {
  3225. // if there is an ajax source load the data
  3226. if ( dataSrc == 'ajax' ) {
  3227. _fnBuildAjax( settings, [], function(json) {
  3228. var aData = _fnAjaxDataSrc( settings, json );
  3229.  
  3230. // Got the data - add it to the table
  3231. for ( i=0 ; i<aData.length ; i++ ) {
  3232. _fnAddData( settings, aData[i] );
  3233. }
  3234.  
  3235. // Reset the init display for cookie saving. We've already done
  3236. // a filter, and therefore cleared it before. So we need to make
  3237. // it appear 'fresh'
  3238. settings.iInitDisplayStart = iAjaxStart;
  3239.  
  3240. _fnReDraw( settings );
  3241.  
  3242. _fnProcessingDisplay( settings, false );
  3243. _fnInitComplete( settings, json );
  3244. }, settings );
  3245. }
  3246. else {
  3247. _fnProcessingDisplay( settings, false );
  3248. _fnInitComplete( settings );
  3249. }
  3250. }
  3251. }
  3252.  
  3253.  
  3254. /**
  3255. * Draw the table for the first time, adding all required features
  3256. * @param {object} oSettings dataTables settings object
  3257. * @param {object} [json] JSON from the server that completed the table, if using Ajax source
  3258. * with client-side processing (optional)
  3259. * @memberof DataTable#oApi
  3260. */
  3261. function _fnInitComplete ( settings, json )
  3262. {
  3263. settings._bInitComplete = true;
  3264.  
  3265. // On an Ajax load we now have data and therefore want to apply the column
  3266. // sizing
  3267. if ( json ) {
  3268. _fnAdjustColumnSizing( settings );
  3269. }
  3270.  
  3271. _fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );
  3272. }
  3273.  
  3274.  
  3275. function _fnLengthChange ( settings, val )
  3276. {
  3277. var len = parseInt( val, 10 );
  3278. settings._iDisplayLength = len;
  3279.  
  3280. _fnLengthOverflow( settings );
  3281.  
  3282. // Fire length change event
  3283. _fnCallbackFire( settings, null, 'length', [settings, len] );
  3284. }
  3285.  
  3286.  
  3287. /**
  3288. * Generate the node required for user display length changing
  3289. * @param {object} settings dataTables settings object
  3290. * @returns {node} Display length feature node
  3291. * @memberof DataTable#oApi
  3292. */
  3293. function _fnFeatureHtmlLength ( settings )
  3294. {
  3295. var
  3296. classes = settings.oClasses,
  3297. tableId = settings.sTableId,
  3298. menu = settings.aLengthMenu,
  3299. d2 = $.isArray( menu[0] ),
  3300. lengths = d2 ? menu[0] : menu,
  3301. language = d2 ? menu[1] : menu;
  3302.  
  3303. var select = $('<select/>', {
  3304. 'name': tableId+'_length',
  3305. 'aria-controls': tableId,
  3306. 'class': classes.sLengthSelect
  3307. } );
  3308.  
  3309. for ( var i=0, ien=lengths.length ; i<ien ; i++ ) {
  3310. select[0][ i ] = new Option( language[i], lengths[i] );
  3311. }
  3312.  
  3313. var div = $('<div><label/></div>').addClass( classes.sLength );
  3314. if ( ! settings.aanFeatures.l ) {
  3315. div[0].id = tableId+'_length';
  3316. }
  3317.  
  3318. // Can't use `select` variable as user might provide their own and the
  3319. // reference is broken by the use of outerHTML
  3320. $('select', div)
  3321. .val( settings._iDisplayLength )
  3322. .bind( 'change.DT', function(e) {
  3323. _fnLengthChange( settings, $(this).val() );
  3324. _fnDraw( settings );
  3325. } );
  3326.  
  3327. // Update node value whenever anything changes the table's length
  3328. $(settings.nTable).bind( 'length.dt.DT', function (e, s, len) {
  3329. if ( settings === s ) {
  3330. $('select', div).val( len );
  3331. }
  3332. } );
  3333.  
  3334. return div[0];
  3335. }
  3336.  
  3337.  
  3338.  
  3339. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  3340. * Note that most of the paging logic is done in
  3341. * DataTable.ext.pager
  3342. */
  3343.  
  3344. /**
  3345. * Generate the node required for default pagination
  3346. * @param {object} oSettings dataTables settings object
  3347. * @returns {node} Pagination feature node
  3348. * @memberof DataTable#oApi
  3349. */
  3350. function _fnFeatureHtmlPaginate ( settings )
  3351. {
  3352. var
  3353. type = settings.sPaginationType,
  3354. plugin = DataTable.ext.pager[ type ],
  3355. modern = typeof plugin === 'function',
  3356. redraw = function( settings ) {
  3357. _fnDraw( settings );
  3358. },
  3359. node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
  3360. features = settings.aanFeatures;
  3361.  
  3362. if ( ! modern ) {
  3363. plugin.fnInit( settings, node, redraw );
  3364. }
  3365.  
  3366. /* Add a draw callback for the pagination on first instance, to update the paging display */
  3367. if ( ! features.p )
  3368. {
  3369. node.id = settings.sTableId+'_paginate';
  3370.  
  3371. settings.aoDrawCallback.push( {
  3372. "fn": function( settings ) {
  3373. if ( modern ) {
  3374. var
  3375. start = settings._iDisplayStart,
  3376. len = settings._iDisplayLength,
  3377. visRecords = settings.fnRecordsDisplay(),
  3378. all = len === -1,
  3379. page = all ? 0 : Math.ceil( start / len ),
  3380. pages = all ? 1 : Math.ceil( visRecords / len ),
  3381. buttons = plugin(page, pages),
  3382. i, ien;
  3383.  
  3384. for ( i=0, ien=features.p.length ; i<ien ; i++ ) {
  3385. _fnRenderer( settings, 'pageButton' )(
  3386. settings, features.p[i], i, buttons, page, pages
  3387. );
  3388. }
  3389. }
  3390. else {
  3391. plugin.fnUpdate( settings, redraw );
  3392. }
  3393. },
  3394. "sName": "pagination"
  3395. } );
  3396. }
  3397.  
  3398. return node;
  3399. }
  3400.  
  3401.  
  3402. /**
  3403. * Alter the display settings to change the page
  3404. * @param {object} settings DataTables settings object
  3405. * @param {string|int} action Paging action to take: "first", "previous",
  3406. * "next" or "last" or page number to jump to (integer)
  3407. * @param [bool] redraw Automatically draw the update or not
  3408. * @returns {bool} true page has changed, false - no change
  3409. * @memberof DataTable#oApi
  3410. */
  3411. function _fnPageChange ( settings, action, redraw )
  3412. {
  3413. var
  3414. start = settings._iDisplayStart,
  3415. len = settings._iDisplayLength,
  3416. records = settings.fnRecordsDisplay();
  3417.  
  3418. if ( records === 0 || len === -1 )
  3419. {
  3420. start = 0;
  3421. }
  3422. else if ( typeof action === "number" )
  3423. {
  3424. start = action * len;
  3425.  
  3426. if ( start > records )
  3427. {
  3428. start = 0;
  3429. }
  3430. }
  3431. else if ( action == "first" )
  3432. {
  3433. start = 0;
  3434. }
  3435. else if ( action == "previous" )
  3436. {
  3437. start = len >= 0 ?
  3438. start - len :
  3439. 0;
  3440.  
  3441. if ( start < 0 )
  3442. {
  3443. start = 0;
  3444. }
  3445. }
  3446. else if ( action == "next" )
  3447. {
  3448. if ( start + len < records )
  3449. {
  3450. start += len;
  3451. }
  3452. }
  3453. else if ( action == "last" )
  3454. {
  3455. start = Math.floor( (records-1) / len) * len;
  3456. }
  3457. else
  3458. {
  3459. _fnLog( settings, 0, "Unknown paging action: "+action, 5 );
  3460. }
  3461.  
  3462. var changed = settings._iDisplayStart !== start;
  3463. settings._iDisplayStart = start;
  3464.  
  3465. if ( changed ) {
  3466. _fnCallbackFire( settings, null, 'page', [settings] );
  3467.  
  3468. if ( redraw ) {
  3469. _fnDraw( settings );
  3470. }
  3471. }
  3472.  
  3473. return changed;
  3474. }
  3475.  
  3476.  
  3477.  
  3478. /**
  3479. * Generate the node required for the processing node
  3480. * @param {object} settings dataTables settings object
  3481. * @returns {node} Processing element
  3482. * @memberof DataTable#oApi
  3483. */
  3484. function _fnFeatureHtmlProcessing ( settings )
  3485. {
  3486. return $('<div/>', {
  3487. 'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,
  3488. 'class': settings.oClasses.sProcessing
  3489. } )
  3490. .html( settings.oLanguage.sProcessing )
  3491. .insertBefore( settings.nTable )[0];
  3492. }
  3493.  
  3494.  
  3495. /**
  3496. * Display or hide the processing indicator
  3497. * @param {object} settings dataTables settings object
  3498. * @param {bool} show Show the processing indicator (true) or not (false)
  3499. * @memberof DataTable#oApi
  3500. */
  3501. function _fnProcessingDisplay ( settings, show )
  3502. {
  3503. if ( settings.oFeatures.bProcessing ) {
  3504. $(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );
  3505. }
  3506.  
  3507. _fnCallbackFire( settings, null, 'processing', [settings, show] );
  3508. }
  3509.  
  3510. /**
  3511. * Add any control elements for the table - specifically scrolling
  3512. * @param {object} settings dataTables settings object
  3513. * @returns {node} Node to add to the DOM
  3514. * @memberof DataTable#oApi
  3515. */
  3516. function _fnFeatureHtmlTable ( settings )
  3517. {
  3518. var table = $(settings.nTable);
  3519.  
  3520. // Add the ARIA grid role to the table
  3521. table.attr( 'role', 'grid' );
  3522.  
  3523. // Scrolling from here on in
  3524. var scroll = settings.oScroll;
  3525.  
  3526. if ( scroll.sX === '' && scroll.sY === '' ) {
  3527. return settings.nTable;
  3528. }
  3529.  
  3530. var scrollX = scroll.sX;
  3531. var scrollY = scroll.sY;
  3532. var classes = settings.oClasses;
  3533. var caption = table.children('caption');
  3534. var captionSide = caption.length ? caption[0]._captionSide : null;
  3535. var headerClone = $( table[0].cloneNode(false) );
  3536. var footerClone = $( table[0].cloneNode(false) );
  3537. var footer = table.children('tfoot');
  3538. var _div = '<div/>';
  3539. var size = function ( s ) {
  3540. return !s ? null : _fnStringToCss( s );
  3541. };
  3542.  
  3543. // This is fairly messy, but with x scrolling enabled, if the table has a
  3544. // width attribute, regardless of any width applied using the column width
  3545. // options, the browser will shrink or grow the table as needed to fit into
  3546. // that 100%. That would make the width options useless. So we remove it.
  3547. // This is okay, under the assumption that width:100% is applied to the
  3548. // table in CSS (it is in the default stylesheet) which will set the table
  3549. // width as appropriate (the attribute and css behave differently...)
  3550. if ( scroll.sX && table.attr('width') === '100%' ) {
  3551. table.removeAttr('width');
  3552. }
  3553.  
  3554. if ( ! footer.length ) {
  3555. footer = null;
  3556. }
  3557.  
  3558. /*
  3559. * The HTML structure that we want to generate in this function is:
  3560. * div - scroller
  3561. * div - scroll head
  3562. * div - scroll head inner
  3563. * table - scroll head table
  3564. * thead - thead
  3565. * div - scroll body
  3566. * table - table (master table)
  3567. * thead - thead clone for sizing
  3568. * tbody - tbody
  3569. * div - scroll foot
  3570. * div - scroll foot inner
  3571. * table - scroll foot table
  3572. * tfoot - tfoot
  3573. */
  3574. var scroller = $( _div, { 'class': classes.sScrollWrapper } )
  3575. .append(
  3576. $(_div, { 'class': classes.sScrollHead } )
  3577. .css( {
  3578. overflow: 'hidden',
  3579. position: 'relative',
  3580. border: 0,
  3581. width: scrollX ? size(scrollX) : '100%'
  3582. } )
  3583. .append(
  3584. $(_div, { 'class': classes.sScrollHeadInner } )
  3585. .css( {
  3586. 'box-sizing': 'content-box',
  3587. width: scroll.sXInner || '100%'
  3588. } )
  3589. .append(
  3590. headerClone
  3591. .removeAttr('id')
  3592. .css( 'margin-left', 0 )
  3593. .append( captionSide === 'top' ? caption : null )
  3594. .append(
  3595. table.children('thead')
  3596. )
  3597. )
  3598. )
  3599. )
  3600. .append(
  3601. $(_div, { 'class': classes.sScrollBody } )
  3602. .css( {
  3603. overflow: 'auto',
  3604. height: size( scrollY ),
  3605. width: size( scrollX )
  3606. } )
  3607. .append( table )
  3608. );
  3609.  
  3610. if ( footer ) {
  3611. scroller.append(
  3612. $(_div, { 'class': classes.sScrollFoot } )
  3613. .css( {
  3614. overflow: 'hidden',
  3615. border: 0,
  3616. width: scrollX ? size(scrollX) : '100%'
  3617. } )
  3618. .append(
  3619. $(_div, { 'class': classes.sScrollFootInner } )
  3620. .append(
  3621. footerClone
  3622. .removeAttr('id')
  3623. .css( 'margin-left', 0 )
  3624. .append( captionSide === 'bottom' ? caption : null )
  3625. .append(
  3626. table.children('tfoot')
  3627. )
  3628. )
  3629. )
  3630. );
  3631. }
  3632.  
  3633. var children = scroller.children();
  3634. var scrollHead = children[0];
  3635. var scrollBody = children[1];
  3636. var scrollFoot = footer ? children[2] : null;
  3637.  
  3638. // When the body is scrolled, then we also want to scroll the headers
  3639. if ( scrollX ) {
  3640. $(scrollBody).scroll( function (e) {
  3641. var scrollLeft = this.scrollLeft;
  3642.  
  3643. scrollHead.scrollLeft = scrollLeft;
  3644.  
  3645. if ( footer ) {
  3646. scrollFoot.scrollLeft = scrollLeft;
  3647. }
  3648. } );
  3649. }
  3650.  
  3651. settings.nScrollHead = scrollHead;
  3652. settings.nScrollBody = scrollBody;
  3653. settings.nScrollFoot = scrollFoot;
  3654.  
  3655. // On redraw - align columns
  3656. settings.aoDrawCallback.push( {
  3657. "fn": _fnScrollDraw,
  3658. "sName": "scrolling"
  3659. } );
  3660.  
  3661. return scroller[0];
  3662. }
  3663.  
  3664.  
  3665.  
  3666. /**
  3667. * Update the header, footer and body tables for resizing - i.e. column
  3668. * alignment.
  3669. *
  3670. * Welcome to the most horrible function DataTables. The process that this
  3671. * function follows is basically:
  3672. * 1. Re-create the table inside the scrolling div
  3673. * 2. Take live measurements from the DOM
  3674. * 3. Apply the measurements to align the columns
  3675. * 4. Clean up
  3676. *
  3677. * @param {object} settings dataTables settings object
  3678. * @memberof DataTable#oApi
  3679. */
  3680. function _fnScrollDraw ( settings )
  3681. {
  3682. // Given that this is such a monster function, a lot of variables are use
  3683. // to try and keep the minimised size as small as possible
  3684. var
  3685. scroll = settings.oScroll,
  3686. scrollX = scroll.sX,
  3687. scrollXInner = scroll.sXInner,
  3688. scrollY = scroll.sY,
  3689. barWidth = scroll.iBarWidth,
  3690. divHeader = $(settings.nScrollHead),
  3691. divHeaderStyle = divHeader[0].style,
  3692. divHeaderInner = divHeader.children('div'),
  3693. divHeaderInnerStyle = divHeaderInner[0].style,
  3694. divHeaderTable = divHeaderInner.children('table'),
  3695. divBodyEl = settings.nScrollBody,
  3696. divBody = $(divBodyEl),
  3697. divBodyStyle = divBodyEl.style,
  3698. divFooter = $(settings.nScrollFoot),
  3699. divFooterInner = divFooter.children('div'),
  3700. divFooterTable = divFooterInner.children('table'),
  3701. header = $(settings.nTHead),
  3702. table = $(settings.nTable),
  3703. tableEl = table[0],
  3704. tableStyle = tableEl.style,
  3705. footer = settings.nTFoot ? $(settings.nTFoot) : null,
  3706. browser = settings.oBrowser,
  3707. ie67 = browser.bScrollOversize,
  3708. headerTrgEls, footerTrgEls,
  3709. headerSrcEls, footerSrcEls,
  3710. headerCopy, footerCopy,
  3711. headerWidths=[], footerWidths=[],
  3712. headerContent=[],
  3713. idx, correction, sanityWidth,
  3714. zeroOut = function(nSizer) {
  3715. var style = nSizer.style;
  3716. style.paddingTop = "0";
  3717. style.paddingBottom = "0";
  3718. style.borderTopWidth = "0";
  3719. style.borderBottomWidth = "0";
  3720. style.height = 0;
  3721. };
  3722.  
  3723. /*
  3724. * 1. Re-create the table inside the scrolling div
  3725. */
  3726.  
  3727. // Remove the old minimised thead and tfoot elements in the inner table
  3728. table.children('thead, tfoot').remove();
  3729.  
  3730. // Clone the current header and footer elements and then place it into the inner table
  3731. headerCopy = header.clone().prependTo( table );
  3732. headerTrgEls = header.find('tr'); // original header is in its own table
  3733. headerSrcEls = headerCopy.find('tr');
  3734. headerCopy.find('th, td').removeAttr('tabindex');
  3735.  
  3736. if ( footer ) {
  3737. footerCopy = footer.clone().prependTo( table );
  3738. footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
  3739. footerSrcEls = footerCopy.find('tr');
  3740. }
  3741.  
  3742.  
  3743. /*
  3744. * 2. Take live measurements from the DOM - do not alter the DOM itself!
  3745. */
  3746.  
  3747. // Remove old sizing and apply the calculated column widths
  3748. // Get the unique column headers in the newly created (cloned) header. We want to apply the
  3749. // calculated sizes to this header
  3750. if ( ! scrollX )
  3751. {
  3752. divBodyStyle.width = '100%';
  3753. divHeader[0].style.width = '100%';
  3754. }
  3755.  
  3756. $.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {
  3757. idx = _fnVisibleToColumnIndex( settings, i );
  3758. el.style.width = settings.aoColumns[idx].sWidth;
  3759. } );
  3760.  
  3761. if ( footer ) {
  3762. _fnApplyToChildren( function(n) {
  3763. n.style.width = "";
  3764. }, footerSrcEls );
  3765. }
  3766.  
  3767. // If scroll collapse is enabled, when we put the headers back into the body for sizing, we
  3768. // will end up forcing the scrollbar to appear, making our measurements wrong for when we
  3769. // then hide it (end of this function), so add the header height to the body scroller.
  3770. if ( scroll.bCollapse && scrollY !== "" ) {
  3771. divBodyStyle.height = (divBody[0].offsetHeight + header[0].offsetHeight)+"px";
  3772. }
  3773.  
  3774. // Size the table as a whole
  3775. sanityWidth = table.outerWidth();
  3776. if ( scrollX === "" ) {
  3777. // No x scrolling
  3778. tableStyle.width = "100%";
  3779.  
  3780. // IE7 will make the width of the table when 100% include the scrollbar
  3781. // - which is shouldn't. When there is a scrollbar we need to take this
  3782. // into account.
  3783. if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
  3784. divBody.css('overflow-y') == "scroll")
  3785. ) {
  3786. tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
  3787. }
  3788. }
  3789. else
  3790. {
  3791. // x scrolling
  3792. if ( scrollXInner !== "" ) {
  3793. // x scroll inner has been given - use it
  3794. tableStyle.width = _fnStringToCss(scrollXInner);
  3795. }
  3796. else if ( sanityWidth == divBody.width() && divBody.height() < table.height() ) {
  3797. // There is y-scrolling - try to take account of the y scroll bar
  3798. tableStyle.width = _fnStringToCss( sanityWidth-barWidth );
  3799. if ( table.outerWidth() > sanityWidth-barWidth ) {
  3800. // Not possible to take account of it
  3801. tableStyle.width = _fnStringToCss( sanityWidth );
  3802. }
  3803. }
  3804. else {
  3805. // When all else fails
  3806. tableStyle.width = _fnStringToCss( sanityWidth );
  3807. }
  3808. }
  3809.  
  3810. // Recalculate the sanity width - now that we've applied the required width,
  3811. // before it was a temporary variable. This is required because the column
  3812. // width calculation is done before this table DOM is created.
  3813. sanityWidth = table.outerWidth();
  3814.  
  3815. // Hidden header should have zero height, so remove padding and borders. Then
  3816. // set the width based on the real headers
  3817.  
  3818. // Apply all styles in one pass
  3819. _fnApplyToChildren( zeroOut, headerSrcEls );
  3820.  
  3821. // Read all widths in next pass
  3822. _fnApplyToChildren( function(nSizer) {
  3823. headerContent.push( nSizer.innerHTML );
  3824. headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
  3825. }, headerSrcEls );
  3826.  
  3827. // Apply all widths in final pass
  3828. _fnApplyToChildren( function(nToSize, i) {
  3829. nToSize.style.width = headerWidths[i];
  3830. }, headerTrgEls );
  3831.  
  3832. $(headerSrcEls).height(0);
  3833.  
  3834. /* Same again with the footer if we have one */
  3835. if ( footer )
  3836. {
  3837. _fnApplyToChildren( zeroOut, footerSrcEls );
  3838.  
  3839. _fnApplyToChildren( function(nSizer) {
  3840. footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
  3841. }, footerSrcEls );
  3842.  
  3843. _fnApplyToChildren( function(nToSize, i) {
  3844. nToSize.style.width = footerWidths[i];
  3845. }, footerTrgEls );
  3846.  
  3847. $(footerSrcEls).height(0);
  3848. }
  3849.  
  3850.  
  3851. /*
  3852. * 3. Apply the measurements
  3853. */
  3854.  
  3855. // "Hide" the header and footer that we used for the sizing. We need to keep
  3856. // the content of the cell so that the width applied to the header and body
  3857. // both match, but we want to hide it completely. We want to also fix their
  3858. // width to what they currently are
  3859. _fnApplyToChildren( function(nSizer, i) {
  3860. nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+headerContent[i]+'</div>';
  3861. nSizer.style.width = headerWidths[i];
  3862. }, headerSrcEls );
  3863.  
  3864. if ( footer )
  3865. {
  3866. _fnApplyToChildren( function(nSizer, i) {
  3867. nSizer.innerHTML = "";
  3868. nSizer.style.width = footerWidths[i];
  3869. }, footerSrcEls );
  3870. }
  3871.  
  3872. // Sanity check that the table is of a sensible width. If not then we are going to get
  3873. // misalignment - try to prevent this by not allowing the table to shrink below its min width
  3874. if ( table.outerWidth() < sanityWidth )
  3875. {
  3876. // The min width depends upon if we have a vertical scrollbar visible or not */
  3877. correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
  3878. divBody.css('overflow-y') == "scroll")) ?
  3879. sanityWidth+barWidth :
  3880. sanityWidth;
  3881.  
  3882. // IE6/7 are a law unto themselves...
  3883. if ( ie67 && (divBodyEl.scrollHeight >
  3884. divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
  3885. ) {
  3886. tableStyle.width = _fnStringToCss( correction-barWidth );
  3887. }
  3888.  
  3889. // And give the user a warning that we've stopped the table getting too small
  3890. if ( scrollX === "" || scrollXInner !== "" ) {
  3891. _fnLog( settings, 1, 'Possible column misalignment', 6 );
  3892. }
  3893. }
  3894. else
  3895. {
  3896. correction = '100%';
  3897. }
  3898.  
  3899. // Apply to the container elements
  3900. divBodyStyle.width = _fnStringToCss( correction );
  3901. divHeaderStyle.width = _fnStringToCss( correction );
  3902.  
  3903. if ( footer ) {
  3904. settings.nScrollFoot.style.width = _fnStringToCss( correction );
  3905. }
  3906.  
  3907.  
  3908. /*
  3909. * 4. Clean up
  3910. */
  3911. if ( ! scrollY ) {
  3912. /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
  3913. * the scrollbar height from the visible display, rather than adding it on. We need to
  3914. * set the height in order to sort this. Don't want to do it in any other browsers.
  3915. */
  3916. if ( ie67 ) {
  3917. divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );
  3918. }
  3919. }
  3920.  
  3921. if ( scrollY && scroll.bCollapse ) {
  3922. divBodyStyle.height = _fnStringToCss( scrollY );
  3923.  
  3924. var iExtra = (scrollX && tableEl.offsetWidth > divBodyEl.offsetWidth) ?
  3925. barWidth :
  3926. 0;
  3927.  
  3928. if ( tableEl.offsetHeight < divBodyEl.offsetHeight ) {
  3929. divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+iExtra );
  3930. }
  3931. }
  3932.  
  3933. /* Finally set the width's of the header and footer tables */
  3934. var iOuterWidth = table.outerWidth();
  3935. divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
  3936. divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );
  3937.  
  3938. // Figure out if there are scrollbar present - if so then we need a the header and footer to
  3939. // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
  3940. var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
  3941. var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
  3942. divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px";
  3943.  
  3944. if ( footer ) {
  3945. divFooterTable[0].style.width = _fnStringToCss( iOuterWidth );
  3946. divFooterInner[0].style.width = _fnStringToCss( iOuterWidth );
  3947. divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px";
  3948. }
  3949.  
  3950. /* Adjust the position of the header in case we loose the y-scrollbar */
  3951. divBody.scroll();
  3952.  
  3953. // If sorting or filtering has occurred, jump the scrolling back to the top
  3954. // only if we aren't holding the position
  3955. if ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {
  3956. divBodyEl.scrollTop = 0;
  3957. }
  3958. }
  3959.  
  3960.  
  3961.  
  3962. /**
  3963. * Apply a given function to the display child nodes of an element array (typically
  3964. * TD children of TR rows
  3965. * @param {function} fn Method to apply to the objects
  3966. * @param array {nodes} an1 List of elements to look through for display children
  3967. * @param array {nodes} an2 Another list (identical structure to the first) - optional
  3968. * @memberof DataTable#oApi
  3969. */
  3970. function _fnApplyToChildren( fn, an1, an2 )
  3971. {
  3972. var index=0, i=0, iLen=an1.length;
  3973. var nNode1, nNode2;
  3974.  
  3975. while ( i < iLen ) {
  3976. nNode1 = an1[i].firstChild;
  3977. nNode2 = an2 ? an2[i].firstChild : null;
  3978.  
  3979. while ( nNode1 ) {
  3980. if ( nNode1.nodeType === 1 ) {
  3981. if ( an2 ) {
  3982. fn( nNode1, nNode2, index );
  3983. }
  3984. else {
  3985. fn( nNode1, index );
  3986. }
  3987.  
  3988. index++;
  3989. }
  3990.  
  3991. nNode1 = nNode1.nextSibling;
  3992. nNode2 = an2 ? nNode2.nextSibling : null;
  3993. }
  3994.  
  3995. i++;
  3996. }
  3997. }
  3998.  
  3999.  
  4000.  
  4001. var __re_html_remove = /<.*?>/g;
  4002.  
  4003.  
  4004. /**
  4005. * Calculate the width of columns for the table
  4006. * @param {object} oSettings dataTables settings object
  4007. * @memberof DataTable#oApi
  4008. */
  4009. function _fnCalculateColumnWidths ( oSettings )
  4010. {
  4011. var
  4012. table = oSettings.nTable,
  4013. columns = oSettings.aoColumns,
  4014. scroll = oSettings.oScroll,
  4015. scrollY = scroll.sY,
  4016. scrollX = scroll.sX,
  4017. scrollXInner = scroll.sXInner,
  4018. columnCount = columns.length,
  4019. visibleColumns = _fnGetColumns( oSettings, 'bVisible' ),
  4020. headerCells = $('th', oSettings.nTHead),
  4021. tableWidthAttr = table.getAttribute('width'),
  4022. tableContainer = table.parentNode,
  4023. userInputs = false,
  4024. i, column, columnIdx, width, outerWidth;
  4025.  
  4026. /* Convert any user input sizes into pixel sizes */
  4027. for ( i=0 ; i<visibleColumns.length ; i++ ) {
  4028. column = columns[ visibleColumns[i] ];
  4029.  
  4030. if ( column.sWidth !== null ) {
  4031. column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );
  4032.  
  4033. userInputs = true;
  4034. }
  4035. }
  4036.  
  4037. /* If the number of columns in the DOM equals the number that we have to
  4038. * process in DataTables, then we can use the offsets that are created by
  4039. * the web- browser. No custom sizes can be set in order for this to happen,
  4040. * nor scrolling used
  4041. */
  4042. if ( ! userInputs && ! scrollX && ! scrollY &&
  4043. columnCount == _fnVisbleColumns( oSettings ) &&
  4044. columnCount == headerCells.length
  4045. ) {
  4046. for ( i=0 ; i<columnCount ; i++ ) {
  4047. columns[i].sWidth = _fnStringToCss( headerCells.eq(i).width() );
  4048. }
  4049. }
  4050. else
  4051. {
  4052. // Otherwise construct a single row table with the widest node in the
  4053. // data, assign any user defined widths, then insert it into the DOM and
  4054. // allow the browser to do all the hard work of calculating table widths
  4055. var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
  4056. .empty()
  4057. .css( 'visibility', 'hidden' )
  4058. .removeAttr( 'id' )
  4059. .append( $(oSettings.nTHead).clone( false ) )
  4060. .append( $(oSettings.nTFoot).clone( false ) )
  4061. .append( $('<tbody><tr/></tbody>') );
  4062.  
  4063. // Remove any assigned widths from the footer (from scrolling)
  4064. tmpTable.find('tfoot th, tfoot td').css('width', '');
  4065.  
  4066. var tr = tmpTable.find( 'tbody tr' );
  4067.  
  4068. // Apply custom sizing to the cloned header
  4069. headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
  4070.  
  4071. for ( i=0 ; i<visibleColumns.length ; i++ ) {
  4072. column = columns[ visibleColumns[i] ];
  4073.  
  4074. headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
  4075. _fnStringToCss( column.sWidthOrig ) :
  4076. '';
  4077. }
  4078.  
  4079. // Find the widest cell for each column and put it into the table
  4080. if ( oSettings.aoData.length ) {
  4081. for ( i=0 ; i<visibleColumns.length ; i++ ) {
  4082. columnIdx = visibleColumns[i];
  4083. column = columns[ columnIdx ];
  4084.  
  4085. $( _fnGetWidestNode( oSettings, columnIdx ) )
  4086. .clone( false )
  4087. .append( column.sContentPadding )
  4088. .appendTo( tr );
  4089. }
  4090. }
  4091.  
  4092. // Table has been built, attach to the document so we can work with it
  4093. tmpTable.appendTo( tableContainer );
  4094.  
  4095. // When scrolling (X or Y) we want to set the width of the table as
  4096. // appropriate. However, when not scrolling leave the table width as it
  4097. // is. This results in slightly different, but I think correct behaviour
  4098. if ( scrollX && scrollXInner ) {
  4099. tmpTable.width( scrollXInner );
  4100. }
  4101. else if ( scrollX ) {
  4102. tmpTable.css( 'width', 'auto' );
  4103.  
  4104. if ( tmpTable.width() < tableContainer.offsetWidth ) {
  4105. tmpTable.width( tableContainer.offsetWidth );
  4106. }
  4107. }
  4108. else if ( scrollY ) {
  4109. tmpTable.width( tableContainer.offsetWidth );
  4110. }
  4111. else if ( tableWidthAttr ) {
  4112. tmpTable.width( tableWidthAttr );
  4113. }
  4114.  
  4115. // Take into account the y scrollbar
  4116. _fnScrollingWidthAdjust( oSettings, tmpTable[0] );
  4117.  
  4118. // Browsers need a bit of a hand when a width is assigned to any columns
  4119. // when x-scrolling as they tend to collapse the table to the min-width,
  4120. // even if we sent the column widths. So we need to keep track of what
  4121. // the table width should be by summing the user given values, and the
  4122. // automatic values
  4123. if ( scrollX )
  4124. {
  4125. var total = 0;
  4126.  
  4127. for ( i=0 ; i<visibleColumns.length ; i++ ) {
  4128. column = columns[ visibleColumns[i] ];
  4129. outerWidth = $(headerCells[i]).outerWidth();
  4130.  
  4131. total += column.sWidthOrig === null ?
  4132. outerWidth :
  4133. parseInt( column.sWidth, 10 ) + outerWidth - $(headerCells[i]).width();
  4134. }
  4135.  
  4136. tmpTable.width( _fnStringToCss( total ) );
  4137. table.style.width = _fnStringToCss( total );
  4138. }
  4139.  
  4140. // Get the width of each column in the constructed table
  4141. for ( i=0 ; i<visibleColumns.length ; i++ ) {
  4142. column = columns[ visibleColumns[i] ];
  4143. width = $(headerCells[i]).width();
  4144.  
  4145. if ( width ) {
  4146. column.sWidth = _fnStringToCss( width );
  4147. }
  4148. }
  4149.  
  4150. table.style.width = _fnStringToCss( tmpTable.css('width') );
  4151.  
  4152. // Finished with the table - ditch it
  4153. tmpTable.remove();
  4154. }
  4155.  
  4156. // If there is a width attr, we want to attach an event listener which
  4157. // allows the table sizing to automatically adjust when the window is
  4158. // resized. Use the width attr rather than CSS, since we can't know if the
  4159. // CSS is a relative value or absolute - DOM read is always px.
  4160. if ( tableWidthAttr ) {
  4161. table.style.width = _fnStringToCss( tableWidthAttr );
  4162. }
  4163.  
  4164. if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
  4165. $(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
  4166. _fnAdjustColumnSizing( oSettings );
  4167. } ) );
  4168.  
  4169. oSettings._reszEvt = true;
  4170. }
  4171. }
  4172.  
  4173.  
  4174. /**
  4175. * Throttle the calls to a function. Arguments and context are maintained for
  4176. * the throttled function
  4177. * @param {function} fn Function to be called
  4178. * @param {int} [freq=200] call frequency in mS
  4179. * @returns {function} wrapped function
  4180. * @memberof DataTable#oApi
  4181. */
  4182. function _fnThrottle( fn, freq ) {
  4183. var
  4184. frequency = freq !== undefined ? freq : 200,
  4185. last,
  4186. timer;
  4187.  
  4188. return function () {
  4189. var
  4190. that = this,
  4191. now = +new Date(),
  4192. args = arguments;
  4193.  
  4194. if ( last && now < last + frequency ) {
  4195. clearTimeout( timer );
  4196.  
  4197. timer = setTimeout( function () {
  4198. last = undefined;
  4199. fn.apply( that, args );
  4200. }, frequency );
  4201. }
  4202. else if ( last ) {
  4203. last = now;
  4204. fn.apply( that, args );
  4205. }
  4206. else {
  4207. last = now;
  4208. }
  4209. };
  4210. }
  4211.  
  4212.  
  4213. /**
  4214. * Convert a CSS unit width to pixels (e.g. 2em)
  4215. * @param {string} width width to be converted
  4216. * @param {node} parent parent to get the with for (required for relative widths) - optional
  4217. * @returns {int} width in pixels
  4218. * @memberof DataTable#oApi
  4219. */
  4220. function _fnConvertToWidth ( width, parent )
  4221. {
  4222. if ( ! width ) {
  4223. return 0;
  4224. }
  4225.  
  4226. var n = $('<div/>')
  4227. .css( 'width', _fnStringToCss( width ) )
  4228. .appendTo( parent || document.body );
  4229.  
  4230. var val = n[0].offsetWidth;
  4231. n.remove();
  4232.  
  4233. return val;
  4234. }
  4235.  
  4236.  
  4237. /**
  4238. * Adjust a table's width to take account of vertical scroll bar
  4239. * @param {object} oSettings dataTables settings object
  4240. * @param {node} n table node
  4241. * @memberof DataTable#oApi
  4242. */
  4243.  
  4244. function _fnScrollingWidthAdjust ( settings, n )
  4245. {
  4246. var scroll = settings.oScroll;
  4247.  
  4248. if ( scroll.sX || scroll.sY ) {
  4249. // When y-scrolling only, we want to remove the width of the scroll bar
  4250. // so the table + scroll bar will fit into the area available, otherwise
  4251. // we fix the table at its current size with no adjustment
  4252. var correction = ! scroll.sX ? scroll.iBarWidth : 0;
  4253. n.style.width = _fnStringToCss( $(n).outerWidth() - correction );
  4254. }
  4255. }
  4256.  
  4257.  
  4258. /**
  4259. * Get the widest node
  4260. * @param {object} settings dataTables settings object
  4261. * @param {int} colIdx column of interest
  4262. * @returns {node} widest table node
  4263. * @memberof DataTable#oApi
  4264. */
  4265. function _fnGetWidestNode( settings, colIdx )
  4266. {
  4267. var idx = _fnGetMaxLenString( settings, colIdx );
  4268. if ( idx < 0 ) {
  4269. return null;
  4270. }
  4271.  
  4272. var data = settings.aoData[ idx ];
  4273. return ! data.nTr ? // Might not have been created when deferred rendering
  4274. $('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :
  4275. data.anCells[ colIdx ];
  4276. }
  4277.  
  4278.  
  4279. /**
  4280. * Get the maximum strlen for each data column
  4281. * @param {object} settings dataTables settings object
  4282. * @param {int} colIdx column of interest
  4283. * @returns {string} max string length for each column
  4284. * @memberof DataTable#oApi
  4285. */
  4286. function _fnGetMaxLenString( settings, colIdx )
  4287. {
  4288. var s, max=-1, maxIdx = -1;
  4289.  
  4290. for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
  4291. s = _fnGetCellData( settings, i, colIdx, 'display' )+'';
  4292. s = s.replace( __re_html_remove, '' );
  4293.  
  4294. if ( s.length > max ) {
  4295. max = s.length;
  4296. maxIdx = i;
  4297. }
  4298. }
  4299.  
  4300. return maxIdx;
  4301. }
  4302.  
  4303.  
  4304. /**
  4305. * Append a CSS unit (only if required) to a string
  4306. * @param {string} value to css-ify
  4307. * @returns {string} value with css unit
  4308. * @memberof DataTable#oApi
  4309. */
  4310. function _fnStringToCss( s )
  4311. {
  4312. if ( s === null ) {
  4313. return '0px';
  4314. }
  4315.  
  4316. if ( typeof s == 'number' ) {
  4317. return s < 0 ?
  4318. '0px' :
  4319. s+'px';
  4320. }
  4321.  
  4322. // Check it has a unit character already
  4323. return s.match(/\d$/) ?
  4324. s+'px' :
  4325. s;
  4326. }
  4327.  
  4328.  
  4329. /**
  4330. * Get the width of a scroll bar in this browser being used
  4331. * @returns {int} width in pixels
  4332. * @memberof DataTable#oApi
  4333. */
  4334. function _fnScrollBarWidth ()
  4335. {
  4336. // On first run a static variable is set, since this is only needed once.
  4337. // Subsequent runs will just use the previously calculated value
  4338. if ( ! DataTable.__scrollbarWidth ) {
  4339. var inner = $('<p/>').css( {
  4340. width: '100%',
  4341. height: 200,
  4342. padding: 0
  4343. } )[0];
  4344.  
  4345. var outer = $('<div/>')
  4346. .css( {
  4347. position: 'absolute',
  4348. top: 0,
  4349. left: 0,
  4350. width: 200,
  4351. height: 150,
  4352. padding: 0,
  4353. overflow: 'hidden',
  4354. visibility: 'hidden'
  4355. } )
  4356. .append( inner )
  4357. .appendTo( 'body' );
  4358.  
  4359. var w1 = inner.offsetWidth;
  4360. outer.css( 'overflow', 'scroll' );
  4361. var w2 = inner.offsetWidth;
  4362.  
  4363. if ( w1 === w2 ) {
  4364. w2 = outer[0].clientWidth;
  4365. }
  4366.  
  4367. outer.remove();
  4368.  
  4369. DataTable.__scrollbarWidth = w1 - w2;
  4370. }
  4371.  
  4372. return DataTable.__scrollbarWidth;
  4373. }
  4374.  
  4375.  
  4376.  
  4377. function _fnSortFlatten ( settings )
  4378. {
  4379. var
  4380. i, iLen, k, kLen,
  4381. aSort = [],
  4382. aiOrig = [],
  4383. aoColumns = settings.aoColumns,
  4384. aDataSort, iCol, sType, srcCol,
  4385. fixed = settings.aaSortingFixed,
  4386. fixedObj = $.isPlainObject( fixed ),
  4387. nestedSort = [],
  4388. add = function ( a ) {
  4389. if ( a.length && ! $.isArray( a[0] ) ) {
  4390. // 1D array
  4391. nestedSort.push( a );
  4392. }
  4393. else {
  4394. // 2D array
  4395. nestedSort.push.apply( nestedSort, a );
  4396. }
  4397. };
  4398.  
  4399. // Build the sort array, with pre-fix and post-fix options if they have been
  4400. // specified
  4401. if ( $.isArray( fixed ) ) {
  4402. add( fixed );
  4403. }
  4404.  
  4405. if ( fixedObj && fixed.pre ) {
  4406. add( fixed.pre );
  4407. }
  4408.  
  4409. add( settings.aaSorting );
  4410.  
  4411. if (fixedObj && fixed.post ) {
  4412. add( fixed.post );
  4413. }
  4414.  
  4415. for ( i=0 ; i<nestedSort.length ; i++ )
  4416. {
  4417. srcCol = nestedSort[i][0];
  4418. aDataSort = aoColumns[ srcCol ].aDataSort;
  4419.  
  4420. for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
  4421. {
  4422. iCol = aDataSort[k];
  4423. sType = aoColumns[ iCol ].sType || 'string';
  4424.  
  4425. if ( nestedSort[i]._idx === undefined ) {
  4426. nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );
  4427. }
  4428.  
  4429. aSort.push( {
  4430. src: srcCol,
  4431. col: iCol,
  4432. dir: nestedSort[i][1],
  4433. index: nestedSort[i]._idx,
  4434. type: sType,
  4435. formatter: DataTable.ext.type.order[ sType+"-pre" ]
  4436. } );
  4437. }
  4438. }
  4439.  
  4440. return aSort;
  4441. }
  4442.  
  4443. /**
  4444. * Change the order of the table
  4445. * @param {object} oSettings dataTables settings object
  4446. * @memberof DataTable#oApi
  4447. * @todo This really needs split up!
  4448. */
  4449. function _fnSort ( oSettings )
  4450. {
  4451. var
  4452. i, ien, iLen, j, jLen, k, kLen,
  4453. sDataType, nTh,
  4454. aiOrig = [],
  4455. oExtSort = DataTable.ext.type.order,
  4456. aoData = oSettings.aoData,
  4457. aoColumns = oSettings.aoColumns,
  4458. aDataSort, data, iCol, sType, oSort,
  4459. formatters = 0,
  4460. sortCol,
  4461. displayMaster = oSettings.aiDisplayMaster,
  4462. aSort;
  4463.  
  4464. // Resolve any column types that are unknown due to addition or invalidation
  4465. // @todo Can this be moved into a 'data-ready' handler which is called when
  4466. // data is going to be used in the table?
  4467. _fnColumnTypes( oSettings );
  4468.  
  4469. aSort = _fnSortFlatten( oSettings );
  4470.  
  4471. for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
  4472. sortCol = aSort[i];
  4473.  
  4474. // Track if we can use the fast sort algorithm
  4475. if ( sortCol.formatter ) {
  4476. formatters++;
  4477. }
  4478.  
  4479. // Load the data needed for the sort, for each cell
  4480. _fnSortData( oSettings, sortCol.col );
  4481. }
  4482.  
  4483. /* No sorting required if server-side or no sorting array */
  4484. if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
  4485. {
  4486. // Create a value - key array of the current row positions such that we can use their
  4487. // current position during the sort, if values match, in order to perform stable sorting
  4488. for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
  4489. aiOrig[ displayMaster[i] ] = i;
  4490. }
  4491.  
  4492. /* Do the sort - here we want multi-column sorting based on a given data source (column)
  4493. * and sorting function (from oSort) in a certain direction. It's reasonably complex to
  4494. * follow on it's own, but this is what we want (example two column sorting):
  4495. * fnLocalSorting = function(a,b){
  4496. * var iTest;
  4497. * iTest = oSort['string-asc']('data11', 'data12');
  4498. * if (iTest !== 0)
  4499. * return iTest;
  4500. * iTest = oSort['numeric-desc']('data21', 'data22');
  4501. * if (iTest !== 0)
  4502. * return iTest;
  4503. * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
  4504. * }
  4505. * Basically we have a test for each sorting column, if the data in that column is equal,
  4506. * test the next column. If all columns match, then we use a numeric sort on the row
  4507. * positions in the original data array to provide a stable sort.
  4508. *
  4509. * Note - I know it seems excessive to have two sorting methods, but the first is around
  4510. * 15% faster, so the second is only maintained for backwards compatibility with sorting
  4511. * methods which do not have a pre-sort formatting function.
  4512. */
  4513. if ( formatters === aSort.length ) {
  4514. // All sort types have formatting functions
  4515. displayMaster.sort( function ( a, b ) {
  4516. var
  4517. x, y, k, test, sort,
  4518. len=aSort.length,
  4519. dataA = aoData[a]._aSortData,
  4520. dataB = aoData[b]._aSortData;
  4521.  
  4522. for ( k=0 ; k<len ; k++ ) {
  4523. sort = aSort[k];
  4524.  
  4525. x = dataA[ sort.col ];
  4526. y = dataB[ sort.col ];
  4527.  
  4528. test = x<y ? -1 : x>y ? 1 : 0;
  4529. if ( test !== 0 ) {
  4530. return sort.dir === 'asc' ? test : -test;
  4531. }
  4532. }
  4533.  
  4534. x = aiOrig[a];
  4535. y = aiOrig[b];
  4536. return x<y ? -1 : x>y ? 1 : 0;
  4537. } );
  4538. }
  4539. else {
  4540. // Depreciated - remove in 1.11 (providing a plug-in option)
  4541. // Not all sort types have formatting methods, so we have to call their sorting
  4542. // methods.
  4543. displayMaster.sort( function ( a, b ) {
  4544. var
  4545. x, y, k, l, test, sort, fn,
  4546. len=aSort.length,
  4547. dataA = aoData[a]._aSortData,
  4548. dataB = aoData[b]._aSortData;
  4549.  
  4550. for ( k=0 ; k<len ; k++ ) {
  4551. sort = aSort[k];
  4552.  
  4553. x = dataA[ sort.col ];
  4554. y = dataB[ sort.col ];
  4555.  
  4556. fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
  4557. test = fn( x, y );
  4558. if ( test !== 0 ) {
  4559. return test;
  4560. }
  4561. }
  4562.  
  4563. x = aiOrig[a];
  4564. y = aiOrig[b];
  4565. return x<y ? -1 : x>y ? 1 : 0;
  4566. } );
  4567. }
  4568. }
  4569.  
  4570. /* Tell the draw function that we have sorted the data */
  4571. oSettings.bSorted = true;
  4572. }
  4573.  
  4574.  
  4575. function _fnSortAria ( settings )
  4576. {
  4577. var label;
  4578. var nextSort;
  4579. var columns = settings.aoColumns;
  4580. var aSort = _fnSortFlatten( settings );
  4581. var oAria = settings.oLanguage.oAria;
  4582.  
  4583. // ARIA attributes - need to loop all columns, to update all (removing old
  4584. // attributes as needed)
  4585. for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
  4586. {
  4587. var col = columns[i];
  4588. var asSorting = col.asSorting;
  4589. var sTitle = col.sTitle.replace( /<.*?>/g, "" );
  4590. var th = col.nTh;
  4591.  
  4592. // IE7 is throwing an error when setting these properties with jQuery's
  4593. // attr() and removeAttr() methods...
  4594. th.removeAttribute('aria-sort');
  4595.  
  4596. /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
  4597. if ( col.bSortable ) {
  4598. if ( aSort.length > 0 && aSort[0].col == i ) {
  4599. th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" );
  4600. nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];
  4601. }
  4602. else {
  4603. nextSort = asSorting[0];
  4604. }
  4605.  
  4606. label = sTitle + ( nextSort === "asc" ?
  4607. oAria.sSortAscending :
  4608. oAria.sSortDescending
  4609. );
  4610. }
  4611. else {
  4612. label = sTitle;
  4613. }
  4614.  
  4615. th.setAttribute('aria-label', label);
  4616. }
  4617. }
  4618.  
  4619.  
  4620. /**
  4621. * Function to run on user sort request
  4622. * @param {object} settings dataTables settings object
  4623. * @param {node} attachTo node to attach the handler to
  4624. * @param {int} colIdx column sorting index
  4625. * @param {boolean} [append=false] Append the requested sort to the existing
  4626. * sort if true (i.e. multi-column sort)
  4627. * @param {function} [callback] callback function
  4628. * @memberof DataTable#oApi
  4629. */
  4630. function _fnSortListener ( settings, colIdx, append, callback )
  4631. {
  4632. var col = settings.aoColumns[ colIdx ];
  4633. var sorting = settings.aaSorting;
  4634. var asSorting = col.asSorting;
  4635. var nextSortIdx;
  4636. var next = function ( a, overflow ) {
  4637. var idx = a._idx;
  4638. if ( idx === undefined ) {
  4639. idx = $.inArray( a[1], asSorting );
  4640. }
  4641.  
  4642. return idx+1 < asSorting.length ?
  4643. idx+1 :
  4644. overflow ?
  4645. null :
  4646. 0;
  4647. };
  4648.  
  4649. // Convert to 2D array if needed
  4650. if ( typeof sorting[0] === 'number' ) {
  4651. sorting = settings.aaSorting = [ sorting ];
  4652. }
  4653.  
  4654. // If appending the sort then we are multi-column sorting
  4655. if ( append && settings.oFeatures.bSortMulti ) {
  4656. // Are we already doing some kind of sort on this column?
  4657. var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
  4658.  
  4659. if ( sortIdx !== -1 ) {
  4660. // Yes, modify the sort
  4661. nextSortIdx = next( sorting[sortIdx], true );
  4662.  
  4663. if ( nextSortIdx === null ) {
  4664. sorting.splice( sortIdx, 1 );
  4665. }
  4666. else {
  4667. sorting[sortIdx][1] = asSorting[ nextSortIdx ];
  4668. sorting[sortIdx]._idx = nextSortIdx;
  4669. }
  4670. }
  4671. else {
  4672. // No sort on this column yet
  4673. sorting.push( [ colIdx, asSorting[0], 0 ] );
  4674. sorting[sorting.length-1]._idx = 0;
  4675. }
  4676. }
  4677. else if ( sorting.length && sorting[0][0] == colIdx ) {
  4678. // Single column - already sorting on this column, modify the sort
  4679. nextSortIdx = next( sorting[0] );
  4680.  
  4681. sorting.length = 1;
  4682. sorting[0][1] = asSorting[ nextSortIdx ];
  4683. sorting[0]._idx = nextSortIdx;
  4684. }
  4685. else {
  4686. // Single column - sort only on this column
  4687. sorting.length = 0;
  4688. sorting.push( [ colIdx, asSorting[0] ] );
  4689. sorting[0]._idx = 0;
  4690. }
  4691.  
  4692. // Run the sort by calling a full redraw
  4693. _fnReDraw( settings );
  4694.  
  4695. // callback used for async user interaction
  4696. if ( typeof callback == 'function' ) {
  4697. callback( settings );
  4698. }
  4699. }
  4700.  
  4701.  
  4702. /**
  4703. * Attach a sort handler (click) to a node
  4704. * @param {object} settings dataTables settings object
  4705. * @param {node} attachTo node to attach the handler to
  4706. * @param {int} colIdx column sorting index
  4707. * @param {function} [callback] callback function
  4708. * @memberof DataTable#oApi
  4709. */
  4710. function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
  4711. {
  4712. var col = settings.aoColumns[ colIdx ];
  4713.  
  4714. _fnBindAction( attachTo, {}, function (e) {
  4715. /* If the column is not sortable - don't to anything */
  4716. if ( col.bSortable === false ) {
  4717. return;
  4718. }
  4719.  
  4720. // If processing is enabled use a timeout to allow the processing
  4721. // display to be shown - otherwise to it synchronously
  4722. if ( settings.oFeatures.bProcessing ) {
  4723. _fnProcessingDisplay( settings, true );
  4724.  
  4725. setTimeout( function() {
  4726. _fnSortListener( settings, colIdx, e.shiftKey, callback );
  4727.  
  4728. // In server-side processing, the draw callback will remove the
  4729. // processing display
  4730. if ( _fnDataSource( settings ) !== 'ssp' ) {
  4731. _fnProcessingDisplay( settings, false );
  4732. }
  4733. }, 0 );
  4734. }
  4735. else {
  4736. _fnSortListener( settings, colIdx, e.shiftKey, callback );
  4737. }
  4738. } );
  4739. }
  4740.  
  4741.  
  4742. /**
  4743. * Set the sorting classes on table's body, Note: it is safe to call this function
  4744. * when bSort and bSortClasses are false
  4745. * @param {object} oSettings dataTables settings object
  4746. * @memberof DataTable#oApi
  4747. */
  4748. function _fnSortingClasses( settings )
  4749. {
  4750. var oldSort = settings.aLastSort;
  4751. var sortClass = settings.oClasses.sSortColumn;
  4752. var sort = _fnSortFlatten( settings );
  4753. var features = settings.oFeatures;
  4754. var i, ien, colIdx;
  4755.  
  4756. if ( features.bSort && features.bSortClasses ) {
  4757. // Remove old sorting classes
  4758. for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
  4759. colIdx = oldSort[i].src;
  4760.  
  4761. // Remove column sorting
  4762. $( _pluck( settings.aoData, 'anCells', colIdx ) )
  4763. .removeClass( sortClass + (i<2 ? i+1 : 3) );
  4764. }
  4765.  
  4766. // Add new column sorting
  4767. for ( i=0, ien=sort.length ; i<ien ; i++ ) {
  4768. colIdx = sort[i].src;
  4769.  
  4770. $( _pluck( settings.aoData, 'anCells', colIdx ) )
  4771. .addClass( sortClass + (i<2 ? i+1 : 3) );
  4772. }
  4773. }
  4774.  
  4775. settings.aLastSort = sort;
  4776. }
  4777.  
  4778.  
  4779. // Get the data to sort a column, be it from cache, fresh (populating the
  4780. // cache), or from a sort formatter
  4781. function _fnSortData( settings, idx )
  4782. {
  4783. // Custom sorting function - provided by the sort data type
  4784. var column = settings.aoColumns[ idx ];
  4785. var customSort = DataTable.ext.order[ column.sSortDataType ];
  4786. var customData;
  4787.  
  4788. if ( customSort ) {
  4789. customData = customSort.call( settings.oInstance, settings, idx,
  4790. _fnColumnIndexToVisible( settings, idx )
  4791. );
  4792. }
  4793.  
  4794. // Use / populate cache
  4795. var row, cellData;
  4796. var formatter = DataTable.ext.type.order[ column.sType+"-pre" ];
  4797.  
  4798. for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
  4799. row = settings.aoData[i];
  4800.  
  4801. if ( ! row._aSortData ) {
  4802. row._aSortData = [];
  4803. }
  4804.  
  4805. if ( ! row._aSortData[idx] || customSort ) {
  4806. cellData = customSort ?
  4807. customData[i] : // If there was a custom sort function, use data from there
  4808. _fnGetCellData( settings, i, idx, 'sort' );
  4809.  
  4810. row._aSortData[ idx ] = formatter ?
  4811. formatter( cellData ) :
  4812. cellData;
  4813. }
  4814. }
  4815. }
  4816.  
  4817.  
  4818.  
  4819. /**
  4820. * Save the state of a table
  4821. * @param {object} oSettings dataTables settings object
  4822. * @memberof DataTable#oApi
  4823. */
  4824. function _fnSaveState ( settings )
  4825. {
  4826. if ( !settings.oFeatures.bStateSave || settings.bDestroying )
  4827. {
  4828. return;
  4829. }
  4830.  
  4831. /* Store the interesting variables */
  4832. var state = {
  4833. time: +new Date(),
  4834. start: settings._iDisplayStart,
  4835. length: settings._iDisplayLength,
  4836. order: $.extend( true, [], settings.aaSorting ),
  4837. search: _fnSearchToCamel( settings.oPreviousSearch ),
  4838. columns: $.map( settings.aoColumns, function ( col, i ) {
  4839. return {
  4840. visible: col.bVisible,
  4841. search: _fnSearchToCamel( settings.aoPreSearchCols[i] )
  4842. };
  4843. } )
  4844. };
  4845.  
  4846. _fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] );
  4847.  
  4848. settings.oSavedState = state;
  4849. settings.fnStateSaveCallback.call( settings.oInstance, settings, state );
  4850. }
  4851.  
  4852.  
  4853. /**
  4854. * Attempt to load a saved table state
  4855. * @param {object} oSettings dataTables settings object
  4856. * @param {object} oInit DataTables init object so we can override settings
  4857. * @memberof DataTable#oApi
  4858. */
  4859. function _fnLoadState ( settings, oInit )
  4860. {
  4861. var i, ien;
  4862. var columns = settings.aoColumns;
  4863.  
  4864. if ( ! settings.oFeatures.bStateSave ) {
  4865. return;
  4866. }
  4867.  
  4868. var state = settings.fnStateLoadCallback.call( settings.oInstance, settings );
  4869. if ( ! state || ! state.time ) {
  4870. return;
  4871. }
  4872.  
  4873. /* Allow custom and plug-in manipulation functions to alter the saved data set and
  4874. * cancelling of loading by returning false
  4875. */
  4876. var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, state] );
  4877. if ( $.inArray( false, abStateLoad ) !== -1 ) {
  4878. return;
  4879. }
  4880.  
  4881. /* Reject old data */
  4882. var duration = settings.iStateDuration;
  4883. if ( duration > 0 && state.time < +new Date() - (duration*1000) ) {
  4884. return;
  4885. }
  4886.  
  4887. // Number of columns have changed - all bets are off, no restore of settings
  4888. if ( columns.length !== state.columns.length ) {
  4889. return;
  4890. }
  4891.  
  4892. // Store the saved state so it might be accessed at any time
  4893. settings.oLoadedState = $.extend( true, {}, state );
  4894.  
  4895. // Restore key features - todo - for 1.11 this needs to be done by
  4896. // subscribed events
  4897. settings._iDisplayStart = state.start;
  4898. settings.iInitDisplayStart = state.start;
  4899. settings._iDisplayLength = state.length;
  4900. settings.aaSorting = [];
  4901.  
  4902. // Order
  4903. $.each( state.order, function ( i, col ) {
  4904. settings.aaSorting.push( col[0] >= columns.length ?
  4905. [ 0, col[1] ] :
  4906. col
  4907. );
  4908. } );
  4909.  
  4910. // Search
  4911. $.extend( settings.oPreviousSearch, _fnSearchToHung( state.search ) );
  4912.  
  4913. // Columns
  4914. for ( i=0, ien=state.columns.length ; i<ien ; i++ ) {
  4915. var col = state.columns[i];
  4916.  
  4917. // Visibility
  4918. columns[i].bVisible = col.visible;
  4919.  
  4920. // Search
  4921. $.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );
  4922. }
  4923.  
  4924. _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, state] );
  4925. }
  4926.  
  4927.  
  4928. /**
  4929. * Return the settings object for a particular table
  4930. * @param {node} table table we are using as a dataTable
  4931. * @returns {object} Settings object - or null if not found
  4932. * @memberof DataTable#oApi
  4933. */
  4934. function _fnSettingsFromNode ( table )
  4935. {
  4936. var settings = DataTable.settings;
  4937. var idx = $.inArray( table, _pluck( settings, 'nTable' ) );
  4938.  
  4939. return idx !== -1 ?
  4940. settings[ idx ] :
  4941. null;
  4942. }
  4943.  
  4944.  
  4945. /**
  4946. * Log an error message
  4947. * @param {object} settings dataTables settings object
  4948. * @param {int} level log error messages, or display them to the user
  4949. * @param {string} msg error message
  4950. * @param {int} tn Technical note id to get more information about the error.
  4951. * @memberof DataTable#oApi
  4952. */
  4953. function _fnLog( settings, level, msg, tn )
  4954. {
  4955. msg = 'DataTables warning: '+
  4956. (settings!==null ? 'table id='+settings.sTableId+' - ' : '')+msg;
  4957.  
  4958. if ( tn ) {
  4959. msg += '. For more information about this error, please see '+
  4960. 'http://datatables.net/tn/'+tn;
  4961. }
  4962.  
  4963. if ( ! level ) {
  4964. // Backwards compatibility pre 1.10
  4965. var ext = DataTable.ext;
  4966. var type = ext.sErrMode || ext.errMode;
  4967.  
  4968. if ( type == 'alert' ) {
  4969. alert( msg );
  4970. }
  4971. else {
  4972. throw new Error(msg);
  4973. }
  4974. }
  4975. else if ( window.console && console.log ) {
  4976. console.log( msg );
  4977. }
  4978. }
  4979.  
  4980.  
  4981. /**
  4982. * See if a property is defined on one object, if so assign it to the other object
  4983. * @param {object} ret target object
  4984. * @param {object} src source object
  4985. * @param {string} name property
  4986. * @param {string} [mappedName] name to map too - optional, name used if not given
  4987. * @memberof DataTable#oApi
  4988. */
  4989. function _fnMap( ret, src, name, mappedName )
  4990. {
  4991. if ( $.isArray( name ) ) {
  4992. $.each( name, function (i, val) {
  4993. if ( $.isArray( val ) ) {
  4994. _fnMap( ret, src, val[0], val[1] );
  4995. }
  4996. else {
  4997. _fnMap( ret, src, val );
  4998. }
  4999. } );
  5000.  
  5001. return;
  5002. }
  5003.  
  5004. if ( mappedName === undefined ) {
  5005. mappedName = name;
  5006. }
  5007.  
  5008. if ( src[name] !== undefined ) {
  5009. ret[mappedName] = src[name];
  5010. }
  5011. }
  5012.  
  5013.  
  5014. /**
  5015. * Extend objects - very similar to jQuery.extend, but deep copy objects, and
  5016. * shallow copy arrays. The reason we need to do this, is that we don't want to
  5017. * deep copy array init values (such as aaSorting) since the dev wouldn't be
  5018. * able to override them, but we do want to deep copy arrays.
  5019. * @param {object} out Object to extend
  5020. * @param {object} extender Object from which the properties will be applied to
  5021. * out
  5022. * @param {boolean} breakRefs If true, then arrays will be sliced to take an
  5023. * independent copy with the exception of the `data` or `aaData` parameters
  5024. * if they are present. This is so you can pass in a collection to
  5025. * DataTables and have that used as your data source without breaking the
  5026. * references
  5027. * @returns {object} out Reference, just for convenience - out === the return.
  5028. * @memberof DataTable#oApi
  5029. * @todo This doesn't take account of arrays inside the deep copied objects.
  5030. */
  5031. function _fnExtend( out, extender, breakRefs )
  5032. {
  5033. var val;
  5034.  
  5035. for ( var prop in extender ) {
  5036. if ( extender.hasOwnProperty(prop) ) {
  5037. val = extender[prop];
  5038.  
  5039. if ( $.isPlainObject( val ) ) {
  5040. if ( ! $.isPlainObject( out[prop] ) ) {
  5041. out[prop] = {};
  5042. }
  5043. $.extend( true, out[prop], val );
  5044. }
  5045. else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {
  5046. out[prop] = val.slice();
  5047. }
  5048. else {
  5049. out[prop] = val;
  5050. }
  5051. }
  5052. }
  5053.  
  5054. return out;
  5055. }
  5056.  
  5057.  
  5058. /**
  5059. * Bind an event handers to allow a click or return key to activate the callback.
  5060. * This is good for accessibility since a return on the keyboard will have the
  5061. * same effect as a click, if the element has focus.
  5062. * @param {element} n Element to bind the action to
  5063. * @param {object} oData Data object to pass to the triggered function
  5064. * @param {function} fn Callback function for when the event is triggered
  5065. * @memberof DataTable#oApi
  5066. */
  5067. function _fnBindAction( n, oData, fn )
  5068. {
  5069. $(n)
  5070. .bind( 'click.DT', oData, function (e) {
  5071. n.blur(); // Remove focus outline for mouse users
  5072. fn(e);
  5073. } )
  5074. .bind( 'keypress.DT', oData, function (e){
  5075. if ( e.which === 13 ) {
  5076. e.preventDefault();
  5077. fn(e);
  5078. }
  5079. } )
  5080. .bind( 'selectstart.DT', function () {
  5081. /* Take the brutal approach to cancelling text selection */
  5082. return false;
  5083. } );
  5084. }
  5085.  
  5086.  
  5087. /**
  5088. * Register a callback function. Easily allows a callback function to be added to
  5089. * an array store of callback functions that can then all be called together.
  5090. * @param {object} oSettings dataTables settings object
  5091. * @param {string} sStore Name of the array storage for the callbacks in oSettings
  5092. * @param {function} fn Function to be called back
  5093. * @param {string} sName Identifying name for the callback (i.e. a label)
  5094. * @memberof DataTable#oApi
  5095. */
  5096. function _fnCallbackReg( oSettings, sStore, fn, sName )
  5097. {
  5098. if ( fn )
  5099. {
  5100. oSettings[sStore].push( {
  5101. "fn": fn,
  5102. "sName": sName
  5103. } );
  5104. }
  5105. }
  5106.  
  5107.  
  5108. /**
  5109. * Fire callback functions and trigger events. Note that the loop over the
  5110. * callback array store is done backwards! Further note that you do not want to
  5111. * fire off triggers in time sensitive applications (for example cell creation)
  5112. * as its slow.
  5113. * @param {object} settings dataTables settings object
  5114. * @param {string} callbackArr Name of the array storage for the callbacks in
  5115. * oSettings
  5116. * @param {string} event Name of the jQuery custom event to trigger. If null no
  5117. * trigger is fired
  5118. * @param {array} args Array of arguments to pass to the callback function /
  5119. * trigger
  5120. * @memberof DataTable#oApi
  5121. */
  5122. function _fnCallbackFire( settings, callbackArr, e, args )
  5123. {
  5124. var ret = [];
  5125.  
  5126. if ( callbackArr ) {
  5127. ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {
  5128. return val.fn.apply( settings.oInstance, args );
  5129. } );
  5130. }
  5131.  
  5132. if ( e !== null ) {
  5133. $(settings.nTable).trigger( e+'.dt', args );
  5134. }
  5135.  
  5136. return ret;
  5137. }
  5138.  
  5139.  
  5140. function _fnLengthOverflow ( settings )
  5141. {
  5142. var
  5143. start = settings._iDisplayStart,
  5144. end = settings.fnDisplayEnd(),
  5145. len = settings._iDisplayLength;
  5146.  
  5147. /* If we have space to show extra rows (backing up from the end point - then do so */
  5148. if ( start >= end )
  5149. {
  5150. start = end - len;
  5151. }
  5152.  
  5153. // Keep the start record on the current page
  5154. start -= (start % len);
  5155.  
  5156. if ( len === -1 || start < 0 )
  5157. {
  5158. start = 0;
  5159. }
  5160.  
  5161. settings._iDisplayStart = start;
  5162. }
  5163.  
  5164.  
  5165. function _fnRenderer( settings, type )
  5166. {
  5167. var renderer = settings.renderer;
  5168. var host = DataTable.ext.renderer[type];
  5169.  
  5170. if ( $.isPlainObject( renderer ) && renderer[type] ) {
  5171. // Specific renderer for this type. If available use it, otherwise use
  5172. // the default.
  5173. return host[renderer[type]] || host._;
  5174. }
  5175. else if ( typeof renderer === 'string' ) {
  5176. // Common renderer - if there is one available for this type use it,
  5177. // otherwise use the default
  5178. return host[renderer] || host._;
  5179. }
  5180.  
  5181. // Use the default
  5182. return host._;
  5183. }
  5184.  
  5185.  
  5186. /**
  5187. * Detect the data source being used for the table. Used to simplify the code
  5188. * a little (ajax) and to make it compress a little smaller.
  5189. *
  5190. * @param {object} settings dataTables settings object
  5191. * @returns {string} Data source
  5192. * @memberof DataTable#oApi
  5193. */
  5194. function _fnDataSource ( settings )
  5195. {
  5196. if ( settings.oFeatures.bServerSide ) {
  5197. return 'ssp';
  5198. }
  5199. else if ( settings.ajax || settings.sAjaxSource ) {
  5200. return 'ajax';
  5201. }
  5202. return 'dom';
  5203. }
  5204.  
  5205.  
  5206. DataTable = function( options )
  5207. {
  5208. /**
  5209. * Perform a jQuery selector action on the table's TR elements (from the tbody) and
  5210. * return the resulting jQuery object.
  5211. * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
  5212. * @param {object} [oOpts] Optional parameters for modifying the rows to be included
  5213. * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
  5214. * criterion ("applied") or all TR elements (i.e. no filter).
  5215. * @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
  5216. * Can be either 'current', whereby the current sorting of the table is used, or
  5217. * 'original' whereby the original order the data was read into the table is used.
  5218. * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
  5219. * ("current") or not ("all"). If 'current' is given, then order is assumed to be
  5220. * 'current' and filter is 'applied', regardless of what they might be given as.
  5221. * @returns {object} jQuery object, filtered by the given selector.
  5222. * @dtopt API
  5223. * @deprecated Since v1.10
  5224. *
  5225. * @example
  5226. * $(document).ready(function() {
  5227. * var oTable = $('#example').dataTable();
  5228. *
  5229. * // Highlight every second row
  5230. * oTable.$('tr:odd').css('backgroundColor', 'blue');
  5231. * } );
  5232. *
  5233. * @example
  5234. * $(document).ready(function() {
  5235. * var oTable = $('#example').dataTable();
  5236. *
  5237. * // Filter to rows with 'Webkit' in them, add a background colour and then
  5238. * // remove the filter, thus highlighting the 'Webkit' rows only.
  5239. * oTable.fnFilter('Webkit');
  5240. * oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
  5241. * oTable.fnFilter('');
  5242. * } );
  5243. */
  5244. this.$ = function ( sSelector, oOpts )
  5245. {
  5246. return this.api(true).$( sSelector, oOpts );
  5247. };
  5248.  
  5249.  
  5250. /**
  5251. * Almost identical to $ in operation, but in this case returns the data for the matched
  5252. * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
  5253. * rather than any descendants, so the data can be obtained for the row/cell. If matching
  5254. * rows are found, the data returned is the original data array/object that was used to
  5255. * create the row (or a generated array if from a DOM source).
  5256. *
  5257. * This method is often useful in-combination with $ where both functions are given the
  5258. * same parameters and the array indexes will match identically.
  5259. * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
  5260. * @param {object} [oOpts] Optional parameters for modifying the rows to be included
  5261. * @param {string} [oOpts.filter=none] Select elements that meet the current filter
  5262. * criterion ("applied") or all elements (i.e. no filter).
  5263. * @param {string} [oOpts.order=current] Order of the data in the processed array.
  5264. * Can be either 'current', whereby the current sorting of the table is used, or
  5265. * 'original' whereby the original order the data was read into the table is used.
  5266. * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
  5267. * ("current") or not ("all"). If 'current' is given, then order is assumed to be
  5268. * 'current' and filter is 'applied', regardless of what they might be given as.
  5269. * @returns {array} Data for the matched elements. If any elements, as a result of the
  5270. * selector, were not TR, TD or TH elements in the DataTable, they will have a null
  5271. * entry in the array.
  5272. * @dtopt API
  5273. * @deprecated Since v1.10
  5274. *
  5275. * @example
  5276. * $(document).ready(function() {
  5277. * var oTable = $('#example').dataTable();
  5278. *
  5279. * // Get the data from the first row in the table
  5280. * var data = oTable._('tr:first');
  5281. *
  5282. * // Do something useful with the data
  5283. * alert( "First cell is: "+data[0] );
  5284. * } );
  5285. *
  5286. * @example
  5287. * $(document).ready(function() {
  5288. * var oTable = $('#example').dataTable();
  5289. *
  5290. * // Filter to 'Webkit' and get all data for
  5291. * oTable.fnFilter('Webkit');
  5292. * var data = oTable._('tr', {"search": "applied"});
  5293. *
  5294. * // Do something with the data
  5295. * alert( data.length+" rows matched the search" );
  5296. * } );
  5297. */
  5298. this._ = function ( sSelector, oOpts )
  5299. {
  5300. return this.api(true).rows( sSelector, oOpts ).data();
  5301. };
  5302.  
  5303.  
  5304. /**
  5305. * Create a DataTables Api instance, with the currently selected tables for
  5306. * the Api's context.
  5307. * @param {boolean} [traditional=false] Set the API instance's context to be
  5308. * only the table referred to by the `DataTable.ext.iApiIndex` option, as was
  5309. * used in the API presented by DataTables 1.9- (i.e. the traditional mode),
  5310. * or if all tables captured in the jQuery object should be used.
  5311. * @return {DataTables.Api}
  5312. */
  5313. this.api = function ( traditional )
  5314. {
  5315. return traditional ?
  5316. new _Api(
  5317. _fnSettingsFromNode( this[ _ext.iApiIndex ] )
  5318. ) :
  5319. new _Api( this );
  5320. };
  5321.  
  5322.  
  5323. /**
  5324. * Add a single new row or multiple rows of data to the table. Please note
  5325. * that this is suitable for client-side processing only - if you are using
  5326. * server-side processing (i.e. "bServerSide": true), then to add data, you
  5327. * must add it to the data source, i.e. the server-side, through an Ajax call.
  5328. * @param {array|object} data The data to be added to the table. This can be:
  5329. * <ul>
  5330. * <li>1D array of data - add a single row with the data provided</li>
  5331. * <li>2D array of arrays - add multiple rows in a single call</li>
  5332. * <li>object - data object when using <i>mData</i></li>
  5333. * <li>array of objects - multiple data objects when using <i>mData</i></li>
  5334. * </ul>
  5335. * @param {bool} [redraw=true] redraw the table or not
  5336. * @returns {array} An array of integers, representing the list of indexes in
  5337. * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
  5338. * the table.
  5339. * @dtopt API
  5340. * @deprecated Since v1.10
  5341. *
  5342. * @example
  5343. * // Global var for counter
  5344. * var giCount = 2;
  5345. *
  5346. * $(document).ready(function() {
  5347. * $('#example').dataTable();
  5348. * } );
  5349. *
  5350. * function fnClickAddRow() {
  5351. * $('#example').dataTable().fnAddData( [
  5352. * giCount+".1",
  5353. * giCount+".2",
  5354. * giCount+".3",
  5355. * giCount+".4" ]
  5356. * );
  5357. *
  5358. * giCount++;
  5359. * }
  5360. */
  5361. this.fnAddData = function( data, redraw )
  5362. {
  5363. var api = this.api( true );
  5364.  
  5365. /* Check if we want to add multiple rows or not */
  5366. var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
  5367. api.rows.add( data ) :
  5368. api.row.add( data );
  5369.  
  5370. if ( redraw === undefined || redraw ) {
  5371. api.draw();
  5372. }
  5373.  
  5374. return rows.flatten().toArray();
  5375. };
  5376.  
  5377.  
  5378. /**
  5379. * This function will make DataTables recalculate the column sizes, based on the data
  5380. * contained in the table and the sizes applied to the columns (in the DOM, CSS or
  5381. * through the sWidth parameter). This can be useful when the width of the table's
  5382. * parent element changes (for example a window resize).
  5383. * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
  5384. * @dtopt API
  5385. * @deprecated Since v1.10
  5386. *
  5387. * @example
  5388. * $(document).ready(function() {
  5389. * var oTable = $('#example').dataTable( {
  5390. * "sScrollY": "200px",
  5391. * "bPaginate": false
  5392. * } );
  5393. *
  5394. * $(window).bind('resize', function () {
  5395. * oTable.fnAdjustColumnSizing();
  5396. * } );
  5397. * } );
  5398. */
  5399. this.fnAdjustColumnSizing = function ( bRedraw )
  5400. {
  5401. var api = this.api( true ).columns.adjust();
  5402. var settings = api.settings()[0];
  5403. var scroll = settings.oScroll;
  5404.  
  5405. if ( bRedraw === undefined || bRedraw ) {
  5406. api.draw( false );
  5407. }
  5408. else if ( scroll.sX !== "" || scroll.sY !== "" ) {
  5409. /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
  5410. _fnScrollDraw( settings );
  5411. }
  5412. };
  5413.  
  5414.  
  5415. /**
  5416. * Quickly and simply clear a table
  5417. * @param {bool} [bRedraw=true] redraw the table or not
  5418. * @dtopt API
  5419. * @deprecated Since v1.10
  5420. *
  5421. * @example
  5422. * $(document).ready(function() {
  5423. * var oTable = $('#example').dataTable();
  5424. *
  5425. * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
  5426. * oTable.fnClearTable();
  5427. * } );
  5428. */
  5429. this.fnClearTable = function( bRedraw )
  5430. {
  5431. var api = this.api( true ).clear();
  5432.  
  5433. if ( bRedraw === undefined || bRedraw ) {
  5434. api.draw();
  5435. }
  5436. };
  5437.  
  5438.  
  5439. /**
  5440. * The exact opposite of 'opening' a row, this function will close any rows which
  5441. * are currently 'open'.
  5442. * @param {node} nTr the table row to 'close'
  5443. * @returns {int} 0 on success, or 1 if failed (can't find the row)
  5444. * @dtopt API
  5445. * @deprecated Since v1.10
  5446. *
  5447. * @example
  5448. * $(document).ready(function() {
  5449. * var oTable;
  5450. *
  5451. * // 'open' an information row when a row is clicked on
  5452. * $('#example tbody tr').click( function () {
  5453. * if ( oTable.fnIsOpen(this) ) {
  5454. * oTable.fnClose( this );
  5455. * } else {
  5456. * oTable.fnOpen( this, "Temporary row opened", "info_row" );
  5457. * }
  5458. * } );
  5459. *
  5460. * oTable = $('#example').dataTable();
  5461. * } );
  5462. */
  5463. this.fnClose = function( nTr )
  5464. {
  5465. this.api( true ).row( nTr ).child.hide();
  5466. };
  5467.  
  5468.  
  5469. /**
  5470. * Remove a row for the table
  5471. * @param {mixed} target The index of the row from aoData to be deleted, or
  5472. * the TR element you want to delete
  5473. * @param {function|null} [callBack] Callback function
  5474. * @param {bool} [redraw=true] Redraw the table or not
  5475. * @returns {array} The row that was deleted
  5476. * @dtopt API
  5477. * @deprecated Since v1.10
  5478. *
  5479. * @example
  5480. * $(document).ready(function() {
  5481. * var oTable = $('#example').dataTable();
  5482. *
  5483. * // Immediately remove the first row
  5484. * oTable.fnDeleteRow( 0 );
  5485. * } );
  5486. */
  5487. this.fnDeleteRow = function( target, callback, redraw )
  5488. {
  5489. var api = this.api( true );
  5490. var rows = api.rows( target );
  5491. var settings = rows.settings()[0];
  5492. var data = settings.aoData[ rows[0][0] ];
  5493.  
  5494. rows.remove();
  5495.  
  5496. if ( callback ) {
  5497. callback.call( this, settings, data );
  5498. }
  5499.  
  5500. if ( redraw === undefined || redraw ) {
  5501. api.draw();
  5502. }
  5503.  
  5504. return data;
  5505. };
  5506.  
  5507.  
  5508. /**
  5509. * Restore the table to it's original state in the DOM by removing all of DataTables
  5510. * enhancements, alterations to the DOM structure of the table and event listeners.
  5511. * @param {boolean} [remove=false] Completely remove the table from the DOM
  5512. * @dtopt API
  5513. * @deprecated Since v1.10
  5514. *
  5515. * @example
  5516. * $(document).ready(function() {
  5517. * // This example is fairly pointless in reality, but shows how fnDestroy can be used
  5518. * var oTable = $('#example').dataTable();
  5519. * oTable.fnDestroy();
  5520. * } );
  5521. */
  5522. this.fnDestroy = function ( remove )
  5523. {
  5524. this.api( true ).destroy( remove );
  5525. };
  5526.  
  5527.  
  5528. /**
  5529. * Redraw the table
  5530. * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
  5531. * @dtopt API
  5532. * @deprecated Since v1.10
  5533. *
  5534. * @example
  5535. * $(document).ready(function() {
  5536. * var oTable = $('#example').dataTable();
  5537. *
  5538. * // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
  5539. * oTable.fnDraw();
  5540. * } );
  5541. */
  5542. this.fnDraw = function( complete )
  5543. {
  5544. // Note that this isn't an exact match to the old call to _fnDraw - it takes
  5545. // into account the new data, but can old position.
  5546. this.api( true ).draw( ! complete );
  5547. };
  5548.  
  5549.  
  5550. /**
  5551. * Filter the input based on data
  5552. * @param {string} sInput String to filter the table on
  5553. * @param {int|null} [iColumn] Column to limit filtering to
  5554. * @param {bool} [bRegex=false] Treat as regular expression or not
  5555. * @param {bool} [bSmart=true] Perform smart filtering or not
  5556. * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
  5557. * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
  5558. * @dtopt API
  5559. * @deprecated Since v1.10
  5560. *
  5561. * @example
  5562. * $(document).ready(function() {
  5563. * var oTable = $('#example').dataTable();
  5564. *
  5565. * // Sometime later - filter...
  5566. * oTable.fnFilter( 'test string' );
  5567. * } );
  5568. */
  5569. this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
  5570. {
  5571. var api = this.api( true );
  5572.  
  5573. if ( iColumn === null || iColumn === undefined ) {
  5574. api.search( sInput, bRegex, bSmart, bCaseInsensitive );
  5575. }
  5576. else {
  5577. api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );
  5578. }
  5579.  
  5580. api.draw();
  5581. };
  5582.  
  5583.  
  5584. /**
  5585. * Get the data for the whole table, an individual row or an individual cell based on the
  5586. * provided parameters.
  5587. * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
  5588. * a TR node then the data source for the whole row will be returned. If given as a
  5589. * TD/TH cell node then iCol will be automatically calculated and the data for the
  5590. * cell returned. If given as an integer, then this is treated as the aoData internal
  5591. * data index for the row (see fnGetPosition) and the data for that row used.
  5592. * @param {int} [col] Optional column index that you want the data of.
  5593. * @returns {array|object|string} If mRow is undefined, then the data for all rows is
  5594. * returned. If mRow is defined, just data for that row, and is iCol is
  5595. * defined, only data for the designated cell is returned.
  5596. * @dtopt API
  5597. * @deprecated Since v1.10
  5598. *
  5599. * @example
  5600. * // Row data
  5601. * $(document).ready(function() {
  5602. * oTable = $('#example').dataTable();
  5603. *
  5604. * oTable.$('tr').click( function () {
  5605. * var data = oTable.fnGetData( this );
  5606. * // ... do something with the array / object of data for the row
  5607. * } );
  5608. * } );
  5609. *
  5610. * @example
  5611. * // Individual cell data
  5612. * $(document).ready(function() {
  5613. * oTable = $('#example').dataTable();
  5614. *
  5615. * oTable.$('td').click( function () {
  5616. * var sData = oTable.fnGetData( this );
  5617. * alert( 'The cell clicked on had the value of '+sData );
  5618. * } );
  5619. * } );
  5620. */
  5621. this.fnGetData = function( src, col )
  5622. {
  5623. var api = this.api( true );
  5624.  
  5625. if ( src !== undefined ) {
  5626. var type = src.nodeName ? src.nodeName.toLowerCase() : '';
  5627.  
  5628. return col !== undefined || type == 'td' || type == 'th' ?
  5629. api.cell( src, col ).data() :
  5630. api.row( src ).data() || null;
  5631. }
  5632.  
  5633. return api.data().toArray();
  5634. };
  5635.  
  5636.  
  5637. /**
  5638. * Get an array of the TR nodes that are used in the table's body. Note that you will
  5639. * typically want to use the '$' API method in preference to this as it is more
  5640. * flexible.
  5641. * @param {int} [iRow] Optional row index for the TR element you want
  5642. * @returns {array|node} If iRow is undefined, returns an array of all TR elements
  5643. * in the table's body, or iRow is defined, just the TR element requested.
  5644. * @dtopt API
  5645. * @deprecated Since v1.10
  5646. *
  5647. * @example
  5648. * $(document).ready(function() {
  5649. * var oTable = $('#example').dataTable();
  5650. *
  5651. * // Get the nodes from the table
  5652. * var nNodes = oTable.fnGetNodes( );
  5653. * } );
  5654. */
  5655. this.fnGetNodes = function( iRow )
  5656. {
  5657. var api = this.api( true );
  5658.  
  5659. return iRow !== undefined ?
  5660. api.row( iRow ).node() :
  5661. api.rows().nodes().flatten().toArray();
  5662. };
  5663.  
  5664.  
  5665. /**
  5666. * Get the array indexes of a particular cell from it's DOM element
  5667. * and column index including hidden columns
  5668. * @param {node} node this can either be a TR, TD or TH in the table's body
  5669. * @returns {int} If nNode is given as a TR, then a single index is returned, or
  5670. * if given as a cell, an array of [row index, column index (visible),
  5671. * column index (all)] is given.
  5672. * @dtopt API
  5673. * @deprecated Since v1.10
  5674. *
  5675. * @example
  5676. * $(document).ready(function() {
  5677. * $('#example tbody td').click( function () {
  5678. * // Get the position of the current data from the node
  5679. * var aPos = oTable.fnGetPosition( this );
  5680. *
  5681. * // Get the data array for this row
  5682. * var aData = oTable.fnGetData( aPos[0] );
  5683. *
  5684. * // Update the data array and return the value
  5685. * aData[ aPos[1] ] = 'clicked';
  5686. * this.innerHTML = 'clicked';
  5687. * } );
  5688. *
  5689. * // Init DataTables
  5690. * oTable = $('#example').dataTable();
  5691. * } );
  5692. */
  5693. this.fnGetPosition = function( node )
  5694. {
  5695. var api = this.api( true );
  5696. var nodeName = node.nodeName.toUpperCase();
  5697.  
  5698. if ( nodeName == 'TR' ) {
  5699. return api.row( node ).index();
  5700. }
  5701. else if ( nodeName == 'TD' || nodeName == 'TH' ) {
  5702. var cell = api.cell( node ).index();
  5703.  
  5704. return [
  5705. cell.row,
  5706. cell.columnVisible,
  5707. cell.column
  5708. ];
  5709. }
  5710. return null;
  5711. };
  5712.  
  5713.  
  5714. /**
  5715. * Check to see if a row is 'open' or not.
  5716. * @param {node} nTr the table row to check
  5717. * @returns {boolean} true if the row is currently open, false otherwise
  5718. * @dtopt API
  5719. * @deprecated Since v1.10
  5720. *
  5721. * @example
  5722. * $(document).ready(function() {
  5723. * var oTable;
  5724. *
  5725. * // 'open' an information row when a row is clicked on
  5726. * $('#example tbody tr').click( function () {
  5727. * if ( oTable.fnIsOpen(this) ) {
  5728. * oTable.fnClose( this );
  5729. * } else {
  5730. * oTable.fnOpen( this, "Temporary row opened", "info_row" );
  5731. * }
  5732. * } );
  5733. *
  5734. * oTable = $('#example').dataTable();
  5735. * } );
  5736. */
  5737. this.fnIsOpen = function( nTr )
  5738. {
  5739. return this.api( true ).row( nTr ).child.isShown();
  5740. };
  5741.  
  5742.  
  5743. /**
  5744. * This function will place a new row directly after a row which is currently
  5745. * on display on the page, with the HTML contents that is passed into the
  5746. * function. This can be used, for example, to ask for confirmation that a
  5747. * particular record should be deleted.
  5748. * @param {node} nTr The table row to 'open'
  5749. * @param {string|node|jQuery} mHtml The HTML to put into the row
  5750. * @param {string} sClass Class to give the new TD cell
  5751. * @returns {node} The row opened. Note that if the table row passed in as the
  5752. * first parameter, is not found in the table, this method will silently
  5753. * return.
  5754. * @dtopt API
  5755. * @deprecated Since v1.10
  5756. *
  5757. * @example
  5758. * $(document).ready(function() {
  5759. * var oTable;
  5760. *
  5761. * // 'open' an information row when a row is clicked on
  5762. * $('#example tbody tr').click( function () {
  5763. * if ( oTable.fnIsOpen(this) ) {
  5764. * oTable.fnClose( this );
  5765. * } else {
  5766. * oTable.fnOpen( this, "Temporary row opened", "info_row" );
  5767. * }
  5768. * } );
  5769. *
  5770. * oTable = $('#example').dataTable();
  5771. * } );
  5772. */
  5773. this.fnOpen = function( nTr, mHtml, sClass )
  5774. {
  5775. return this.api( true )
  5776. .row( nTr )
  5777. .child( mHtml, sClass )
  5778. .show()
  5779. .child()[0];
  5780. };
  5781.  
  5782.  
  5783. /**
  5784. * Change the pagination - provides the internal logic for pagination in a simple API
  5785. * function. With this function you can have a DataTables table go to the next,
  5786. * previous, first or last pages.
  5787. * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
  5788. * or page number to jump to (integer), note that page 0 is the first page.
  5789. * @param {bool} [bRedraw=true] Redraw the table or not
  5790. * @dtopt API
  5791. * @deprecated Since v1.10
  5792. *
  5793. * @example
  5794. * $(document).ready(function() {
  5795. * var oTable = $('#example').dataTable();
  5796. * oTable.fnPageChange( 'next' );
  5797. * } );
  5798. */
  5799. this.fnPageChange = function ( mAction, bRedraw )
  5800. {
  5801. var api = this.api( true ).page( mAction );
  5802.  
  5803. if ( bRedraw === undefined || bRedraw ) {
  5804. api.draw(false);
  5805. }
  5806. };
  5807.  
  5808.  
  5809. /**
  5810. * Show a particular column
  5811. * @param {int} iCol The column whose display should be changed
  5812. * @param {bool} bShow Show (true) or hide (false) the column
  5813. * @param {bool} [bRedraw=true] Redraw the table or not
  5814. * @dtopt API
  5815. * @deprecated Since v1.10
  5816. *
  5817. * @example
  5818. * $(document).ready(function() {
  5819. * var oTable = $('#example').dataTable();
  5820. *
  5821. * // Hide the second column after initialisation
  5822. * oTable.fnSetColumnVis( 1, false );
  5823. * } );
  5824. */
  5825. this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
  5826. {
  5827. var api = this.api( true ).column( iCol ).visible( bShow );
  5828.  
  5829. if ( bRedraw === undefined || bRedraw ) {
  5830. api.columns.adjust().draw();
  5831. }
  5832. };
  5833.  
  5834.  
  5835. /**
  5836. * Get the settings for a particular table for external manipulation
  5837. * @returns {object} DataTables settings object. See
  5838. * {@link DataTable.models.oSettings}
  5839. * @dtopt API
  5840. * @deprecated Since v1.10
  5841. *
  5842. * @example
  5843. * $(document).ready(function() {
  5844. * var oTable = $('#example').dataTable();
  5845. * var oSettings = oTable.fnSettings();
  5846. *
  5847. * // Show an example parameter from the settings
  5848. * alert( oSettings._iDisplayStart );
  5849. * } );
  5850. */
  5851. this.fnSettings = function()
  5852. {
  5853. return _fnSettingsFromNode( this[_ext.iApiIndex] );
  5854. };
  5855.  
  5856.  
  5857. /**
  5858. * Sort the table by a particular column
  5859. * @param {int} iCol the data index to sort on. Note that this will not match the
  5860. * 'display index' if you have hidden data entries
  5861. * @dtopt API
  5862. * @deprecated Since v1.10
  5863. *
  5864. * @example
  5865. * $(document).ready(function() {
  5866. * var oTable = $('#example').dataTable();
  5867. *
  5868. * // Sort immediately with columns 0 and 1
  5869. * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
  5870. * } );
  5871. */
  5872. this.fnSort = function( aaSort )
  5873. {
  5874. this.api( true ).order( aaSort ).draw();
  5875. };
  5876.  
  5877.  
  5878. /**
  5879. * Attach a sort listener to an element for a given column
  5880. * @param {node} nNode the element to attach the sort listener to
  5881. * @param {int} iColumn the column that a click on this node will sort on
  5882. * @param {function} [fnCallback] callback function when sort is run
  5883. * @dtopt API
  5884. * @deprecated Since v1.10
  5885. *
  5886. * @example
  5887. * $(document).ready(function() {
  5888. * var oTable = $('#example').dataTable();
  5889. *
  5890. * // Sort on column 1, when 'sorter' is clicked on
  5891. * oTable.fnSortListener( document.getElementById('sorter'), 1 );
  5892. * } );
  5893. */
  5894. this.fnSortListener = function( nNode, iColumn, fnCallback )
  5895. {
  5896. this.api( true ).order.listener( nNode, iColumn, fnCallback );
  5897. };
  5898.  
  5899.  
  5900. /**
  5901. * Update a table cell or row - this method will accept either a single value to
  5902. * update the cell with, an array of values with one element for each column or
  5903. * an object in the same format as the original data source. The function is
  5904. * self-referencing in order to make the multi column updates easier.
  5905. * @param {object|array|string} mData Data to update the cell/row with
  5906. * @param {node|int} mRow TR element you want to update or the aoData index
  5907. * @param {int} [iColumn] The column to update, give as null or undefined to
  5908. * update a whole row.
  5909. * @param {bool} [bRedraw=true] Redraw the table or not
  5910. * @param {bool} [bAction=true] Perform pre-draw actions or not
  5911. * @returns {int} 0 on success, 1 on error
  5912. * @dtopt API
  5913. * @deprecated Since v1.10
  5914. *
  5915. * @example
  5916. * $(document).ready(function() {
  5917. * var oTable = $('#example').dataTable();
  5918. * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
  5919. * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
  5920. * } );
  5921. */
  5922. this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
  5923. {
  5924. var api = this.api( true );
  5925.  
  5926. if ( iColumn === undefined || iColumn === null ) {
  5927. api.row( mRow ).data( mData );
  5928. }
  5929. else {
  5930. api.cell( mRow, iColumn ).data( mData );
  5931. }
  5932.  
  5933. if ( bAction === undefined || bAction ) {
  5934. api.columns.adjust();
  5935. }
  5936.  
  5937. if ( bRedraw === undefined || bRedraw ) {
  5938. api.draw();
  5939. }
  5940. return 0;
  5941. };
  5942.  
  5943.  
  5944. /**
  5945. * Provide a common method for plug-ins to check the version of DataTables being used, in order
  5946. * to ensure compatibility.
  5947. * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
  5948. * formats "X" and "X.Y" are also acceptable.
  5949. * @returns {boolean} true if this version of DataTables is greater or equal to the required
  5950. * version, or false if this version of DataTales is not suitable
  5951. * @method
  5952. * @dtopt API
  5953. * @deprecated Since v1.10
  5954. *
  5955. * @example
  5956. * $(document).ready(function() {
  5957. * var oTable = $('#example').dataTable();
  5958. * alert( oTable.fnVersionCheck( '1.9.0' ) );
  5959. * } );
  5960. */
  5961. this.fnVersionCheck = _ext.fnVersionCheck;
  5962.  
  5963.  
  5964. var _that = this;
  5965. var emptyInit = options === undefined;
  5966. var len = this.length;
  5967.  
  5968. if ( emptyInit ) {
  5969. options = {};
  5970. }
  5971.  
  5972. this.oApi = this.internal = _ext.internal;
  5973.  
  5974. // Extend with old style plug-in API methods
  5975. for ( var fn in DataTable.ext.internal ) {
  5976. if ( fn ) {
  5977. this[fn] = _fnExternApiFunc(fn);
  5978. }
  5979. }
  5980.  
  5981. this.each(function() {
  5982. // For each initialisation we want to give it a clean initialisation
  5983. // object that can be bashed around
  5984. var o = {};
  5985. var oInit = len > 1 ? // optimisation for single table case
  5986. _fnExtend( o, options, true ) :
  5987. options;
  5988.  
  5989. /*global oInit,_that,emptyInit*/
  5990. var i=0, iLen, j, jLen, k, kLen;
  5991. var sId = this.getAttribute( 'id' );
  5992. var bInitHandedOff = false;
  5993. var defaults = DataTable.defaults;
  5994.  
  5995.  
  5996. /* Sanity check */
  5997. if ( this.nodeName.toLowerCase() != 'table' )
  5998. {
  5999. _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
  6000. return;
  6001. }
  6002.  
  6003. /* Backwards compatibility for the defaults */
  6004. _fnCompatOpts( defaults );
  6005. _fnCompatCols( defaults.column );
  6006.  
  6007. /* Convert the camel-case defaults to Hungarian */
  6008. _fnCamelToHungarian( defaults, defaults, true );
  6009. _fnCamelToHungarian( defaults.column, defaults.column, true );
  6010.  
  6011. /* Setting up the initialisation object */
  6012. _fnCamelToHungarian( defaults, oInit );
  6013.  
  6014. /* Check to see if we are re-initialising a table */
  6015. var allSettings = DataTable.settings;
  6016. for ( i=0, iLen=allSettings.length ; i<iLen ; i++ )
  6017. {
  6018. /* Base check on table node */
  6019. if ( allSettings[i].nTable == this )
  6020. {
  6021. var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
  6022. var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
  6023.  
  6024. if ( emptyInit || bRetrieve )
  6025. {
  6026. return allSettings[i].oInstance;
  6027. }
  6028. else if ( bDestroy )
  6029. {
  6030. allSettings[i].oInstance.fnDestroy();
  6031. break;
  6032. }
  6033. else
  6034. {
  6035. _fnLog( allSettings[i], 0, 'Cannot reinitialise DataTable', 3 );
  6036. return;
  6037. }
  6038. }
  6039.  
  6040. /* If the element we are initialising has the same ID as a table which was previously
  6041. * initialised, but the table nodes don't match (from before) then we destroy the old
  6042. * instance by simply deleting it. This is under the assumption that the table has been
  6043. * destroyed by other methods. Anyone using non-id selectors will need to do this manually
  6044. */
  6045. if ( allSettings[i].sTableId == this.id )
  6046. {
  6047. allSettings.splice( i, 1 );
  6048. break;
  6049. }
  6050. }
  6051.  
  6052. /* Ensure the table has an ID - required for accessibility */
  6053. if ( sId === null || sId === "" )
  6054. {
  6055. sId = "DataTables_Table_"+(DataTable.ext._unique++);
  6056. this.id = sId;
  6057. }
  6058.  
  6059. /* Create the settings object for this table and set some of the default parameters */
  6060. var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
  6061. "nTable": this,
  6062. "oApi": _that.internal,
  6063. "oInit": oInit,
  6064. "sDestroyWidth": $(this)[0].style.width,
  6065. "sInstance": sId,
  6066. "sTableId": sId
  6067. } );
  6068. allSettings.push( oSettings );
  6069.  
  6070. // Need to add the instance after the instance after the settings object has been added
  6071. // to the settings array, so we can self reference the table instance if more than one
  6072. oSettings.oInstance = (_that.length===1) ? _that : $(this).dataTable();
  6073.  
  6074. // Backwards compatibility, before we apply all the defaults
  6075. _fnCompatOpts( oInit );
  6076.  
  6077. if ( oInit.oLanguage )
  6078. {
  6079. _fnLanguageCompat( oInit.oLanguage );
  6080. }
  6081.  
  6082. // If the length menu is given, but the init display length is not, use the length menu
  6083. if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
  6084. {
  6085. oInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?
  6086. oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
  6087. }
  6088.  
  6089. // Apply the defaults and init options to make a single init object will all
  6090. // options defined from defaults and instance options.
  6091. oInit = _fnExtend( $.extend( true, {}, defaults ), oInit );
  6092.  
  6093.  
  6094. // Map the initialisation options onto the settings object
  6095. _fnMap( oSettings.oFeatures, oInit, [
  6096. "bPaginate",
  6097. "bLengthChange",
  6098. "bFilter",
  6099. "bSort",
  6100. "bSortMulti",
  6101. "bInfo",
  6102. "bProcessing",
  6103. "bAutoWidth",
  6104. "bSortClasses",
  6105. "bServerSide",
  6106. "bDeferRender"
  6107. ] );
  6108. _fnMap( oSettings, oInit, [
  6109. "asStripeClasses",
  6110. "ajax",
  6111. "fnServerData",
  6112. "fnFormatNumber",
  6113. "sServerMethod",
  6114. "aaSorting",
  6115. "aaSortingFixed",
  6116. "aLengthMenu",
  6117. "sPaginationType",
  6118. "sAjaxSource",
  6119. "sAjaxDataProp",
  6120. "iStateDuration",
  6121. "sDom",
  6122. "bSortCellsTop",
  6123. "iTabIndex",
  6124. "fnStateLoadCallback",
  6125. "fnStateSaveCallback",
  6126. "renderer",
  6127. "searchDelay",
  6128. [ "iCookieDuration", "iStateDuration" ], // backwards compat
  6129. [ "oSearch", "oPreviousSearch" ],
  6130. [ "aoSearchCols", "aoPreSearchCols" ],
  6131. [ "iDisplayLength", "_iDisplayLength" ],
  6132. [ "bJQueryUI", "bJUI" ]
  6133. ] );
  6134. _fnMap( oSettings.oScroll, oInit, [
  6135. [ "sScrollX", "sX" ],
  6136. [ "sScrollXInner", "sXInner" ],
  6137. [ "sScrollY", "sY" ],
  6138. [ "bScrollCollapse", "bCollapse" ]
  6139. ] );
  6140. _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
  6141.  
  6142. /* Callback functions which are array driven */
  6143. _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );
  6144. _fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );
  6145. _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );
  6146. _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );
  6147. _fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );
  6148. _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );
  6149. _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );
  6150. _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );
  6151. _fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' );
  6152. _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' );
  6153. _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' );
  6154.  
  6155. var oClasses = oSettings.oClasses;
  6156.  
  6157. // @todo Remove in 1.11
  6158. if ( oInit.bJQueryUI )
  6159. {
  6160. /* Use the JUI classes object for display. You could clone the oStdClasses object if
  6161. * you want to have multiple tables with multiple independent classes
  6162. */
  6163. $.extend( oClasses, DataTable.ext.oJUIClasses, oInit.oClasses );
  6164.  
  6165. if ( oInit.sDom === defaults.sDom && defaults.sDom === "lfrtip" )
  6166. {
  6167. /* Set the DOM to use a layout suitable for jQuery UI's theming */
  6168. oSettings.sDom = '<"H"lfr>t<"F"ip>';
  6169. }
  6170.  
  6171. if ( ! oSettings.renderer ) {
  6172. oSettings.renderer = 'jqueryui';
  6173. }
  6174. else if ( $.isPlainObject( oSettings.renderer ) && ! oSettings.renderer.header ) {
  6175. oSettings.renderer.header = 'jqueryui';
  6176. }
  6177. }
  6178. else
  6179. {
  6180. $.extend( oClasses, DataTable.ext.classes, oInit.oClasses );
  6181. }
  6182. $(this).addClass( oClasses.sTable );
  6183.  
  6184. /* Calculate the scroll bar width and cache it for use later on */
  6185. if ( oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "" )
  6186. {
  6187. oSettings.oScroll.iBarWidth = _fnScrollBarWidth();
  6188. }
  6189. if ( oSettings.oScroll.sX === true ) { // Easy initialisation of x-scrolling
  6190. oSettings.oScroll.sX = '100%';
  6191. }
  6192.  
  6193. if ( oSettings.iInitDisplayStart === undefined )
  6194. {
  6195. /* Display start point, taking into account the save saving */
  6196. oSettings.iInitDisplayStart = oInit.iDisplayStart;
  6197. oSettings._iDisplayStart = oInit.iDisplayStart;
  6198. }
  6199.  
  6200. if ( oInit.iDeferLoading !== null )
  6201. {
  6202. oSettings.bDeferLoading = true;
  6203. var tmp = $.isArray( oInit.iDeferLoading );
  6204. oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
  6205. oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
  6206. }
  6207.  
  6208. /* Language definitions */
  6209. var oLanguage = oSettings.oLanguage;
  6210. $.extend( true, oLanguage, oInit.oLanguage );
  6211.  
  6212. if ( oLanguage.sUrl !== "" )
  6213. {
  6214. /* Get the language definitions from a file - because this Ajax call makes the language
  6215. * get async to the remainder of this function we use bInitHandedOff to indicate that
  6216. * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
  6217. */
  6218. $.ajax( {
  6219. dataType: 'json',
  6220. url: oLanguage.sUrl,
  6221. success: function ( json ) {
  6222. _fnLanguageCompat( json );
  6223. _fnCamelToHungarian( defaults.oLanguage, json );
  6224. $.extend( true, oLanguage, json );
  6225. _fnInitialise( oSettings );
  6226. },
  6227. error: function () {
  6228. // Error occurred loading language file, continue on as best we can
  6229. _fnInitialise( oSettings );
  6230. }
  6231. } );
  6232. bInitHandedOff = true;
  6233. }
  6234.  
  6235. /*
  6236. * Stripes
  6237. */
  6238. if ( oInit.asStripeClasses === null )
  6239. {
  6240. oSettings.asStripeClasses =[
  6241. oClasses.sStripeOdd,
  6242. oClasses.sStripeEven
  6243. ];
  6244. }
  6245.  
  6246. /* Remove row stripe classes if they are already on the table row */
  6247. var stripeClasses = oSettings.asStripeClasses;
  6248. var rowOne = $('tbody tr:eq(0)', this);
  6249. if ( $.inArray( true, $.map( stripeClasses, function(el, i) {
  6250. return rowOne.hasClass(el);
  6251. } ) ) !== -1 ) {
  6252. $('tbody tr', this).removeClass( stripeClasses.join(' ') );
  6253. oSettings.asDestroyStripes = stripeClasses.slice();
  6254. }
  6255.  
  6256. /*
  6257. * Columns
  6258. * See if we should load columns automatically or use defined ones
  6259. */
  6260. var anThs = [];
  6261. var aoColumnsInit;
  6262. var nThead = this.getElementsByTagName('thead');
  6263. if ( nThead.length !== 0 )
  6264. {
  6265. _fnDetectHeader( oSettings.aoHeader, nThead[0] );
  6266. anThs = _fnGetUniqueThs( oSettings );
  6267. }
  6268.  
  6269. /* If not given a column array, generate one with nulls */
  6270. if ( oInit.aoColumns === null )
  6271. {
  6272. aoColumnsInit = [];
  6273. for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
  6274. {
  6275. aoColumnsInit.push( null );
  6276. }
  6277. }
  6278. else
  6279. {
  6280. aoColumnsInit = oInit.aoColumns;
  6281. }
  6282.  
  6283. /* Add the columns */
  6284. for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
  6285. {
  6286. _fnAddColumn( oSettings, anThs ? anThs[i] : null );
  6287. }
  6288.  
  6289. /* Apply the column definitions */
  6290. _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
  6291. _fnColumnOptions( oSettings, iCol, oDef );
  6292. } );
  6293.  
  6294. /* HTML5 attribute detection - build an mData object automatically if the
  6295. * attributes are found
  6296. */
  6297. if ( rowOne.length ) {
  6298. var a = function ( cell, name ) {
  6299. return cell.getAttribute( 'data-'+name ) ? name : null;
  6300. };
  6301.  
  6302. $.each( _fnGetRowElements( oSettings, rowOne[0] ).cells, function (i, cell) {
  6303. var col = oSettings.aoColumns[i];
  6304.  
  6305. if ( col.mData === i ) {
  6306. var sort = a( cell, 'sort' ) || a( cell, 'order' );
  6307. var filter = a( cell, 'filter' ) || a( cell, 'search' );
  6308.  
  6309. if ( sort !== null || filter !== null ) {
  6310. col.mData = {
  6311. _: i+'.display',
  6312. sort: sort !== null ? i+'.@data-'+sort : undefined,
  6313. type: sort !== null ? i+'.@data-'+sort : undefined,
  6314. filter: filter !== null ? i+'.@data-'+filter : undefined
  6315. };
  6316.  
  6317. _fnColumnOptions( oSettings, i );
  6318. }
  6319. }
  6320. } );
  6321. }
  6322.  
  6323. var features = oSettings.oFeatures;
  6324.  
  6325. /* Must be done after everything which can be overridden by the state saving! */
  6326. if ( oInit.bStateSave )
  6327. {
  6328. features.bStateSave = true;
  6329. _fnLoadState( oSettings, oInit );
  6330. _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
  6331. }
  6332.  
  6333.  
  6334. /*
  6335. * Sorting
  6336. * @todo For modularisation (1.11) this needs to do into a sort start up handler
  6337. */
  6338.  
  6339. // If aaSorting is not defined, then we use the first indicator in asSorting
  6340. // in case that has been altered, so the default sort reflects that option
  6341. if ( oInit.aaSorting === undefined )
  6342. {
  6343. var sorting = oSettings.aaSorting;
  6344. for ( i=0, iLen=sorting.length ; i<iLen ; i++ )
  6345. {
  6346. sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
  6347. }
  6348. }
  6349.  
  6350. /* Do a first pass on the sorting classes (allows any size changes to be taken into
  6351. * account, and also will apply sorting disabled classes if disabled
  6352. */
  6353. _fnSortingClasses( oSettings );
  6354.  
  6355. if ( features.bSort )
  6356. {
  6357. _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
  6358. if ( oSettings.bSorted ) {
  6359. var aSort = _fnSortFlatten( oSettings );
  6360. var sortedColumns = {};
  6361.  
  6362. $.each( aSort, function (i, val) {
  6363. sortedColumns[ val.src ] = val.dir;
  6364. } );
  6365.  
  6366. _fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
  6367. _fnSortAria( oSettings );
  6368. }
  6369. } );
  6370. }
  6371.  
  6372. _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
  6373. if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
  6374. _fnSortingClasses( oSettings );
  6375. }
  6376. }, 'sc' );
  6377.  
  6378.  
  6379. /*
  6380. * Final init
  6381. * Cache the header, body and footer as required, creating them if needed
  6382. */
  6383.  
  6384. /* Browser support detection */
  6385. _fnBrowserDetect( oSettings );
  6386.  
  6387. // Work around for Webkit bug 83867 - store the caption-side before removing from doc
  6388. var captions = $(this).children('caption').each( function () {
  6389. this._captionSide = $(this).css('caption-side');
  6390. } );
  6391.  
  6392. var thead = $(this).children('thead');
  6393. if ( thead.length === 0 )
  6394. {
  6395. thead = $('<thead/>').appendTo(this);
  6396. }
  6397. oSettings.nTHead = thead[0];
  6398.  
  6399. var tbody = $(this).children('tbody');
  6400. if ( tbody.length === 0 )
  6401. {
  6402. tbody = $('<tbody/>').appendTo(this);
  6403. }
  6404. oSettings.nTBody = tbody[0];
  6405.  
  6406. var tfoot = $(this).children('tfoot');
  6407. if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") )
  6408. {
  6409. // If we are a scrolling table, and no footer has been given, then we need to create
  6410. // a tfoot element for the caption element to be appended to
  6411. tfoot = $('<tfoot/>').appendTo(this);
  6412. }
  6413.  
  6414. if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
  6415. $(this).addClass( oClasses.sNoFooter );
  6416. }
  6417. else if ( tfoot.length > 0 ) {
  6418. oSettings.nTFoot = tfoot[0];
  6419. _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
  6420. }
  6421.  
  6422. /* Check if there is data passing into the constructor */
  6423. if ( oInit.aaData )
  6424. {
  6425. for ( i=0 ; i<oInit.aaData.length ; i++ )
  6426. {
  6427. _fnAddData( oSettings, oInit.aaData[ i ] );
  6428. }
  6429. }
  6430. else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' )
  6431. {
  6432. /* Grab the data from the page - only do this when deferred loading or no Ajax
  6433. * source since there is no point in reading the DOM data if we are then going
  6434. * to replace it with Ajax data
  6435. */
  6436. _fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
  6437. }
  6438.  
  6439. /* Copy the data index array */
  6440. oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
  6441.  
  6442. /* Initialisation complete - table can be drawn */
  6443. oSettings.bInitialised = true;
  6444.  
  6445. /* Check if we need to initialise the table (it might not have been handed off to the
  6446. * language processor)
  6447. */
  6448. if ( bInitHandedOff === false )
  6449. {
  6450. _fnInitialise( oSettings );
  6451. }
  6452. } );
  6453. _that = null;
  6454. return this;
  6455. };
  6456.  
  6457.  
  6458.  
  6459. /**
  6460. * Computed structure of the DataTables API, defined by the options passed to
  6461. * `DataTable.Api.register()` when building the API.
  6462. *
  6463. * The structure is built in order to speed creation and extension of the Api
  6464. * objects since the extensions are effectively pre-parsed.
  6465. *
  6466. * The array is an array of objects with the following structure, where this
  6467. * base array represents the Api prototype base:
  6468. *
  6469. * [
  6470. * {
  6471. * name: 'data' -- string - Property name
  6472. * val: function () {}, -- function - Api method (or undefined if just an object
  6473. * methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
  6474. * propExt: [ ... ] -- array - Array of Api object definitions to extend the property
  6475. * },
  6476. * {
  6477. * name: 'row'
  6478. * val: {},
  6479. * methodExt: [ ... ],
  6480. * propExt: [
  6481. * {
  6482. * name: 'data'
  6483. * val: function () {},
  6484. * methodExt: [ ... ],
  6485. * propExt: [ ... ]
  6486. * },
  6487. * ...
  6488. * ]
  6489. * }
  6490. * ]
  6491. *
  6492. * @type {Array}
  6493. * @ignore
  6494. */
  6495. var __apiStruct = [];
  6496.  
  6497.  
  6498. /**
  6499. * `Array.prototype` reference.
  6500. *
  6501. * @type object
  6502. * @ignore
  6503. */
  6504. var __arrayProto = Array.prototype;
  6505.  
  6506.  
  6507. /**
  6508. * Abstraction for `context` parameter of the `Api` constructor to allow it to
  6509. * take several different forms for ease of use.
  6510. *
  6511. * Each of the input parameter types will be converted to a DataTables settings
  6512. * object where possible.
  6513. *
  6514. * @param {string|node|jQuery|object} mixed DataTable identifier. Can be one
  6515. * of:
  6516. *
  6517. * * `string` - jQuery selector. Any DataTables' matching the given selector
  6518. * with be found and used.
  6519. * * `node` - `TABLE` node which has already been formed into a DataTable.
  6520. * * `jQuery` - A jQuery object of `TABLE` nodes.
  6521. * * `object` - DataTables settings object
  6522. * * `DataTables.Api` - API instance
  6523. * @return {array|null} Matching DataTables settings objects. `null` or
  6524. * `undefined` is returned if no matching DataTable is found.
  6525. * @ignore
  6526. */
  6527. var _toSettings = function ( mixed )
  6528. {
  6529. var idx, jq;
  6530. var settings = DataTable.settings;
  6531. var tables = $.map( settings, function (el, i) {
  6532. return el.nTable;
  6533. } );
  6534.  
  6535. if ( ! mixed ) {
  6536. return [];
  6537. }
  6538. else if ( mixed.nTable && mixed.oApi ) {
  6539. // DataTables settings object
  6540. return [ mixed ];
  6541. }
  6542. else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {
  6543. // Table node
  6544. idx = $.inArray( mixed, tables );
  6545. return idx !== -1 ? [ settings[idx] ] : null;
  6546. }
  6547. else if ( mixed && typeof mixed.settings === 'function' ) {
  6548. return mixed.settings().toArray();
  6549. }
  6550. else if ( typeof mixed === 'string' ) {
  6551. // jQuery selector
  6552. jq = $(mixed);
  6553. }
  6554. else if ( mixed instanceof $ ) {
  6555. // jQuery object (also DataTables instance)
  6556. jq = mixed;
  6557. }
  6558.  
  6559. if ( jq ) {
  6560. return jq.map( function(i) {
  6561. idx = $.inArray( this, tables );
  6562. return idx !== -1 ? settings[idx] : null;
  6563. } ).toArray();
  6564. }
  6565. };
  6566.  
  6567.  
  6568. /**
  6569. * DataTables API class - used to control and interface with one or more
  6570. * DataTables enhanced tables.
  6571. *
  6572. * The API class is heavily based on jQuery, presenting a chainable interface
  6573. * that you can use to interact with tables. Each instance of the API class has
  6574. * a "context" - i.e. the tables that it will operate on. This could be a single
  6575. * table, all tables on a page or a sub-set thereof.
  6576. *
  6577. * Additionally the API is designed to allow you to easily work with the data in
  6578. * the tables, retrieving and manipulating it as required. This is done by
  6579. * presenting the API class as an array like interface. The contents of the
  6580. * array depend upon the actions requested by each method (for example
  6581. * `rows().nodes()` will return an array of nodes, while `rows().data()` will
  6582. * return an array of objects or arrays depending upon your table's
  6583. * configuration). The API object has a number of array like methods (`push`,
  6584. * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
  6585. * `unique` etc) to assist your working with the data held in a table.
  6586. *
  6587. * Most methods (those which return an Api instance) are chainable, which means
  6588. * the return from a method call also has all of the methods available that the
  6589. * top level object had. For example, these two calls are equivalent:
  6590. *
  6591. * // Not chained
  6592. * api.row.add( {...} );
  6593. * api.draw();
  6594. *
  6595. * // Chained
  6596. * api.row.add( {...} ).draw();
  6597. *
  6598. * @class DataTable.Api
  6599. * @param {array|object|string|jQuery} context DataTable identifier. This is
  6600. * used to define which DataTables enhanced tables this API will operate on.
  6601. * Can be one of:
  6602. *
  6603. * * `string` - jQuery selector. Any DataTables' matching the given selector
  6604. * with be found and used.
  6605. * * `node` - `TABLE` node which has already been formed into a DataTable.
  6606. * * `jQuery` - A jQuery object of `TABLE` nodes.
  6607. * * `object` - DataTables settings object
  6608. * @param {array} [data] Data to initialise the Api instance with.
  6609. *
  6610. * @example
  6611. * // Direct initialisation during DataTables construction
  6612. * var api = $('#example').DataTable();
  6613. *
  6614. * @example
  6615. * // Initialisation using a DataTables jQuery object
  6616. * var api = $('#example').dataTable().api();
  6617. *
  6618. * @example
  6619. * // Initialisation as a constructor
  6620. * var api = new $.fn.DataTable.Api( 'table.dataTable' );
  6621. */
  6622. _Api = function ( context, data )
  6623. {
  6624. if ( ! this instanceof _Api ) {
  6625. throw 'DT API must be constructed as a new object';
  6626. // or should it do the 'new' for the caller?
  6627. // return new _Api.apply( this, arguments );
  6628. }
  6629.  
  6630. var settings = [];
  6631. var ctxSettings = function ( o ) {
  6632. var a = _toSettings( o );
  6633. if ( a ) {
  6634. settings.push.apply( settings, a );
  6635. }
  6636. };
  6637.  
  6638. if ( $.isArray( context ) ) {
  6639. for ( var i=0, ien=context.length ; i<ien ; i++ ) {
  6640. ctxSettings( context[i] );
  6641. }
  6642. }
  6643. else {
  6644. ctxSettings( context );
  6645. }
  6646.  
  6647. // Remove duplicates
  6648. this.context = _unique( settings );
  6649.  
  6650. // Initial data
  6651. if ( data ) {
  6652. this.push.apply( this, data.toArray ? data.toArray() : data );
  6653. }
  6654.  
  6655. // selector
  6656. this.selector = {
  6657. rows: null,
  6658. cols: null,
  6659. opts: null
  6660. };
  6661.  
  6662. _Api.extend( this, this, __apiStruct );
  6663. };
  6664.  
  6665. DataTable.Api = _Api;
  6666.  
  6667. _Api.prototype = /** @lends DataTables.Api */{
  6668. /**
  6669. * Return a new Api instance, comprised of the data held in the current
  6670. * instance, join with the other array(s) and/or value(s).
  6671. *
  6672. * An alias for `Array.prototype.concat`.
  6673. *
  6674. * @type method
  6675. * @param {*} value1 Arrays and/or values to concatenate.
  6676. * @param {*} [...] Additional arrays and/or values to concatenate.
  6677. * @returns {DataTables.Api} New API instance, comprising of the combined
  6678. * array.
  6679. */
  6680. concat: __arrayProto.concat,
  6681.  
  6682.  
  6683. context: [], // array of table settings objects
  6684.  
  6685.  
  6686. each: function ( fn )
  6687. {
  6688. for ( var i=0, ien=this.length ; i<ien; i++ ) {
  6689. fn.call( this, this[i], i, this );
  6690. }
  6691.  
  6692. return this;
  6693. },
  6694.  
  6695.  
  6696. eq: function ( idx )
  6697. {
  6698. var ctx = this.context;
  6699.  
  6700. return ctx.length > idx ?
  6701. new _Api( ctx[idx], this[idx] ) :
  6702. null;
  6703. },
  6704.  
  6705.  
  6706. filter: function ( fn )
  6707. {
  6708. var a = [];
  6709.  
  6710. if ( __arrayProto.filter ) {
  6711. a = __arrayProto.filter.call( this, fn, this );
  6712. }
  6713. else {
  6714. // Compatibility for browsers without EMCA-252-5 (JS 1.6)
  6715. for ( var i=0, ien=this.length ; i<ien ; i++ ) {
  6716. if ( fn.call( this, this[i], i, this ) ) {
  6717. a.push( this[i] );
  6718. }
  6719. }
  6720. }
  6721.  
  6722. return new _Api( this.context, a );
  6723. },
  6724.  
  6725.  
  6726. flatten: function ()
  6727. {
  6728. var a = [];
  6729. return new _Api( this.context, a.concat.apply( a, this.toArray() ) );
  6730. },
  6731.  
  6732.  
  6733. join: __arrayProto.join,
  6734.  
  6735.  
  6736. indexOf: __arrayProto.indexOf || function (obj, start)
  6737. {
  6738. for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {
  6739. if ( this[i] === obj ) {
  6740. return i;
  6741. }
  6742. }
  6743. return -1;
  6744. },
  6745.  
  6746. // Note that `alwaysNew` is internal - use iteratorNew externally
  6747. iterator: function ( flatten, type, fn, alwaysNew ) {
  6748. var
  6749. a = [], ret,
  6750. i, ien, j, jen,
  6751. context = this.context,
  6752. rows, items, item,
  6753. selector = this.selector;
  6754.  
  6755. // Argument shifting
  6756. if ( typeof flatten === 'string' ) {
  6757. alwaysNew = fn;
  6758. fn = type;
  6759. type = flatten;
  6760. flatten = false;
  6761. }
  6762.  
  6763. for ( i=0, ien=context.length ; i<ien ; i++ ) {
  6764. var apiInst = new _Api( context[i] );
  6765.  
  6766. if ( type === 'table' ) {
  6767. ret = fn.call( apiInst, context[i], i );
  6768.  
  6769. if ( ret !== undefined ) {
  6770. a.push( ret );
  6771. }
  6772. }
  6773. else if ( type === 'columns' || type === 'rows' ) {
  6774. // this has same length as context - one entry for each table
  6775. ret = fn.call( apiInst, context[i], this[i], i );
  6776.  
  6777. if ( ret !== undefined ) {
  6778. a.push( ret );
  6779. }
  6780. }
  6781. else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {
  6782. // columns and rows share the same structure.
  6783. // 'this' is an array of column indexes for each context
  6784. items = this[i];
  6785.  
  6786. if ( type === 'column-rows' ) {
  6787. rows = _selector_row_indexes( context[i], selector.opts );
  6788. }
  6789.  
  6790. for ( j=0, jen=items.length ; j<jen ; j++ ) {
  6791. item = items[j];
  6792.  
  6793. if ( type === 'cell' ) {
  6794. ret = fn.call( apiInst, context[i], item.row, item.column, i, j );
  6795. }
  6796. else {
  6797. ret = fn.call( apiInst, context[i], item, i, j, rows );
  6798. }
  6799.  
  6800. if ( ret !== undefined ) {
  6801. a.push( ret );
  6802. }
  6803. }
  6804. }
  6805. }
  6806.  
  6807. if ( a.length || alwaysNew ) {
  6808. var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
  6809. var apiSelector = api.selector;
  6810. apiSelector.rows = selector.rows;
  6811. apiSelector.cols = selector.cols;
  6812. apiSelector.opts = selector.opts;
  6813. return api;
  6814. }
  6815. return this;
  6816. },
  6817.  
  6818.  
  6819. lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
  6820. {
  6821. // Bit cheeky...
  6822. return this.indexOf.apply( this.toArray.reverse(), arguments );
  6823. },
  6824.  
  6825.  
  6826. length: 0,
  6827.  
  6828.  
  6829. map: function ( fn )
  6830. {
  6831. var a = [];
  6832.  
  6833. if ( __arrayProto.map ) {
  6834. a = __arrayProto.map.call( this, fn, this );
  6835. }
  6836. else {
  6837. // Compatibility for browsers without EMCA-252-5 (JS 1.6)
  6838. for ( var i=0, ien=this.length ; i<ien ; i++ ) {
  6839. a.push( fn.call( this, this[i], i ) );
  6840. }
  6841. }
  6842.  
  6843. return new _Api( this.context, a );
  6844. },
  6845.  
  6846.  
  6847. pluck: function ( prop )
  6848. {
  6849. return this.map( function ( el ) {
  6850. return el[ prop ];
  6851. } );
  6852. },
  6853.  
  6854. pop: __arrayProto.pop,
  6855.  
  6856.  
  6857. push: __arrayProto.push,
  6858.  
  6859.  
  6860. // Does not return an API instance
  6861. reduce: __arrayProto.reduce || function ( fn, init )
  6862. {
  6863. return _fnReduce( this, fn, init, 0, this.length, 1 );
  6864. },
  6865.  
  6866.  
  6867. reduceRight: __arrayProto.reduceRight || function ( fn, init )
  6868. {
  6869. return _fnReduce( this, fn, init, this.length-1, -1, -1 );
  6870. },
  6871.  
  6872.  
  6873. reverse: __arrayProto.reverse,
  6874.  
  6875.  
  6876. // Object with rows, columns and opts
  6877. selector: null,
  6878.  
  6879.  
  6880. shift: __arrayProto.shift,
  6881.  
  6882.  
  6883. sort: __arrayProto.sort, // ? name - order?
  6884.  
  6885.  
  6886. splice: __arrayProto.splice,
  6887.  
  6888.  
  6889. toArray: function ()
  6890. {
  6891. return __arrayProto.slice.call( this );
  6892. },
  6893.  
  6894.  
  6895. to$: function ()
  6896. {
  6897. return $( this );
  6898. },
  6899.  
  6900.  
  6901. toJQuery: function ()
  6902. {
  6903. return $( this );
  6904. },
  6905.  
  6906.  
  6907. unique: function ()
  6908. {
  6909. return new _Api( this.context, _unique(this) );
  6910. },
  6911.  
  6912.  
  6913. unshift: __arrayProto.unshift
  6914. };
  6915.  
  6916.  
  6917. _Api.extend = function ( scope, obj, ext )
  6918. {
  6919. // Only extend API instances and static properties of the API
  6920. if ( ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {
  6921. return;
  6922. }
  6923.  
  6924. var
  6925. i, ien,
  6926. j, jen,
  6927. struct, inner,
  6928. methodScoping = function ( scope, fn, struc ) {
  6929. return function () {
  6930. var ret = fn.apply( scope, arguments );
  6931.  
  6932. // Method extension
  6933. _Api.extend( ret, ret, struc.methodExt );
  6934. return ret;
  6935. };
  6936. };
  6937.  
  6938. for ( i=0, ien=ext.length ; i<ien ; i++ ) {
  6939. struct = ext[i];
  6940.  
  6941. // Value
  6942. obj[ struct.name ] = typeof struct.val === 'function' ?
  6943. methodScoping( scope, struct.val, struct ) :
  6944. $.isPlainObject( struct.val ) ?
  6945. {} :
  6946. struct.val;
  6947.  
  6948. obj[ struct.name ].__dt_wrapper = true;
  6949.  
  6950. // Property extension
  6951. _Api.extend( scope, obj[ struct.name ], struct.propExt );
  6952. }
  6953. };
  6954.  
  6955.  
  6956. // @todo - Is there need for an augment function?
  6957. // _Api.augment = function ( inst, name )
  6958. // {
  6959. // // Find src object in the structure from the name
  6960. // var parts = name.split('.');
  6961.  
  6962. // _Api.extend( inst, obj );
  6963. // };
  6964.  
  6965.  
  6966. // [
  6967. // {
  6968. // name: 'data' -- string - Property name
  6969. // val: function () {}, -- function - Api method (or undefined if just an object
  6970. // methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
  6971. // propExt: [ ... ] -- array - Array of Api object definitions to extend the property
  6972. // },
  6973. // {
  6974. // name: 'row'
  6975. // val: {},
  6976. // methodExt: [ ... ],
  6977. // propExt: [
  6978. // {
  6979. // name: 'data'
  6980. // val: function () {},
  6981. // methodExt: [ ... ],
  6982. // propExt: [ ... ]
  6983. // },
  6984. // ...
  6985. // ]
  6986. // }
  6987. // ]
  6988.  
  6989. _Api.register = _api_register = function ( name, val )
  6990. {
  6991. if ( $.isArray( name ) ) {
  6992. for ( var j=0, jen=name.length ; j<jen ; j++ ) {
  6993. _Api.register( name[j], val );
  6994. }
  6995. return;
  6996. }
  6997.  
  6998. var
  6999. i, ien,
  7000. heir = name.split('.'),
  7001. struct = __apiStruct,
  7002. key, method;
  7003.  
  7004. var find = function ( src, name ) {
  7005. for ( var i=0, ien=src.length ; i<ien ; i++ ) {
  7006. if ( src[i].name === name ) {
  7007. return src[i];
  7008. }
  7009. }
  7010. return null;
  7011. };
  7012.  
  7013. for ( i=0, ien=heir.length ; i<ien ; i++ ) {
  7014. method = heir[i].indexOf('()') !== -1;
  7015. key = method ?
  7016. heir[i].replace('()', '') :
  7017. heir[i];
  7018.  
  7019. var src = find( struct, key );
  7020. if ( ! src ) {
  7021. src = {
  7022. name: key,
  7023. val: {},
  7024. methodExt: [],
  7025. propExt: []
  7026. };
  7027. struct.push( src );
  7028. }
  7029.  
  7030. if ( i === ien-1 ) {
  7031. src.val = val;
  7032. }
  7033. else {
  7034. struct = method ?
  7035. src.methodExt :
  7036. src.propExt;
  7037. }
  7038. }
  7039. };
  7040.  
  7041.  
  7042. _Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
  7043. _Api.register( pluralName, val );
  7044.  
  7045. _Api.register( singularName, function () {
  7046. var ret = val.apply( this, arguments );
  7047.  
  7048. if ( ret === this ) {
  7049. // Returned item is the API instance that was passed in, return it
  7050. return this;
  7051. }
  7052. else if ( ret instanceof _Api ) {
  7053. // New API instance returned, want the value from the first item
  7054. // in the returned array for the singular result.
  7055. return ret.length ?
  7056. $.isArray( ret[0] ) ?
  7057. new _Api( ret.context, ret[0] ) : // Array results are 'enhanced'
  7058. ret[0] :
  7059. undefined;
  7060. }
  7061.  
  7062. // Non-API return - just fire it back
  7063. return ret;
  7064. } );
  7065. };
  7066.  
  7067.  
  7068. /**
  7069. * Selector for HTML tables. Apply the given selector to the give array of
  7070. * DataTables settings objects.
  7071. *
  7072. * @param {string|integer} [selector] jQuery selector string or integer
  7073. * @param {array} Array of DataTables settings objects to be filtered
  7074. * @return {array}
  7075. * @ignore
  7076. */
  7077. var __table_selector = function ( selector, a )
  7078. {
  7079. // Integer is used to pick out a table by index
  7080. if ( typeof selector === 'number' ) {
  7081. return [ a[ selector ] ];
  7082. }
  7083.  
  7084. // Perform a jQuery selector on the table nodes
  7085. var nodes = $.map( a, function (el, i) {
  7086. return el.nTable;
  7087. } );
  7088.  
  7089. return $(nodes)
  7090. .filter( selector )
  7091. .map( function (i) {
  7092. // Need to translate back from the table node to the settings
  7093. var idx = $.inArray( this, nodes );
  7094. return a[ idx ];
  7095. } )
  7096. .toArray();
  7097. };
  7098.  
  7099.  
  7100.  
  7101. /**
  7102. * Context selector for the API's context (i.e. the tables the API instance
  7103. * refers to.
  7104. *
  7105. * @name DataTable.Api#tables
  7106. * @param {string|integer} [selector] Selector to pick which tables the iterator
  7107. * should operate on. If not given, all tables in the current context are
  7108. * used. This can be given as a jQuery selector (for example `':gt(0)'`) to
  7109. * select multiple tables or as an integer to select a single table.
  7110. * @returns {DataTable.Api} Returns a new API instance if a selector is given.
  7111. */
  7112. _api_register( 'tables()', function ( selector ) {
  7113. // A new instance is created if there was a selector specified
  7114. return selector ?
  7115. new _Api( __table_selector( selector, this.context ) ) :
  7116. this;
  7117. } );
  7118.  
  7119.  
  7120. _api_register( 'table()', function ( selector ) {
  7121. var tables = this.tables( selector );
  7122. var ctx = tables.context;
  7123.  
  7124. // Truncate to the first matched table
  7125. return ctx.length ?
  7126. new _Api( ctx[0] ) :
  7127. tables;
  7128. } );
  7129.  
  7130.  
  7131. _api_registerPlural( 'tables().nodes()', 'table().node()' , function () {
  7132. return this.iterator( 'table', function ( ctx ) {
  7133. return ctx.nTable;
  7134. }, 1 );
  7135. } );
  7136.  
  7137.  
  7138. _api_registerPlural( 'tables().body()', 'table().body()' , function () {
  7139. return this.iterator( 'table', function ( ctx ) {
  7140. return ctx.nTBody;
  7141. }, 1 );
  7142. } );
  7143.  
  7144.  
  7145. _api_registerPlural( 'tables().header()', 'table().header()' , function () {
  7146. return this.iterator( 'table', function ( ctx ) {
  7147. return ctx.nTHead;
  7148. }, 1 );
  7149. } );
  7150.  
  7151.  
  7152. _api_registerPlural( 'tables().footer()', 'table().footer()' , function () {
  7153. return this.iterator( 'table', function ( ctx ) {
  7154. return ctx.nTFoot;
  7155. }, 1 );
  7156. } );
  7157.  
  7158.  
  7159. _api_registerPlural( 'tables().containers()', 'table().container()' , function () {
  7160. return this.iterator( 'table', function ( ctx ) {
  7161. return ctx.nTableWrapper;
  7162. }, 1 );
  7163. } );
  7164.  
  7165.  
  7166.  
  7167. /**
  7168. * Redraw the tables in the current context.
  7169. *
  7170. * @param {boolean} [reset=true] Reset (default) or hold the current paging
  7171. * position. A full re-sort and re-filter is performed when this method is
  7172. * called, which is why the pagination reset is the default action.
  7173. * @returns {DataTables.Api} this
  7174. */
  7175. _api_register( 'draw()', function ( resetPaging ) {
  7176. return this.iterator( 'table', function ( settings ) {
  7177. _fnReDraw( settings, resetPaging===false );
  7178. } );
  7179. } );
  7180.  
  7181.  
  7182.  
  7183. /**
  7184. * Get the current page index.
  7185. *
  7186. * @return {integer} Current page index (zero based)
  7187. *//**
  7188. * Set the current page.
  7189. *
  7190. * Note that if you attempt to show a page which does not exist, DataTables will
  7191. * not throw an error, but rather reset the paging.
  7192. *
  7193. * @param {integer|string} action The paging action to take. This can be one of:
  7194. * * `integer` - The page index to jump to
  7195. * * `string` - An action to take:
  7196. * * `first` - Jump to first page.
  7197. * * `next` - Jump to the next page
  7198. * * `previous` - Jump to previous page
  7199. * * `last` - Jump to the last page.
  7200. * @returns {DataTables.Api} this
  7201. */
  7202. _api_register( 'page()', function ( action ) {
  7203. if ( action === undefined ) {
  7204. return this.page.info().page; // not an expensive call
  7205. }
  7206.  
  7207. // else, have an action to take on all tables
  7208. return this.iterator( 'table', function ( settings ) {
  7209. _fnPageChange( settings, action );
  7210. } );
  7211. } );
  7212.  
  7213.  
  7214. /**
  7215. * Paging information for the first table in the current context.
  7216. *
  7217. * If you require paging information for another table, use the `table()` method
  7218. * with a suitable selector.
  7219. *
  7220. * @return {object} Object with the following properties set:
  7221. * * `page` - Current page index (zero based - i.e. the first page is `0`)
  7222. * * `pages` - Total number of pages
  7223. * * `start` - Display index for the first record shown on the current page
  7224. * * `end` - Display index for the last record shown on the current page
  7225. * * `length` - Display length (number of records). Note that generally `start
  7226. * + length = end`, but this is not always true, for example if there are
  7227. * only 2 records to show on the final page, with a length of 10.
  7228. * * `recordsTotal` - Full data set length
  7229. * * `recordsDisplay` - Data set length once the current filtering criterion
  7230. * are applied.
  7231. */
  7232. _api_register( 'page.info()', function ( action ) {
  7233. if ( this.context.length === 0 ) {
  7234. return undefined;
  7235. }
  7236.  
  7237. var
  7238. settings = this.context[0],
  7239. start = settings._iDisplayStart,
  7240. len = settings._iDisplayLength,
  7241. visRecords = settings.fnRecordsDisplay(),
  7242. all = len === -1;
  7243.  
  7244. return {
  7245. "page": all ? 0 : Math.floor( start / len ),
  7246. "pages": all ? 1 : Math.ceil( visRecords / len ),
  7247. "start": start,
  7248. "end": settings.fnDisplayEnd(),
  7249. "length": len,
  7250. "recordsTotal": settings.fnRecordsTotal(),
  7251. "recordsDisplay": visRecords
  7252. };
  7253. } );
  7254.  
  7255.  
  7256. /**
  7257. * Get the current page length.
  7258. *
  7259. * @return {integer} Current page length. Note `-1` indicates that all records
  7260. * are to be shown.
  7261. *//**
  7262. * Set the current page length.
  7263. *
  7264. * @param {integer} Page length to set. Use `-1` to show all records.
  7265. * @returns {DataTables.Api} this
  7266. */
  7267. _api_register( 'page.len()', function ( len ) {
  7268. // Note that we can't call this function 'length()' because `length`
  7269. // is a Javascript property of functions which defines how many arguments
  7270. // the function expects.
  7271. if ( len === undefined ) {
  7272. return this.context.length !== 0 ?
  7273. this.context[0]._iDisplayLength :
  7274. undefined;
  7275. }
  7276.  
  7277. // else, set the page length
  7278. return this.iterator( 'table', function ( settings ) {
  7279. _fnLengthChange( settings, len );
  7280. } );
  7281. } );
  7282.  
  7283.  
  7284.  
  7285. var __reload = function ( settings, holdPosition, callback ) {
  7286. if ( _fnDataSource( settings ) == 'ssp' ) {
  7287. _fnReDraw( settings, holdPosition );
  7288. }
  7289. else {
  7290. // Trigger xhr
  7291. _fnProcessingDisplay( settings, true );
  7292.  
  7293. _fnBuildAjax( settings, [], function( json ) {
  7294. _fnClearTable( settings );
  7295.  
  7296. var data = _fnAjaxDataSrc( settings, json );
  7297. for ( var i=0, ien=data.length ; i<ien ; i++ ) {
  7298. _fnAddData( settings, data[i] );
  7299. }
  7300.  
  7301. _fnReDraw( settings, holdPosition );
  7302. _fnProcessingDisplay( settings, false );
  7303. } );
  7304. }
  7305.  
  7306. // Use the draw event to trigger a callback, regardless of if it is an async
  7307. // or sync draw
  7308. if ( callback ) {
  7309. var api = new _Api( settings );
  7310.  
  7311. api.one( 'draw', function () {
  7312. callback( api.ajax.json() );
  7313. } );
  7314. }
  7315. };
  7316.  
  7317.  
  7318. /**
  7319. * Get the JSON response from the last Ajax request that DataTables made to the
  7320. * server. Note that this returns the JSON from the first table in the current
  7321. * context.
  7322. *
  7323. * @return {object} JSON received from the server.
  7324. */
  7325. _api_register( 'ajax.json()', function () {
  7326. var ctx = this.context;
  7327.  
  7328. if ( ctx.length > 0 ) {
  7329. return ctx[0].json;
  7330. }
  7331.  
  7332. // else return undefined;
  7333. } );
  7334.  
  7335.  
  7336. /**
  7337. * Get the data submitted in the last Ajax request
  7338. */
  7339. _api_register( 'ajax.params()', function () {
  7340. var ctx = this.context;
  7341.  
  7342. if ( ctx.length > 0 ) {
  7343. return ctx[0].oAjaxData;
  7344. }
  7345.  
  7346. // else return undefined;
  7347. } );
  7348.  
  7349.  
  7350. /**
  7351. * Reload tables from the Ajax data source. Note that this function will
  7352. * automatically re-draw the table when the remote data has been loaded.
  7353. *
  7354. * @param {boolean} [reset=true] Reset (default) or hold the current paging
  7355. * position. A full re-sort and re-filter is performed when this method is
  7356. * called, which is why the pagination reset is the default action.
  7357. * @returns {DataTables.Api} this
  7358. */
  7359. _api_register( 'ajax.reload()', function ( callback, resetPaging ) {
  7360. return this.iterator( 'table', function (settings) {
  7361. __reload( settings, resetPaging===false, callback );
  7362. } );
  7363. } );
  7364.  
  7365.  
  7366. /**
  7367. * Get the current Ajax URL. Note that this returns the URL from the first
  7368. * table in the current context.
  7369. *
  7370. * @return {string} Current Ajax source URL
  7371. *//**
  7372. * Set the Ajax URL. Note that this will set the URL for all tables in the
  7373. * current context.
  7374. *
  7375. * @param {string} url URL to set.
  7376. * @returns {DataTables.Api} this
  7377. */
  7378. _api_register( 'ajax.url()', function ( url ) {
  7379. var ctx = this.context;
  7380.  
  7381. if ( url === undefined ) {
  7382. // get
  7383. if ( ctx.length === 0 ) {
  7384. return undefined;
  7385. }
  7386. ctx = ctx[0];
  7387.  
  7388. return ctx.ajax ?
  7389. $.isPlainObject( ctx.ajax ) ?
  7390. ctx.ajax.url :
  7391. ctx.ajax :
  7392. ctx.sAjaxSource;
  7393. }
  7394.  
  7395. // set
  7396. return this.iterator( 'table', function ( settings ) {
  7397. if ( $.isPlainObject( settings.ajax ) ) {
  7398. settings.ajax.url = url;
  7399. }
  7400. else {
  7401. settings.ajax = url;
  7402. }
  7403. // No need to consider sAjaxSource here since DataTables gives priority
  7404. // to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
  7405. // value of `sAjaxSource` redundant.
  7406. } );
  7407. } );
  7408.  
  7409.  
  7410. /**
  7411. * Load data from the newly set Ajax URL. Note that this method is only
  7412. * available when `ajax.url()` is used to set a URL. Additionally, this method
  7413. * has the same effect as calling `ajax.reload()` but is provided for
  7414. * convenience when setting a new URL. Like `ajax.reload()` it will
  7415. * automatically redraw the table once the remote data has been loaded.
  7416. *
  7417. * @returns {DataTables.Api} this
  7418. */
  7419. _api_register( 'ajax.url().load()', function ( callback, resetPaging ) {
  7420. // Same as a reload, but makes sense to present it for easy access after a
  7421. // url change
  7422. return this.iterator( 'table', function ( ctx ) {
  7423. __reload( ctx, resetPaging===false, callback );
  7424. } );
  7425. } );
  7426.  
  7427.  
  7428.  
  7429.  
  7430. var _selector_run = function ( selector, select )
  7431. {
  7432. var
  7433. out = [], res,
  7434. a, i, ien, j, jen,
  7435. selectorType = typeof selector;
  7436.  
  7437. // Can't just check for isArray here, as an API or jQuery instance might be
  7438. // given with their array like look
  7439. if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {
  7440. selector = [ selector ];
  7441. }
  7442.  
  7443. for ( i=0, ien=selector.length ; i<ien ; i++ ) {
  7444. a = selector[i] && selector[i].split ?
  7445. selector[i].split(',') :
  7446. [ selector[i] ];
  7447.  
  7448. for ( j=0, jen=a.length ; j<jen ; j++ ) {
  7449. res = select( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );
  7450.  
  7451. if ( res && res.length ) {
  7452. out.push.apply( out, res );
  7453. }
  7454. }
  7455. }
  7456.  
  7457. return out;
  7458. };
  7459.  
  7460.  
  7461. var _selector_opts = function ( opts )
  7462. {
  7463. if ( ! opts ) {
  7464. opts = {};
  7465. }
  7466.  
  7467. // Backwards compatibility for 1.9- which used the terminology filter rather
  7468. // than search
  7469. if ( opts.filter && ! opts.search ) {
  7470. opts.search = opts.filter;
  7471. }
  7472.  
  7473. return {
  7474. search: opts.search || 'none',
  7475. order: opts.order || 'current',
  7476. page: opts.page || 'all'
  7477. };
  7478. };
  7479.  
  7480.  
  7481. var _selector_first = function ( inst )
  7482. {
  7483. // Reduce the API instance to the first item found
  7484. for ( var i=0, ien=inst.length ; i<ien ; i++ ) {
  7485. if ( inst[i].length > 0 ) {
  7486. // Assign the first element to the first item in the instance
  7487. // and truncate the instance and context
  7488. inst[0] = inst[i];
  7489. inst.length = 1;
  7490. inst.context = [ inst.context[i] ];
  7491.  
  7492. return inst;
  7493. }
  7494. }
  7495.  
  7496. // Not found - return an empty instance
  7497. inst.length = 0;
  7498. return inst;
  7499. };
  7500.  
  7501.  
  7502. var _selector_row_indexes = function ( settings, opts )
  7503. {
  7504. var
  7505. i, ien, tmp, a=[],
  7506. displayFiltered = settings.aiDisplay,
  7507. displayMaster = settings.aiDisplayMaster;
  7508.  
  7509. var
  7510. search = opts.search, // none, applied, removed
  7511. order = opts.order, // applied, current, index (original - compatibility with 1.9)
  7512. page = opts.page; // all, current
  7513.  
  7514. if ( _fnDataSource( settings ) == 'ssp' ) {
  7515. // In server-side processing mode, most options are irrelevant since
  7516. // rows not shown don't exist and the index order is the applied order
  7517. // Removed is a special case - for consistency just return an empty
  7518. // array
  7519. return search === 'removed' ?
  7520. [] :
  7521. _range( 0, displayMaster.length );
  7522. }
  7523. else if ( page == 'current' ) {
  7524. // Current page implies that order=current and fitler=applied, since it is
  7525. // fairly senseless otherwise, regardless of what order and search actually
  7526. // are
  7527. for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
  7528. a.push( displayFiltered[i] );
  7529. }
  7530. }
  7531. else if ( order == 'current' || order == 'applied' ) {
  7532. a = search == 'none' ?
  7533. displayMaster.slice() : // no search
  7534. search == 'applied' ?
  7535. displayFiltered.slice() : // applied search
  7536. $.map( displayMaster, function (el, i) { // removed search
  7537. return $.inArray( el, displayFiltered ) === -1 ? el : null;
  7538. } );
  7539. }
  7540. else if ( order == 'index' || order == 'original' ) {
  7541. for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
  7542. if ( search == 'none' ) {
  7543. a.push( i );
  7544. }
  7545. else { // applied | removed
  7546. tmp = $.inArray( i, displayFiltered );
  7547.  
  7548. if ((tmp === -1 && search == 'removed') ||
  7549. (tmp >= 0 && search == 'applied') )
  7550. {
  7551. a.push( i );
  7552. }
  7553. }
  7554. }
  7555. }
  7556.  
  7557. return a;
  7558. };
  7559.  
  7560.  
  7561. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  7562. * Rows
  7563. *
  7564. * {} - no selector - use all available rows
  7565. * {integer} - row aoData index
  7566. * {node} - TR node
  7567. * {string} - jQuery selector to apply to the TR elements
  7568. * {array} - jQuery array of nodes, or simply an array of TR nodes
  7569. *
  7570. */
  7571.  
  7572.  
  7573. var __row_selector = function ( settings, selector, opts )
  7574. {
  7575. return _selector_run( selector, function ( sel ) {
  7576. var selInt = _intVal( sel );
  7577. var i, ien;
  7578.  
  7579. // Short cut - selector is a number and no options provided (default is
  7580. // all records, so no need to check if the index is in there, since it
  7581. // must be - dev error if the index doesn't exist).
  7582. if ( selInt !== null && ! opts ) {
  7583. return [ selInt ];
  7584. }
  7585.  
  7586. var rows = _selector_row_indexes( settings, opts );
  7587.  
  7588. if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
  7589. // Selector - integer
  7590. return [ selInt ];
  7591. }
  7592. else if ( ! sel ) {
  7593. // Selector - none
  7594. return rows;
  7595. }
  7596.  
  7597. // Selector - function
  7598. if ( typeof sel === 'function' ) {
  7599. return $.map( rows, function (idx) {
  7600. var row = settings.aoData[ idx ];
  7601. return sel( idx, row._aData, row.nTr ) ? idx : null;
  7602. } );
  7603. }
  7604.  
  7605. // Get nodes in the order from the `rows` array with null values removed
  7606. var nodes = _removeEmpty(
  7607. _pluck_order( settings.aoData, rows, 'nTr' )
  7608. );
  7609.  
  7610. // Selector - node
  7611. if ( sel.nodeName ) {
  7612. if ( $.inArray( sel, nodes ) !== -1 ) {
  7613. return [ sel._DT_RowIndex ]; // sel is a TR node that is in the table
  7614. // and DataTables adds a prop for fast lookup
  7615. }
  7616. }
  7617.  
  7618. // Selector - jQuery selector string, array of nodes or jQuery object/
  7619. // As jQuery's .filter() allows jQuery objects to be passed in filter,
  7620. // it also allows arrays, so this will cope with all three options
  7621. return $(nodes)
  7622. .filter( sel )
  7623. .map( function () {
  7624. return this._DT_RowIndex;
  7625. } )
  7626. .toArray();
  7627. } );
  7628. };
  7629.  
  7630.  
  7631. /**
  7632. *
  7633. */
  7634. _api_register( 'rows()', function ( selector, opts ) {
  7635. // argument shifting
  7636. if ( selector === undefined ) {
  7637. selector = '';
  7638. }
  7639. else if ( $.isPlainObject( selector ) ) {
  7640. opts = selector;
  7641. selector = '';
  7642. }
  7643.  
  7644. opts = _selector_opts( opts );
  7645.  
  7646. var inst = this.iterator( 'table', function ( settings ) {
  7647. return __row_selector( settings, selector, opts );
  7648. }, 1 );
  7649.  
  7650. // Want argument shifting here and in __row_selector?
  7651. inst.selector.rows = selector;
  7652. inst.selector.opts = opts;
  7653.  
  7654. return inst;
  7655. } );
  7656.  
  7657.  
  7658. _api_register( 'rows().nodes()', function () {
  7659. return this.iterator( 'row', function ( settings, row ) {
  7660. return settings.aoData[ row ].nTr || undefined;
  7661. }, 1 );
  7662. } );
  7663.  
  7664. _api_register( 'rows().data()', function () {
  7665. return this.iterator( true, 'rows', function ( settings, rows ) {
  7666. return _pluck_order( settings.aoData, rows, '_aData' );
  7667. }, 1 );
  7668. } );
  7669.  
  7670. _api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {
  7671. return this.iterator( 'row', function ( settings, row ) {
  7672. var r = settings.aoData[ row ];
  7673. return type === 'search' ? r._aFilterData : r._aSortData;
  7674. }, 1 );
  7675. } );
  7676.  
  7677. _api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
  7678. return this.iterator( 'row', function ( settings, row ) {
  7679. _fnInvalidate( settings, row, src );
  7680. } );
  7681. } );
  7682.  
  7683. _api_registerPlural( 'rows().indexes()', 'row().index()', function () {
  7684. return this.iterator( 'row', function ( settings, row ) {
  7685. return row;
  7686. }, 1 );
  7687. } );
  7688.  
  7689. _api_registerPlural( 'rows().remove()', 'row().remove()', function () {
  7690. var that = this;
  7691.  
  7692. return this.iterator( 'row', function ( settings, row, thatIdx ) {
  7693. var data = settings.aoData;
  7694.  
  7695. data.splice( row, 1 );
  7696.  
  7697. // Update the _DT_RowIndex parameter on all rows in the table
  7698. for ( var i=0, ien=data.length ; i<ien ; i++ ) {
  7699. if ( data[i].nTr !== null ) {
  7700. data[i].nTr._DT_RowIndex = i;
  7701. }
  7702. }
  7703.  
  7704. // Remove the target row from the search array
  7705. var displayIndex = $.inArray( row, settings.aiDisplay );
  7706.  
  7707. // Delete from the display arrays
  7708. _fnDeleteIndex( settings.aiDisplayMaster, row );
  7709. _fnDeleteIndex( settings.aiDisplay, row );
  7710. _fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
  7711.  
  7712. // Check for an 'overflow' they case for displaying the table
  7713. _fnLengthOverflow( settings );
  7714. } );
  7715. } );
  7716.  
  7717.  
  7718. _api_register( 'rows.add()', function ( rows ) {
  7719. var newRows = this.iterator( 'table', function ( settings ) {
  7720. var row, i, ien;
  7721. var out = [];
  7722.  
  7723. for ( i=0, ien=rows.length ; i<ien ; i++ ) {
  7724. row = rows[i];
  7725.  
  7726. if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
  7727. out.push( _fnAddTr( settings, row )[0] );
  7728. }
  7729. else {
  7730. out.push( _fnAddData( settings, row ) );
  7731. }
  7732. }
  7733.  
  7734. return out;
  7735. }, 1 );
  7736.  
  7737. // Return an Api.rows() extended instance, so rows().nodes() etc can be used
  7738. var modRows = this.rows( -1 );
  7739. modRows.pop();
  7740. modRows.push.apply( modRows, newRows.toArray() );
  7741.  
  7742. return modRows;
  7743. } );
  7744.  
  7745.  
  7746.  
  7747.  
  7748.  
  7749. /**
  7750. *
  7751. */
  7752. _api_register( 'row()', function ( selector, opts ) {
  7753. return _selector_first( this.rows( selector, opts ) );
  7754. } );
  7755.  
  7756.  
  7757. _api_register( 'row().data()', function ( data ) {
  7758. var ctx = this.context;
  7759.  
  7760. if ( data === undefined ) {
  7761. // Get
  7762. return ctx.length && this.length ?
  7763. ctx[0].aoData[ this[0] ]._aData :
  7764. undefined;
  7765. }
  7766.  
  7767. // Set
  7768. ctx[0].aoData[ this[0] ]._aData = data;
  7769.  
  7770. // Automatically invalidate
  7771. _fnInvalidate( ctx[0], this[0], 'data' );
  7772.  
  7773. return this;
  7774. } );
  7775.  
  7776.  
  7777. _api_register( 'row().node()', function () {
  7778. var ctx = this.context;
  7779.  
  7780. return ctx.length && this.length ?
  7781. ctx[0].aoData[ this[0] ].nTr || null :
  7782. null;
  7783. } );
  7784.  
  7785.  
  7786. _api_register( 'row.add()', function ( row ) {
  7787. // Allow a jQuery object to be passed in - only a single row is added from
  7788. // it though - the first element in the set
  7789. if ( row instanceof $ && row.length ) {
  7790. row = row[0];
  7791. }
  7792.  
  7793. var rows = this.iterator( 'table', function ( settings ) {
  7794. if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
  7795. return _fnAddTr( settings, row )[0];
  7796. }
  7797. return _fnAddData( settings, row );
  7798. } );
  7799.  
  7800. // Return an Api.rows() extended instance, with the newly added row selected
  7801. return this.row( rows[0] );
  7802. } );
  7803.  
  7804.  
  7805.  
  7806. var __details_add = function ( ctx, row, data, klass )
  7807. {
  7808. // Convert to array of TR elements
  7809. var rows = [];
  7810. var addRow = function ( r, k ) {
  7811. // If we get a TR element, then just add it directly - up to the dev
  7812. // to add the correct number of columns etc
  7813. if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {
  7814. rows.push( r );
  7815. }
  7816. else {
  7817. // Otherwise create a row with a wrapper
  7818. var created = $('<tr><td/></tr>').addClass( k );
  7819. $('td', created)
  7820. .addClass( k )
  7821. .html( r )
  7822. [0].colSpan = _fnVisbleColumns( ctx );
  7823.  
  7824. rows.push( created[0] );
  7825. }
  7826. };
  7827.  
  7828. if ( $.isArray( data ) || data instanceof $ ) {
  7829. for ( var i=0, ien=data.length ; i<ien ; i++ ) {
  7830. addRow( data[i], klass );
  7831. }
  7832. }
  7833. else {
  7834. addRow( data, klass );
  7835. }
  7836.  
  7837. if ( row._details ) {
  7838. row._details.remove();
  7839. }
  7840.  
  7841. row._details = $(rows);
  7842.  
  7843. // If the children were already shown, that state should be retained
  7844. if ( row._detailsShow ) {
  7845. row._details.insertAfter( row.nTr );
  7846. }
  7847. };
  7848.  
  7849.  
  7850. var __details_remove = function ( api, idx )
  7851. {
  7852. var ctx = api.context;
  7853.  
  7854. if ( ctx.length ) {
  7855. var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
  7856.  
  7857. if ( row._details ) {
  7858. row._details.remove();
  7859.  
  7860. row._detailsShow = undefined;
  7861. row._details = undefined;
  7862. }
  7863. }
  7864. };
  7865.  
  7866.  
  7867. var __details_display = function ( api, show ) {
  7868. var ctx = api.context;
  7869.  
  7870. if ( ctx.length && api.length ) {
  7871. var row = ctx[0].aoData[ api[0] ];
  7872.  
  7873. if ( row._details ) {
  7874. row._detailsShow = show;
  7875.  
  7876. if ( show ) {
  7877. row._details.insertAfter( row.nTr );
  7878. }
  7879. else {
  7880. row._details.detach();
  7881. }
  7882.  
  7883. __details_events( ctx[0] );
  7884. }
  7885. }
  7886. };
  7887.  
  7888.  
  7889. var __details_events = function ( settings )
  7890. {
  7891. var api = new _Api( settings );
  7892. var namespace = '.dt.DT_details';
  7893. var drawEvent = 'draw'+namespace;
  7894. var colvisEvent = 'column-visibility'+namespace;
  7895. var destroyEvent = 'destroy'+namespace;
  7896. var data = settings.aoData;
  7897.  
  7898. api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );
  7899.  
  7900. if ( _pluck( data, '_details' ).length > 0 ) {
  7901. // On each draw, insert the required elements into the document
  7902. api.on( drawEvent, function ( e, ctx ) {
  7903. if ( settings !== ctx ) {
  7904. return;
  7905. }
  7906.  
  7907. api.rows( {page:'current'} ).eq(0).each( function (idx) {
  7908. // Internal data grab
  7909. var row = data[ idx ];
  7910.  
  7911. if ( row._detailsShow ) {
  7912. row._details.insertAfter( row.nTr );
  7913. }
  7914. } );
  7915. } );
  7916.  
  7917. // Column visibility change - update the colspan
  7918. api.on( colvisEvent, function ( e, ctx, idx, vis ) {
  7919. if ( settings !== ctx ) {
  7920. return;
  7921. }
  7922.  
  7923. // Update the colspan for the details rows (note, only if it already has
  7924. // a colspan)
  7925. var row, visible = _fnVisbleColumns( ctx );
  7926.  
  7927. for ( var i=0, ien=data.length ; i<ien ; i++ ) {
  7928. row = data[i];
  7929.  
  7930. if ( row._details ) {
  7931. row._details.children('td[colspan]').attr('colspan', visible );
  7932. }
  7933. }
  7934. } );
  7935.  
  7936. // Table destroyed - nuke any child rows
  7937. api.on( destroyEvent, function ( e, ctx ) {
  7938. if ( settings !== ctx ) {
  7939. return;
  7940. }
  7941.  
  7942. for ( var i=0, ien=data.length ; i<ien ; i++ ) {
  7943. if ( data[i]._details ) {
  7944. __details_remove( api, i );
  7945. }
  7946. }
  7947. } );
  7948. }
  7949. };
  7950.  
  7951. // Strings for the method names to help minification
  7952. var _emp = '';
  7953. var _child_obj = _emp+'row().child';
  7954. var _child_mth = _child_obj+'()';
  7955.  
  7956. // data can be:
  7957. // tr
  7958. // string
  7959. // jQuery or array of any of the above
  7960. _api_register( _child_mth, function ( data, klass ) {
  7961. var ctx = this.context;
  7962.  
  7963. if ( data === undefined ) {
  7964. // get
  7965. return ctx.length && this.length ?
  7966. ctx[0].aoData[ this[0] ]._details :
  7967. undefined;
  7968. }
  7969. else if ( data === true ) {
  7970. // show
  7971. this.child.show();
  7972. }
  7973. else if ( data === false ) {
  7974. // remove
  7975. __details_remove( this );
  7976. }
  7977. else if ( ctx.length && this.length ) {
  7978. // set
  7979. __details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );
  7980. }
  7981.  
  7982. return this;
  7983. } );
  7984.  
  7985.  
  7986. _api_register( [
  7987. _child_obj+'.show()',
  7988. _child_mth+'.show()' // only when `child()` was called with parameters (without
  7989. ], function ( show ) { // it returns an object and this method is not executed)
  7990. __details_display( this, true );
  7991. return this;
  7992. } );
  7993.  
  7994.  
  7995. _api_register( [
  7996. _child_obj+'.hide()',
  7997. _child_mth+'.hide()' // only when `child()` was called with parameters (without
  7998. ], function () { // it returns an object and this method is not executed)
  7999. __details_display( this, false );
  8000. return this;
  8001. } );
  8002.  
  8003.  
  8004. _api_register( [
  8005. _child_obj+'.remove()',
  8006. _child_mth+'.remove()' // only when `child()` was called with parameters (without
  8007. ], function () { // it returns an object and this method is not executed)
  8008. __details_remove( this );
  8009. return this;
  8010. } );
  8011.  
  8012.  
  8013. _api_register( _child_obj+'.isShown()', function () {
  8014. var ctx = this.context;
  8015.  
  8016. if ( ctx.length && this.length ) {
  8017. // _detailsShown as false or undefined will fall through to return false
  8018. return ctx[0].aoData[ this[0] ]._detailsShow || false;
  8019. }
  8020. return false;
  8021. } );
  8022.  
  8023.  
  8024.  
  8025. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  8026. * Columns
  8027. *
  8028. * {integer} - column index (>=0 count from left, <0 count from right)
  8029. * "{integer}:visIdx" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right)
  8030. * "{integer}:visible" - alias for {integer}:visIdx (>=0 count from left, <0 count from right)
  8031. * "{string}:name" - column name
  8032. * "{string}" - jQuery selector on column header nodes
  8033. *
  8034. */
  8035.  
  8036. // can be an array of these items, comma separated list, or an array of comma
  8037. // separated lists
  8038.  
  8039. var __re_column_selector = /^(.+):(name|visIdx|visible)$/;
  8040.  
  8041.  
  8042. // r1 and r2 are redundant - but it means that the parameters match for the
  8043. // iterator callback in columns().data()
  8044. var __columnData = function ( settings, column, r1, r2, rows ) {
  8045. var a = [];
  8046. for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
  8047. a.push( _fnGetCellData( settings, rows[row], column ) );
  8048. }
  8049. return a;
  8050. };
  8051.  
  8052.  
  8053. var __column_selector = function ( settings, selector, opts )
  8054. {
  8055. var
  8056. columns = settings.aoColumns,
  8057. names = _pluck( columns, 'sName' ),
  8058. nodes = _pluck( columns, 'nTh' );
  8059.  
  8060. return _selector_run( selector, function ( s ) {
  8061. var selInt = _intVal( s );
  8062.  
  8063. // Selector - all
  8064. if ( s === '' ) {
  8065. return _range( columns.length );
  8066. }
  8067.  
  8068. // Selector - index
  8069. if ( selInt !== null ) {
  8070. return [ selInt >= 0 ?
  8071. selInt : // Count from left
  8072. columns.length + selInt // Count from right (+ because its a negative value)
  8073. ];
  8074. }
  8075.  
  8076. // Selector = function
  8077. if ( typeof s === 'function' ) {
  8078. var rows = _selector_row_indexes( settings, opts );
  8079.  
  8080. return $.map( columns, function (col, idx) {
  8081. return s(
  8082. idx,
  8083. __columnData( settings, idx, 0, 0, rows ),
  8084. nodes[ idx ]
  8085. ) ? idx : null;
  8086. } );
  8087. }
  8088.  
  8089. // jQuery or string selector
  8090. var match = typeof s === 'string' ?
  8091. s.match( __re_column_selector ) :
  8092. '';
  8093.  
  8094. if ( match ) {
  8095. switch( match[2] ) {
  8096. case 'visIdx':
  8097. case 'visible':
  8098. var idx = parseInt( match[1], 10 );
  8099. // Visible index given, convert to column index
  8100. if ( idx < 0 ) {
  8101. // Counting from the right
  8102. var visColumns = $.map( columns, function (col,i) {
  8103. return col.bVisible ? i : null;
  8104. } );
  8105. return [ visColumns[ visColumns.length + idx ] ];
  8106. }
  8107. // Counting from the left
  8108. return [ _fnVisibleToColumnIndex( settings, idx ) ];
  8109.  
  8110. case 'name':
  8111. // match by name. `names` is column index complete and in order
  8112. return $.map( names, function (name, i) {
  8113. return name === match[1] ? i : null;
  8114. } );
  8115. }
  8116. }
  8117. else {
  8118. // jQuery selector on the TH elements for the columns
  8119. return $( nodes )
  8120. .filter( s )
  8121. .map( function () {
  8122. return $.inArray( this, nodes ); // `nodes` is column index complete and in order
  8123. } )
  8124. .toArray();
  8125. }
  8126. } );
  8127. };
  8128.  
  8129.  
  8130. var __setColumnVis = function ( settings, column, vis, recalc ) {
  8131. var
  8132. cols = settings.aoColumns,
  8133. col = cols[ column ],
  8134. data = settings.aoData,
  8135. row, cells, i, ien, tr;
  8136.  
  8137. // Get
  8138. if ( vis === undefined ) {
  8139. return col.bVisible;
  8140. }
  8141.  
  8142. // Set
  8143. // No change
  8144. if ( col.bVisible === vis ) {
  8145. return;
  8146. }
  8147.  
  8148. if ( vis ) {
  8149. // Insert column
  8150. // Need to decide if we should use appendChild or insertBefore
  8151. var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );
  8152.  
  8153. for ( i=0, ien=data.length ; i<ien ; i++ ) {
  8154. tr = data[i].nTr;
  8155. cells = data[i].anCells;
  8156.  
  8157. if ( tr ) {
  8158. // insertBefore can act like appendChild if 2nd arg is null
  8159. tr.insertBefore( cells[ column ], cells[ insertBefore ] || null );
  8160. }
  8161. }
  8162. }
  8163. else {
  8164. // Remove column
  8165. $( _pluck( settings.aoData, 'anCells', column ) ).detach();
  8166. }
  8167.  
  8168. // Common actions
  8169. col.bVisible = vis;
  8170. _fnDrawHead( settings, settings.aoHeader );
  8171. _fnDrawHead( settings, settings.aoFooter );
  8172.  
  8173. if ( recalc === undefined || recalc ) {
  8174. // Automatically adjust column sizing
  8175. _fnAdjustColumnSizing( settings );
  8176.  
  8177. // Realign columns for scrolling
  8178. if ( settings.oScroll.sX || settings.oScroll.sY ) {
  8179. _fnScrollDraw( settings );
  8180. }
  8181. }
  8182.  
  8183. _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis] );
  8184.  
  8185. _fnSaveState( settings );
  8186. };
  8187.  
  8188.  
  8189. /**
  8190. *
  8191. */
  8192. _api_register( 'columns()', function ( selector, opts ) {
  8193. // argument shifting
  8194. if ( selector === undefined ) {
  8195. selector = '';
  8196. }
  8197. else if ( $.isPlainObject( selector ) ) {
  8198. opts = selector;
  8199. selector = '';
  8200. }
  8201.  
  8202. opts = _selector_opts( opts );
  8203.  
  8204. var inst = this.iterator( 'table', function ( settings ) {
  8205. return __column_selector( settings, selector, opts );
  8206. }, 1 );
  8207.  
  8208. // Want argument shifting here and in _row_selector?
  8209. inst.selector.cols = selector;
  8210. inst.selector.opts = opts;
  8211.  
  8212. return inst;
  8213. } );
  8214.  
  8215.  
  8216. /**
  8217. *
  8218. */
  8219. _api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {
  8220. return this.iterator( 'column', function ( settings, column ) {
  8221. return settings.aoColumns[column].nTh;
  8222. }, 1 );
  8223. } );
  8224.  
  8225.  
  8226. /**
  8227. *
  8228. */
  8229. _api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {
  8230. return this.iterator( 'column', function ( settings, column ) {
  8231. return settings.aoColumns[column].nTf;
  8232. }, 1 );
  8233. } );
  8234.  
  8235.  
  8236. /**
  8237. *
  8238. */
  8239. _api_registerPlural( 'columns().data()', 'column().data()', function () {
  8240. return this.iterator( 'column-rows', __columnData, 1 );
  8241. } );
  8242.  
  8243.  
  8244. _api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {
  8245. return this.iterator( 'column', function ( settings, column ) {
  8246. return settings.aoColumns[column].mData;
  8247. }, 1 );
  8248. } );
  8249.  
  8250.  
  8251. _api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {
  8252. return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
  8253. return _pluck_order( settings.aoData, rows,
  8254. type === 'search' ? '_aFilterData' : '_aSortData', column
  8255. );
  8256. }, 1 );
  8257. } );
  8258.  
  8259.  
  8260. _api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
  8261. return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
  8262. return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
  8263. }, 1 );
  8264. } );
  8265.  
  8266.  
  8267.  
  8268. _api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {
  8269. return this.iterator( 'column', function ( settings, column ) {
  8270. if ( vis === undefined ) {
  8271. return settings.aoColumns[ column ].bVisible;
  8272. } // else
  8273. __setColumnVis( settings, column, vis, calc );
  8274. } );
  8275. } );
  8276.  
  8277.  
  8278.  
  8279. _api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {
  8280. return this.iterator( 'column', function ( settings, column ) {
  8281. return type === 'visible' ?
  8282. _fnColumnIndexToVisible( settings, column ) :
  8283. column;
  8284. }, 1 );
  8285. } );
  8286.  
  8287.  
  8288. // _api_register( 'columns().show()', function () {
  8289. // var selector = this.selector;
  8290. // return this.columns( selector.cols, selector.opts ).visible( true );
  8291. // } );
  8292.  
  8293.  
  8294. // _api_register( 'columns().hide()', function () {
  8295. // var selector = this.selector;
  8296. // return this.columns( selector.cols, selector.opts ).visible( false );
  8297. // } );
  8298.  
  8299.  
  8300.  
  8301. _api_register( 'columns.adjust()', function () {
  8302. return this.iterator( 'table', function ( settings ) {
  8303. _fnAdjustColumnSizing( settings );
  8304. }, 1 );
  8305. } );
  8306.  
  8307.  
  8308. // Convert from one column index type, to another type
  8309. _api_register( 'column.index()', function ( type, idx ) {
  8310. if ( this.context.length !== 0 ) {
  8311. var ctx = this.context[0];
  8312.  
  8313. if ( type === 'fromVisible' || type === 'toData' ) {
  8314. return _fnVisibleToColumnIndex( ctx, idx );
  8315. }
  8316. else if ( type === 'fromData' || type === 'toVisible' ) {
  8317. return _fnColumnIndexToVisible( ctx, idx );
  8318. }
  8319. }
  8320. } );
  8321.  
  8322.  
  8323. _api_register( 'column()', function ( selector, opts ) {
  8324. return _selector_first( this.columns( selector, opts ) );
  8325. } );
  8326.  
  8327.  
  8328.  
  8329.  
  8330. var __cell_selector = function ( settings, selector, opts )
  8331. {
  8332. var data = settings.aoData;
  8333. var rows = _selector_row_indexes( settings, opts );
  8334. var cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );
  8335. var allCells = $( [].concat.apply([], cells) );
  8336. var row;
  8337. var columns = settings.aoColumns.length;
  8338. var a, i, ien, j, o, host;
  8339.  
  8340. return _selector_run( selector, function ( s ) {
  8341. var fnSelector = typeof s === 'function';
  8342.  
  8343. if ( s === null || s === undefined || fnSelector ) {
  8344. // All cells and function selectors
  8345. a = [];
  8346.  
  8347. for ( i=0, ien=rows.length ; i<ien ; i++ ) {
  8348. row = rows[i];
  8349.  
  8350. for ( j=0 ; j<columns ; j++ ) {
  8351. o = {
  8352. row: row,
  8353. column: j
  8354. };
  8355.  
  8356. if ( fnSelector ) {
  8357. // Selector - function
  8358. host = settings.aoData[ row ];
  8359.  
  8360. if ( s( o, _fnGetCellData(settings, row, j), host.anCells[j] ) ) {
  8361. a.push( o );
  8362. }
  8363. }
  8364. else {
  8365. // Selector - all
  8366. a.push( o );
  8367. }
  8368. }
  8369. }
  8370.  
  8371. return a;
  8372. }
  8373.  
  8374. // Selector - index
  8375. if ( $.isPlainObject( s ) ) {
  8376. return [s];
  8377. }
  8378.  
  8379. // Selector - jQuery filtered cells
  8380. return allCells
  8381. .filter( s )
  8382. .map( function (i, el) {
  8383. row = el.parentNode._DT_RowIndex;
  8384.  
  8385. return {
  8386. row: row,
  8387. column: $.inArray( el, data[ row ].anCells )
  8388. };
  8389. } )
  8390. .toArray();
  8391. } );
  8392. };
  8393.  
  8394.  
  8395.  
  8396.  
  8397. _api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {
  8398. // Argument shifting
  8399. if ( $.isPlainObject( rowSelector ) ) {
  8400. // Indexes
  8401. if ( typeof rowSelector.row !== undefined ) {
  8402. opts = columnSelector;
  8403. columnSelector = null;
  8404. }
  8405. else {
  8406. opts = rowSelector;
  8407. rowSelector = null;
  8408. }
  8409. }
  8410. if ( $.isPlainObject( columnSelector ) ) {
  8411. opts = columnSelector;
  8412. columnSelector = null;
  8413. }
  8414.  
  8415. // Cell selector
  8416. if ( columnSelector === null || columnSelector === undefined ) {
  8417. return this.iterator( 'table', function ( settings ) {
  8418. return __cell_selector( settings, rowSelector, _selector_opts( opts ) );
  8419. } );
  8420. }
  8421.  
  8422. // Row + column selector
  8423. var columns = this.columns( columnSelector, opts );
  8424. var rows = this.rows( rowSelector, opts );
  8425. var a, i, ien, j, jen;
  8426.  
  8427. var cells = this.iterator( 'table', function ( settings, idx ) {
  8428. a = [];
  8429.  
  8430. for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
  8431. for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
  8432. a.push( {
  8433. row: rows[idx][i],
  8434. column: columns[idx][j]
  8435. } );
  8436. }
  8437. }
  8438.  
  8439. return a;
  8440. }, 1 );
  8441.  
  8442. $.extend( cells.selector, {
  8443. cols: columnSelector,
  8444. rows: rowSelector,
  8445. opts: opts
  8446. } );
  8447.  
  8448. return cells;
  8449. } );
  8450.  
  8451.  
  8452. _api_registerPlural( 'cells().nodes()', 'cell().node()', function () {
  8453. return this.iterator( 'cell', function ( settings, row, column ) {
  8454. var cells = settings.aoData[ row ].anCells;
  8455. return cells ?
  8456. cells[ column ] :
  8457. undefined;
  8458. }, 1 );
  8459. } );
  8460.  
  8461.  
  8462. _api_register( 'cells().data()', function () {
  8463. return this.iterator( 'cell', function ( settings, row, column ) {
  8464. return _fnGetCellData( settings, row, column );
  8465. }, 1 );
  8466. } );
  8467.  
  8468.  
  8469. _api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {
  8470. type = type === 'search' ? '_aFilterData' : '_aSortData';
  8471.  
  8472. return this.iterator( 'cell', function ( settings, row, column ) {
  8473. return settings.aoData[ row ][ type ][ column ];
  8474. }, 1 );
  8475. } );
  8476.  
  8477.  
  8478. _api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {
  8479. return this.iterator( 'cell', function ( settings, row, column ) {
  8480. return _fnGetCellData( settings, row, column, type );
  8481. }, 1 );
  8482. } );
  8483.  
  8484.  
  8485. _api_registerPlural( 'cells().indexes()', 'cell().index()', function () {
  8486. return this.iterator( 'cell', function ( settings, row, column ) {
  8487. return {
  8488. row: row,
  8489. column: column,
  8490. columnVisible: _fnColumnIndexToVisible( settings, column )
  8491. };
  8492. }, 1 );
  8493. } );
  8494.  
  8495.  
  8496. _api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {
  8497. return this.iterator( 'cell', function ( settings, row, column ) {
  8498. _fnInvalidate( settings, row, src, column );
  8499. } );
  8500. } );
  8501.  
  8502.  
  8503.  
  8504. _api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {
  8505. return _selector_first( this.cells( rowSelector, columnSelector, opts ) );
  8506. } );
  8507.  
  8508.  
  8509. _api_register( 'cell().data()', function ( data ) {
  8510. var ctx = this.context;
  8511. var cell = this[0];
  8512.  
  8513. if ( data === undefined ) {
  8514. // Get
  8515. return ctx.length && cell.length ?
  8516. _fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :
  8517. undefined;
  8518. }
  8519.  
  8520. // Set
  8521. _fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );
  8522. _fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );
  8523.  
  8524. return this;
  8525. } );
  8526.  
  8527.  
  8528.  
  8529. /**
  8530. * Get current ordering (sorting) that has been applied to the table.
  8531. *
  8532. * @returns {array} 2D array containing the sorting information for the first
  8533. * table in the current context. Each element in the parent array represents
  8534. * a column being sorted upon (i.e. multi-sorting with two columns would have
  8535. * 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
  8536. * the column index that the sorting condition applies to, the second is the
  8537. * direction of the sort (`desc` or `asc`) and, optionally, the third is the
  8538. * index of the sorting order from the `column.sorting` initialisation array.
  8539. *//**
  8540. * Set the ordering for the table.
  8541. *
  8542. * @param {integer} order Column index to sort upon.
  8543. * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
  8544. * @returns {DataTables.Api} this
  8545. *//**
  8546. * Set the ordering for the table.
  8547. *
  8548. * @param {array} order 1D array of sorting information to be applied.
  8549. * @param {array} [...] Optional additional sorting conditions
  8550. * @returns {DataTables.Api} this
  8551. *//**
  8552. * Set the ordering for the table.
  8553. *
  8554. * @param {array} order 2D array of sorting information to be applied.
  8555. * @returns {DataTables.Api} this
  8556. */
  8557. _api_register( 'order()', function ( order, dir ) {
  8558. var ctx = this.context;
  8559.  
  8560. if ( order === undefined ) {
  8561. // get
  8562. return ctx.length !== 0 ?
  8563. ctx[0].aaSorting :
  8564. undefined;
  8565. }
  8566.  
  8567. // set
  8568. if ( typeof order === 'number' ) {
  8569. // Simple column / direction passed in
  8570. order = [ [ order, dir ] ];
  8571. }
  8572. else if ( ! $.isArray( order[0] ) ) {
  8573. // Arguments passed in (list of 1D arrays)
  8574. order = Array.prototype.slice.call( arguments );
  8575. }
  8576. // otherwise a 2D array was passed in
  8577.  
  8578. return this.iterator( 'table', function ( settings ) {
  8579. settings.aaSorting = order.slice();
  8580. } );
  8581. } );
  8582.  
  8583.  
  8584. /**
  8585. * Attach a sort listener to an element for a given column
  8586. *
  8587. * @param {node|jQuery|string} node Identifier for the element(s) to attach the
  8588. * listener to. This can take the form of a single DOM node, a jQuery
  8589. * collection of nodes or a jQuery selector which will identify the node(s).
  8590. * @param {integer} column the column that a click on this node will sort on
  8591. * @param {function} [callback] callback function when sort is run
  8592. * @returns {DataTables.Api} this
  8593. */
  8594. _api_register( 'order.listener()', function ( node, column, callback ) {
  8595. return this.iterator( 'table', function ( settings ) {
  8596. _fnSortAttachListener( settings, node, column, callback );
  8597. } );
  8598. } );
  8599.  
  8600.  
  8601. // Order by the selected column(s)
  8602. _api_register( [
  8603. 'columns().order()',
  8604. 'column().order()'
  8605. ], function ( dir ) {
  8606. var that = this;
  8607.  
  8608. return this.iterator( 'table', function ( settings, i ) {
  8609. var sort = [];
  8610.  
  8611. $.each( that[i], function (j, col) {
  8612. sort.push( [ col, dir ] );
  8613. } );
  8614.  
  8615. settings.aaSorting = sort;
  8616. } );
  8617. } );
  8618.  
  8619.  
  8620.  
  8621. _api_register( 'search()', function ( input, regex, smart, caseInsen ) {
  8622. var ctx = this.context;
  8623.  
  8624. if ( input === undefined ) {
  8625. // get
  8626. return ctx.length !== 0 ?
  8627. ctx[0].oPreviousSearch.sSearch :
  8628. undefined;
  8629. }
  8630.  
  8631. // set
  8632. return this.iterator( 'table', function ( settings ) {
  8633. if ( ! settings.oFeatures.bFilter ) {
  8634. return;
  8635. }
  8636.  
  8637. _fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {
  8638. "sSearch": input+"",
  8639. "bRegex": regex === null ? false : regex,
  8640. "bSmart": smart === null ? true : smart,
  8641. "bCaseInsensitive": caseInsen === null ? true : caseInsen
  8642. } ), 1 );
  8643. } );
  8644. } );
  8645.  
  8646.  
  8647. _api_registerPlural(
  8648. 'columns().search()',
  8649. 'column().search()',
  8650. function ( input, regex, smart, caseInsen ) {
  8651. return this.iterator( 'column', function ( settings, column ) {
  8652. var preSearch = settings.aoPreSearchCols;
  8653.  
  8654. if ( input === undefined ) {
  8655. // get
  8656. return preSearch[ column ].sSearch;
  8657. }
  8658.  
  8659. // set
  8660. if ( ! settings.oFeatures.bFilter ) {
  8661. return;
  8662. }
  8663.  
  8664. $.extend( preSearch[ column ], {
  8665. "sSearch": input+"",
  8666. "bRegex": regex === null ? false : regex,
  8667. "bSmart": smart === null ? true : smart,
  8668. "bCaseInsensitive": caseInsen === null ? true : caseInsen
  8669. } );
  8670.  
  8671. _fnFilterComplete( settings, settings.oPreviousSearch, 1 );
  8672. } );
  8673. }
  8674. );
  8675.  
  8676. /*
  8677. * State API methods
  8678. */
  8679.  
  8680. _api_register( 'state()', function () {
  8681. return this.context.length ?
  8682. this.context[0].oSavedState :
  8683. null;
  8684. } );
  8685.  
  8686.  
  8687. _api_register( 'state.clear()', function () {
  8688. return this.iterator( 'table', function ( settings ) {
  8689. // Save an empty object
  8690. settings.fnStateSaveCallback.call( settings.oInstance, settings, {} );
  8691. } );
  8692. } );
  8693.  
  8694.  
  8695. _api_register( 'state.loaded()', function () {
  8696. return this.context.length ?
  8697. this.context[0].oLoadedState :
  8698. null;
  8699. } );
  8700.  
  8701.  
  8702. _api_register( 'state.save()', function () {
  8703. return this.iterator( 'table', function ( settings ) {
  8704. _fnSaveState( settings );
  8705. } );
  8706. } );
  8707.  
  8708.  
  8709.  
  8710. /**
  8711. * Provide a common method for plug-ins to check the version of DataTables being
  8712. * used, in order to ensure compatibility.
  8713. *
  8714. * @param {string} version Version string to check for, in the format "X.Y.Z".
  8715. * Note that the formats "X" and "X.Y" are also acceptable.
  8716. * @returns {boolean} true if this version of DataTables is greater or equal to
  8717. * the required version, or false if this version of DataTales is not
  8718. * suitable
  8719. * @static
  8720. * @dtopt API-Static
  8721. *
  8722. * @example
  8723. * alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
  8724. */
  8725. DataTable.versionCheck = DataTable.fnVersionCheck = function( version )
  8726. {
  8727. var aThis = DataTable.version.split('.');
  8728. var aThat = version.split('.');
  8729. var iThis, iThat;
  8730.  
  8731. for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {
  8732. iThis = parseInt( aThis[i], 10 ) || 0;
  8733. iThat = parseInt( aThat[i], 10 ) || 0;
  8734.  
  8735. // Parts are the same, keep comparing
  8736. if (iThis === iThat) {
  8737. continue;
  8738. }
  8739.  
  8740. // Parts are different, return immediately
  8741. return iThis > iThat;
  8742. }
  8743.  
  8744. return true;
  8745. };
  8746.  
  8747.  
  8748. /**
  8749. * Check if a `<table>` node is a DataTable table already or not.
  8750. *
  8751. * @param {node|jquery|string} table Table node, jQuery object or jQuery
  8752. * selector for the table to test. Note that if more than more than one
  8753. * table is passed on, only the first will be checked
  8754. * @returns {boolean} true the table given is a DataTable, or false otherwise
  8755. * @static
  8756. * @dtopt API-Static
  8757. *
  8758. * @example
  8759. * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
  8760. * $('#example').dataTable();
  8761. * }
  8762. */
  8763. DataTable.isDataTable = DataTable.fnIsDataTable = function ( table )
  8764. {
  8765. var t = $(table).get(0);
  8766. var is = false;
  8767.  
  8768. $.each( DataTable.settings, function (i, o) {
  8769. if ( o.nTable === t || o.nScrollHead === t || o.nScrollFoot === t ) {
  8770. is = true;
  8771. }
  8772. } );
  8773.  
  8774. return is;
  8775. };
  8776.  
  8777.  
  8778. /**
  8779. * Get all DataTable tables that have been initialised - optionally you can
  8780. * select to get only currently visible tables.
  8781. *
  8782. * @param {boolean} [visible=false] Flag to indicate if you want all (default)
  8783. * or visible tables only.
  8784. * @returns {array} Array of `table` nodes (not DataTable instances) which are
  8785. * DataTables
  8786. * @static
  8787. * @dtopt API-Static
  8788. *
  8789. * @example
  8790. * $.each( $.fn.dataTable.tables(true), function () {
  8791. * $(table).DataTable().columns.adjust();
  8792. * } );
  8793. */
  8794. DataTable.tables = DataTable.fnTables = function ( visible )
  8795. {
  8796. return $.map( DataTable.settings, function (o) {
  8797. if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
  8798. return o.nTable;
  8799. }
  8800. } );
  8801. };
  8802.  
  8803.  
  8804. /**
  8805. * DataTables utility methods
  8806. *
  8807. * This namespace provides helper methods that DataTables uses internally to
  8808. * create a DataTable, but which are not exclusively used only for DataTables.
  8809. * These methods can be used by extension authors to save the duplication of
  8810. * code.
  8811. *
  8812. * @namespace
  8813. */
  8814. DataTable.util = {
  8815. /**
  8816. * Throttle the calls to a function. Arguments and context are maintained
  8817. * for the throttled function.
  8818. *
  8819. * @param {function} fn Function to be called
  8820. * @param {integer} freq Call frequency in mS
  8821. * @return {function} Wrapped function
  8822. */
  8823. throttle: _fnThrottle,
  8824.  
  8825.  
  8826. /**
  8827. * Escape a string such that it can be used in a regular expression
  8828. *
  8829. * @param {string} sVal string to escape
  8830. * @returns {string} escaped string
  8831. */
  8832. escapeRegex: _fnEscapeRegex
  8833. };
  8834.  
  8835.  
  8836. /**
  8837. * Convert from camel case parameters to Hungarian notation. This is made public
  8838. * for the extensions to provide the same ability as DataTables core to accept
  8839. * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
  8840. * parameters.
  8841. *
  8842. * @param {object} src The model object which holds all parameters that can be
  8843. * mapped.
  8844. * @param {object} user The object to convert from camel case to Hungarian.
  8845. * @param {boolean} force When set to `true`, properties which already have a
  8846. * Hungarian value in the `user` object will be overwritten. Otherwise they
  8847. * won't be.
  8848. */
  8849. DataTable.camelToHungarian = _fnCamelToHungarian;
  8850.  
  8851.  
  8852.  
  8853. /**
  8854. *
  8855. */
  8856. _api_register( '$()', function ( selector, opts ) {
  8857. var
  8858. rows = this.rows( opts ).nodes(), // Get all rows
  8859. jqRows = $(rows);
  8860.  
  8861. return $( [].concat(
  8862. jqRows.filter( selector ).toArray(),
  8863. jqRows.find( selector ).toArray()
  8864. ) );
  8865. } );
  8866.  
  8867.  
  8868. // jQuery functions to operate on the tables
  8869. $.each( [ 'on', 'one', 'off' ], function (i, key) {
  8870. _api_register( key+'()', function ( /* event, handler */ ) {
  8871. var args = Array.prototype.slice.call(arguments);
  8872.  
  8873. // Add the `dt` namespace automatically if it isn't already present
  8874. if ( ! args[0].match(/\.dt\b/) ) {
  8875. args[0] += '.dt';
  8876. }
  8877.  
  8878. var inst = $( this.tables().nodes() );
  8879. inst[key].apply( inst, args );
  8880. return this;
  8881. } );
  8882. } );
  8883.  
  8884.  
  8885. _api_register( 'clear()', function () {
  8886. return this.iterator( 'table', function ( settings ) {
  8887. _fnClearTable( settings );
  8888. } );
  8889. } );
  8890.  
  8891.  
  8892. _api_register( 'settings()', function () {
  8893. return new _Api( this.context, this.context );
  8894. } );
  8895.  
  8896.  
  8897. _api_register( 'data()', function () {
  8898. return this.iterator( 'table', function ( settings ) {
  8899. return _pluck( settings.aoData, '_aData' );
  8900. } ).flatten();
  8901. } );
  8902.  
  8903.  
  8904. _api_register( 'destroy()', function ( remove ) {
  8905. remove = remove || false;
  8906.  
  8907. return this.iterator( 'table', function ( settings ) {
  8908. var orig = settings.nTableWrapper.parentNode;
  8909. var classes = settings.oClasses;
  8910. var table = settings.nTable;
  8911. var tbody = settings.nTBody;
  8912. var thead = settings.nTHead;
  8913. var tfoot = settings.nTFoot;
  8914. var jqTable = $(table);
  8915. var jqTbody = $(tbody);
  8916. var jqWrapper = $(settings.nTableWrapper);
  8917. var rows = $.map( settings.aoData, function (r) { return r.nTr; } );
  8918. var i, ien;
  8919.  
  8920. // Flag to note that the table is currently being destroyed - no action
  8921. // should be taken
  8922. settings.bDestroying = true;
  8923.  
  8924. // Fire off the destroy callbacks for plug-ins etc
  8925. _fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] );
  8926.  
  8927. // If not being removed from the document, make all columns visible
  8928. if ( ! remove ) {
  8929. new _Api( settings ).columns().visible( true );
  8930. }
  8931.  
  8932. // Blitz all `DT` namespaced events (these are internal events, the
  8933. // lowercase, `dt` events are user subscribed and they are responsible
  8934. // for removing them
  8935. jqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');
  8936. $(window).unbind('.DT-'+settings.sInstance);
  8937.  
  8938. // When scrolling we had to break the table up - restore it
  8939. if ( table != thead.parentNode ) {
  8940. jqTable.children('thead').detach();
  8941. jqTable.append( thead );
  8942. }
  8943.  
  8944. if ( tfoot && table != tfoot.parentNode ) {
  8945. jqTable.children('tfoot').detach();
  8946. jqTable.append( tfoot );
  8947. }
  8948.  
  8949. // Remove the DataTables generated nodes, events and classes
  8950. jqTable.detach();
  8951. jqWrapper.detach();
  8952.  
  8953. settings.aaSorting = [];
  8954. settings.aaSortingFixed = [];
  8955. _fnSortingClasses( settings );
  8956.  
  8957. $( rows ).removeClass( settings.asStripeClasses.join(' ') );
  8958.  
  8959. $('th, td', thead).removeClass( classes.sSortable+' '+
  8960. classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone
  8961. );
  8962.  
  8963. if ( settings.bJUI ) {
  8964. $('th span.'+classes.sSortIcon+ ', td span.'+classes.sSortIcon, thead).detach();
  8965. $('th, td', thead).each( function () {
  8966. var wrapper = $('div.'+classes.sSortJUIWrapper, this);
  8967. $(this).append( wrapper.contents() );
  8968. wrapper.detach();
  8969. } );
  8970. }
  8971.  
  8972. if ( ! remove && orig ) {
  8973. // insertBefore acts like appendChild if !arg[1]
  8974. orig.insertBefore( table, settings.nTableReinsertBefore );
  8975. }
  8976.  
  8977. // Add the TR elements back into the table in their original order
  8978. jqTbody.children().detach();
  8979. jqTbody.append( rows );
  8980.  
  8981. // Restore the width of the original table - was read from the style property,
  8982. // so we can restore directly to that
  8983. jqTable
  8984. .css( 'width', settings.sDestroyWidth )
  8985. .removeClass( classes.sTable );
  8986.  
  8987. // If the were originally stripe classes - then we add them back here.
  8988. // Note this is not fool proof (for example if not all rows had stripe
  8989. // classes - but it's a good effort without getting carried away
  8990. ien = settings.asDestroyStripes.length;
  8991.  
  8992. if ( ien ) {
  8993. jqTbody.children().each( function (i) {
  8994. $(this).addClass( settings.asDestroyStripes[i % ien] );
  8995. } );
  8996. }
  8997.  
  8998. /* Remove the settings object from the settings array */
  8999. var idx = $.inArray( settings, DataTable.settings );
  9000. if ( idx !== -1 ) {
  9001. DataTable.settings.splice( idx, 1 );
  9002. }
  9003. } );
  9004. } );
  9005.  
  9006.  
  9007. /**
  9008. * Version string for plug-ins to check compatibility. Allowed format is
  9009. * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
  9010. * only for non-release builds. See http://semver.org/ for more information.
  9011. * @member
  9012. * @type string
  9013. * @default Version number
  9014. */
  9015. DataTable.version = "1.10.4";
  9016.  
  9017. /**
  9018. * Private data store, containing all of the settings objects that are
  9019. * created for the tables on a given page.
  9020. *
  9021. * Note that the `DataTable.settings` object is aliased to
  9022. * `jQuery.fn.dataTableExt` through which it may be accessed and
  9023. * manipulated, or `jQuery.fn.dataTable.settings`.
  9024. * @member
  9025. * @type array
  9026. * @default []
  9027. * @private
  9028. */
  9029. DataTable.settings = [];
  9030.  
  9031. /**
  9032. * Object models container, for the various models that DataTables has
  9033. * available to it. These models define the objects that are used to hold
  9034. * the active state and configuration of the table.
  9035. * @namespace
  9036. */
  9037. DataTable.models = {};
  9038.  
  9039.  
  9040.  
  9041. /**
  9042. * Template object for the way in which DataTables holds information about
  9043. * search information for the global filter and individual column filters.
  9044. * @namespace
  9045. */
  9046. DataTable.models.oSearch = {
  9047. /**
  9048. * Flag to indicate if the filtering should be case insensitive or not
  9049. * @type boolean
  9050. * @default true
  9051. */
  9052. "bCaseInsensitive": true,
  9053.  
  9054. /**
  9055. * Applied search term
  9056. * @type string
  9057. * @default <i>Empty string</i>
  9058. */
  9059. "sSearch": "",
  9060.  
  9061. /**
  9062. * Flag to indicate if the search term should be interpreted as a
  9063. * regular expression (true) or not (false) and therefore and special
  9064. * regex characters escaped.
  9065. * @type boolean
  9066. * @default false
  9067. */
  9068. "bRegex": false,
  9069.  
  9070. /**
  9071. * Flag to indicate if DataTables is to use its smart filtering or not.
  9072. * @type boolean
  9073. * @default true
  9074. */
  9075. "bSmart": true
  9076. };
  9077.  
  9078.  
  9079.  
  9080.  
  9081. /**
  9082. * Template object for the way in which DataTables holds information about
  9083. * each individual row. This is the object format used for the settings
  9084. * aoData array.
  9085. * @namespace
  9086. */
  9087. DataTable.models.oRow = {
  9088. /**
  9089. * TR element for the row
  9090. * @type node
  9091. * @default null
  9092. */
  9093. "nTr": null,
  9094.  
  9095. /**
  9096. * Array of TD elements for each row. This is null until the row has been
  9097. * created.
  9098. * @type array nodes
  9099. * @default []
  9100. */
  9101. "anCells": null,
  9102.  
  9103. /**
  9104. * Data object from the original data source for the row. This is either
  9105. * an array if using the traditional form of DataTables, or an object if
  9106. * using mData options. The exact type will depend on the passed in
  9107. * data from the data source, or will be an array if using DOM a data
  9108. * source.
  9109. * @type array|object
  9110. * @default []
  9111. */
  9112. "_aData": [],
  9113.  
  9114. /**
  9115. * Sorting data cache - this array is ostensibly the same length as the
  9116. * number of columns (although each index is generated only as it is
  9117. * needed), and holds the data that is used for sorting each column in the
  9118. * row. We do this cache generation at the start of the sort in order that
  9119. * the formatting of the sort data need be done only once for each cell
  9120. * per sort. This array should not be read from or written to by anything
  9121. * other than the master sorting methods.
  9122. * @type array
  9123. * @default null
  9124. * @private
  9125. */
  9126. "_aSortData": null,
  9127.  
  9128. /**
  9129. * Per cell filtering data cache. As per the sort data cache, used to
  9130. * increase the performance of the filtering in DataTables
  9131. * @type array
  9132. * @default null
  9133. * @private
  9134. */
  9135. "_aFilterData": null,
  9136.  
  9137. /**
  9138. * Filtering data cache. This is the same as the cell filtering cache, but
  9139. * in this case a string rather than an array. This is easily computed with
  9140. * a join on `_aFilterData`, but is provided as a cache so the join isn't
  9141. * needed on every search (memory traded for performance)
  9142. * @type array
  9143. * @default null
  9144. * @private
  9145. */
  9146. "_sFilterRow": null,
  9147.  
  9148. /**
  9149. * Cache of the class name that DataTables has applied to the row, so we
  9150. * can quickly look at this variable rather than needing to do a DOM check
  9151. * on className for the nTr property.
  9152. * @type string
  9153. * @default <i>Empty string</i>
  9154. * @private
  9155. */
  9156. "_sRowStripe": "",
  9157.  
  9158. /**
  9159. * Denote if the original data source was from the DOM, or the data source
  9160. * object. This is used for invalidating data, so DataTables can
  9161. * automatically read data from the original source, unless uninstructed
  9162. * otherwise.
  9163. * @type string
  9164. * @default null
  9165. * @private
  9166. */
  9167. "src": null
  9168. };
  9169.  
  9170.  
  9171. /**
  9172. * Template object for the column information object in DataTables. This object
  9173. * is held in the settings aoColumns array and contains all the information that
  9174. * DataTables needs about each individual column.
  9175. *
  9176. * Note that this object is related to {@link DataTable.defaults.column}
  9177. * but this one is the internal data store for DataTables's cache of columns.
  9178. * It should NOT be manipulated outside of DataTables. Any configuration should
  9179. * be done through the initialisation options.
  9180. * @namespace
  9181. */
  9182. DataTable.models.oColumn = {
  9183. /**
  9184. * Column index. This could be worked out on-the-fly with $.inArray, but it
  9185. * is faster to just hold it as a variable
  9186. * @type integer
  9187. * @default null
  9188. */
  9189. "idx": null,
  9190.  
  9191. /**
  9192. * A list of the columns that sorting should occur on when this column
  9193. * is sorted. That this property is an array allows multi-column sorting
  9194. * to be defined for a column (for example first name / last name columns
  9195. * would benefit from this). The values are integers pointing to the
  9196. * columns to be sorted on (typically it will be a single integer pointing
  9197. * at itself, but that doesn't need to be the case).
  9198. * @type array
  9199. */
  9200. "aDataSort": null,
  9201.  
  9202. /**
  9203. * Define the sorting directions that are applied to the column, in sequence
  9204. * as the column is repeatedly sorted upon - i.e. the first value is used
  9205. * as the sorting direction when the column if first sorted (clicked on).
  9206. * Sort it again (click again) and it will move on to the next index.
  9207. * Repeat until loop.
  9208. * @type array
  9209. */
  9210. "asSorting": null,
  9211.  
  9212. /**
  9213. * Flag to indicate if the column is searchable, and thus should be included
  9214. * in the filtering or not.
  9215. * @type boolean
  9216. */
  9217. "bSearchable": null,
  9218.  
  9219. /**
  9220. * Flag to indicate if the column is sortable or not.
  9221. * @type boolean
  9222. */
  9223. "bSortable": null,
  9224.  
  9225. /**
  9226. * Flag to indicate if the column is currently visible in the table or not
  9227. * @type boolean
  9228. */
  9229. "bVisible": null,
  9230.  
  9231. /**
  9232. * Store for manual type assignment using the `column.type` option. This
  9233. * is held in store so we can manipulate the column's `sType` property.
  9234. * @type string
  9235. * @default null
  9236. * @private
  9237. */
  9238. "_sManualType": null,
  9239.  
  9240. /**
  9241. * Flag to indicate if HTML5 data attributes should be used as the data
  9242. * source for filtering or sorting. True is either are.
  9243. * @type boolean
  9244. * @default false
  9245. * @private
  9246. */
  9247. "_bAttrSrc": false,
  9248.  
  9249. /**
  9250. * Developer definable function that is called whenever a cell is created (Ajax source,
  9251. * etc) or processed for input (DOM source). This can be used as a compliment to mRender
  9252. * allowing you to modify the DOM element (add background colour for example) when the
  9253. * element is available.
  9254. * @type function
  9255. * @param {element} nTd The TD node that has been created
  9256. * @param {*} sData The Data for the cell
  9257. * @param {array|object} oData The data for the whole row
  9258. * @param {int} iRow The row index for the aoData data store
  9259. * @default null
  9260. */
  9261. "fnCreatedCell": null,
  9262.  
  9263. /**
  9264. * Function to get data from a cell in a column. You should <b>never</b>
  9265. * access data directly through _aData internally in DataTables - always use
  9266. * the method attached to this property. It allows mData to function as
  9267. * required. This function is automatically assigned by the column
  9268. * initialisation method
  9269. * @type function
  9270. * @param {array|object} oData The data array/object for the array
  9271. * (i.e. aoData[]._aData)
  9272. * @param {string} sSpecific The specific data type you want to get -
  9273. * 'display', 'type' 'filter' 'sort'
  9274. * @returns {*} The data for the cell from the given row's data
  9275. * @default null
  9276. */
  9277. "fnGetData": null,
  9278.  
  9279. /**
  9280. * Function to set data for a cell in the column. You should <b>never</b>
  9281. * set the data directly to _aData internally in DataTables - always use
  9282. * this method. It allows mData to function as required. This function
  9283. * is automatically assigned by the column initialisation method
  9284. * @type function
  9285. * @param {array|object} oData The data array/object for the array
  9286. * (i.e. aoData[]._aData)
  9287. * @param {*} sValue Value to set
  9288. * @default null
  9289. */
  9290. "fnSetData": null,
  9291.  
  9292. /**
  9293. * Property to read the value for the cells in the column from the data
  9294. * source array / object. If null, then the default content is used, if a
  9295. * function is given then the return from the function is used.
  9296. * @type function|int|string|null
  9297. * @default null
  9298. */
  9299. "mData": null,
  9300.  
  9301. /**
  9302. * Partner property to mData which is used (only when defined) to get
  9303. * the data - i.e. it is basically the same as mData, but without the
  9304. * 'set' option, and also the data fed to it is the result from mData.
  9305. * This is the rendering method to match the data method of mData.
  9306. * @type function|int|string|null
  9307. * @default null
  9308. */
  9309. "mRender": null,
  9310.  
  9311. /**
  9312. * Unique header TH/TD element for this column - this is what the sorting
  9313. * listener is attached to (if sorting is enabled.)
  9314. * @type node
  9315. * @default null
  9316. */
  9317. "nTh": null,
  9318.  
  9319. /**
  9320. * Unique footer TH/TD element for this column (if there is one). Not used
  9321. * in DataTables as such, but can be used for plug-ins to reference the
  9322. * footer for each column.
  9323. * @type node
  9324. * @default null
  9325. */
  9326. "nTf": null,
  9327.  
  9328. /**
  9329. * The class to apply to all TD elements in the table's TBODY for the column
  9330. * @type string
  9331. * @default null
  9332. */
  9333. "sClass": null,
  9334.  
  9335. /**
  9336. * When DataTables calculates the column widths to assign to each column,
  9337. * it finds the longest string in each column and then constructs a
  9338. * temporary table and reads the widths from that. The problem with this
  9339. * is that "mmm" is much wider then "iiii", but the latter is a longer
  9340. * string - thus the calculation can go wrong (doing it properly and putting
  9341. * it into an DOM object and measuring that is horribly(!) slow). Thus as
  9342. * a "work around" we provide this option. It will append its value to the
  9343. * text that is found to be the longest string for the column - i.e. padding.
  9344. * @type string
  9345. */
  9346. "sContentPadding": null,
  9347.  
  9348. /**
  9349. * Allows a default value to be given for a column's data, and will be used
  9350. * whenever a null data source is encountered (this can be because mData
  9351. * is set to null, or because the data source itself is null).
  9352. * @type string
  9353. * @default null
  9354. */
  9355. "sDefaultContent": null,
  9356.  
  9357. /**
  9358. * Name for the column, allowing reference to the column by name as well as
  9359. * by index (needs a lookup to work by name).
  9360. * @type string
  9361. */
  9362. "sName": null,
  9363.  
  9364. /**
  9365. * Custom sorting data type - defines which of the available plug-ins in
  9366. * afnSortData the custom sorting will use - if any is defined.
  9367. * @type string
  9368. * @default std
  9369. */
  9370. "sSortDataType": 'std',
  9371.  
  9372. /**
  9373. * Class to be applied to the header element when sorting on this column
  9374. * @type string
  9375. * @default null
  9376. */
  9377. "sSortingClass": null,
  9378.  
  9379. /**
  9380. * Class to be applied to the header element when sorting on this column -
  9381. * when jQuery UI theming is used.
  9382. * @type string
  9383. * @default null
  9384. */
  9385. "sSortingClassJUI": null,
  9386.  
  9387. /**
  9388. * Title of the column - what is seen in the TH element (nTh).
  9389. * @type string
  9390. */
  9391. "sTitle": null,
  9392.  
  9393. /**
  9394. * Column sorting and filtering type
  9395. * @type string
  9396. * @default null
  9397. */
  9398. "sType": null,
  9399.  
  9400. /**
  9401. * Width of the column
  9402. * @type string
  9403. * @default null
  9404. */
  9405. "sWidth": null,
  9406.  
  9407. /**
  9408. * Width of the column when it was first "encountered"
  9409. * @type string
  9410. * @default null
  9411. */
  9412. "sWidthOrig": null
  9413. };
  9414.  
  9415.  
  9416. /*
  9417. * Developer note: The properties of the object below are given in Hungarian
  9418. * notation, that was used as the interface for DataTables prior to v1.10, however
  9419. * from v1.10 onwards the primary interface is camel case. In order to avoid
  9420. * breaking backwards compatibility utterly with this change, the Hungarian
  9421. * version is still, internally the primary interface, but is is not documented
  9422. * - hence the @name tags in each doc comment. This allows a Javascript function
  9423. * to create a map from Hungarian notation to camel case (going the other direction
  9424. * would require each property to be listed, which would at around 3K to the size
  9425. * of DataTables, while this method is about a 0.5K hit.
  9426. *
  9427. * Ultimately this does pave the way for Hungarian notation to be dropped
  9428. * completely, but that is a massive amount of work and will break current
  9429. * installs (therefore is on-hold until v2).
  9430. */
  9431.  
  9432. /**
  9433. * Initialisation options that can be given to DataTables at initialisation
  9434. * time.
  9435. * @namespace
  9436. */
  9437. DataTable.defaults = {
  9438. /**
  9439. * An array of data to use for the table, passed in at initialisation which
  9440. * will be used in preference to any data which is already in the DOM. This is
  9441. * particularly useful for constructing tables purely in Javascript, for
  9442. * example with a custom Ajax call.
  9443. * @type array
  9444. * @default null
  9445. *
  9446. * @dtopt Option
  9447. * @name DataTable.defaults.data
  9448. *
  9449. * @example
  9450. * // Using a 2D array data source
  9451. * $(document).ready( function () {
  9452. * $('#example').dataTable( {
  9453. * "data": [
  9454. * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
  9455. * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
  9456. * ],
  9457. * "columns": [
  9458. * { "title": "Engine" },
  9459. * { "title": "Browser" },
  9460. * { "title": "Platform" },
  9461. * { "title": "Version" },
  9462. * { "title": "Grade" }
  9463. * ]
  9464. * } );
  9465. * } );
  9466. *
  9467. * @example
  9468. * // Using an array of objects as a data source (`data`)
  9469. * $(document).ready( function () {
  9470. * $('#example').dataTable( {
  9471. * "data": [
  9472. * {
  9473. * "engine": "Trident",
  9474. * "browser": "Internet Explorer 4.0",
  9475. * "platform": "Win 95+",
  9476. * "version": 4,
  9477. * "grade": "X"
  9478. * },
  9479. * {
  9480. * "engine": "Trident",
  9481. * "browser": "Internet Explorer 5.0",
  9482. * "platform": "Win 95+",
  9483. * "version": 5,
  9484. * "grade": "C"
  9485. * }
  9486. * ],
  9487. * "columns": [
  9488. * { "title": "Engine", "data": "engine" },
  9489. * { "title": "Browser", "data": "browser" },
  9490. * { "title": "Platform", "data": "platform" },
  9491. * { "title": "Version", "data": "version" },
  9492. * { "title": "Grade", "data": "grade" }
  9493. * ]
  9494. * } );
  9495. * } );
  9496. */
  9497. "aaData": null,
  9498.  
  9499.  
  9500. /**
  9501. * If ordering is enabled, then DataTables will perform a first pass sort on
  9502. * initialisation. You can define which column(s) the sort is performed
  9503. * upon, and the sorting direction, with this variable. The `sorting` array
  9504. * should contain an array for each column to be sorted initially containing
  9505. * the column's index and a direction string ('asc' or 'desc').
  9506. * @type array
  9507. * @default [[0,'asc']]
  9508. *
  9509. * @dtopt Option
  9510. * @name DataTable.defaults.order
  9511. *
  9512. * @example
  9513. * // Sort by 3rd column first, and then 4th column
  9514. * $(document).ready( function() {
  9515. * $('#example').dataTable( {
  9516. * "order": [[2,'asc'], [3,'desc']]
  9517. * } );
  9518. * } );
  9519. *
  9520. * // No initial sorting
  9521. * $(document).ready( function() {
  9522. * $('#example').dataTable( {
  9523. * "order": []
  9524. * } );
  9525. * } );
  9526. */
  9527. "aaSorting": [[0,'asc']],
  9528.  
  9529.  
  9530. /**
  9531. * This parameter is basically identical to the `sorting` parameter, but
  9532. * cannot be overridden by user interaction with the table. What this means
  9533. * is that you could have a column (visible or hidden) which the sorting
  9534. * will always be forced on first - any sorting after that (from the user)
  9535. * will then be performed as required. This can be useful for grouping rows
  9536. * together.
  9537. * @type array
  9538. * @default null
  9539. *
  9540. * @dtopt Option
  9541. * @name DataTable.defaults.orderFixed
  9542. *
  9543. * @example
  9544. * $(document).ready( function() {
  9545. * $('#example').dataTable( {
  9546. * "orderFixed": [[0,'asc']]
  9547. * } );
  9548. * } )
  9549. */
  9550. "aaSortingFixed": [],
  9551.  
  9552.  
  9553. /**
  9554. * DataTables can be instructed to load data to display in the table from a
  9555. * Ajax source. This option defines how that Ajax call is made and where to.
  9556. *
  9557. * The `ajax` property has three different modes of operation, depending on
  9558. * how it is defined. These are:
  9559. *
  9560. * * `string` - Set the URL from where the data should be loaded from.
  9561. * * `object` - Define properties for `jQuery.ajax`.
  9562. * * `function` - Custom data get function
  9563. *
  9564. * `string`
  9565. * --------
  9566. *
  9567. * As a string, the `ajax` property simply defines the URL from which
  9568. * DataTables will load data.
  9569. *
  9570. * `object`
  9571. * --------
  9572. *
  9573. * As an object, the parameters in the object are passed to
  9574. * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
  9575. * of the Ajax request. DataTables has a number of default parameters which
  9576. * you can override using this option. Please refer to the jQuery
  9577. * documentation for a full description of the options available, although
  9578. * the following parameters provide additional options in DataTables or
  9579. * require special consideration:
  9580. *
  9581. * * `data` - As with jQuery, `data` can be provided as an object, but it
  9582. * can also be used as a function to manipulate the data DataTables sends
  9583. * to the server. The function takes a single parameter, an object of
  9584. * parameters with the values that DataTables has readied for sending. An
  9585. * object may be returned which will be merged into the DataTables
  9586. * defaults, or you can add the items to the object that was passed in and
  9587. * not return anything from the function. This supersedes `fnServerParams`
  9588. * from DataTables 1.9-.
  9589. *
  9590. * * `dataSrc` - By default DataTables will look for the property `data` (or
  9591. * `aaData` for compatibility with DataTables 1.9-) when obtaining data
  9592. * from an Ajax source or for server-side processing - this parameter
  9593. * allows that property to be changed. You can use Javascript dotted
  9594. * object notation to get a data source for multiple levels of nesting, or
  9595. * it my be used as a function. As a function it takes a single parameter,
  9596. * the JSON returned from the server, which can be manipulated as
  9597. * required, with the returned value being that used by DataTables as the
  9598. * data source for the table. This supersedes `sAjaxDataProp` from
  9599. * DataTables 1.9-.
  9600. *
  9601. * * `success` - Should not be overridden it is used internally in
  9602. * DataTables. To manipulate / transform the data returned by the server
  9603. * use `ajax.dataSrc`, or use `ajax` as a function (see below).
  9604. *
  9605. * `function`
  9606. * ----------
  9607. *
  9608. * As a function, making the Ajax call is left up to yourself allowing
  9609. * complete control of the Ajax request. Indeed, if desired, a method other
  9610. * than Ajax could be used to obtain the required data, such as Web storage
  9611. * or an AIR database.
  9612. *
  9613. * The function is given four parameters and no return is required. The
  9614. * parameters are:
  9615. *
  9616. * 1. _object_ - Data to send to the server
  9617. * 2. _function_ - Callback function that must be executed when the required
  9618. * data has been obtained. That data should be passed into the callback
  9619. * as the only parameter
  9620. * 3. _object_ - DataTables settings object for the table
  9621. *
  9622. * Note that this supersedes `fnServerData` from DataTables 1.9-.
  9623. *
  9624. * @type string|object|function
  9625. * @default null
  9626. *
  9627. * @dtopt Option
  9628. * @name DataTable.defaults.ajax
  9629. * @since 1.10.0
  9630. *
  9631. * @example
  9632. * // Get JSON data from a file via Ajax.
  9633. * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
  9634. * $('#example').dataTable( {
  9635. * "ajax": "data.json"
  9636. * } );
  9637. *
  9638. * @example
  9639. * // Get JSON data from a file via Ajax, using `dataSrc` to change
  9640. * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
  9641. * $('#example').dataTable( {
  9642. * "ajax": {
  9643. * "url": "data.json",
  9644. * "dataSrc": "tableData"
  9645. * }
  9646. * } );
  9647. *
  9648. * @example
  9649. * // Get JSON data from a file via Ajax, using `dataSrc` to read data
  9650. * // from a plain array rather than an array in an object
  9651. * $('#example').dataTable( {
  9652. * "ajax": {
  9653. * "url": "data.json",
  9654. * "dataSrc": ""
  9655. * }
  9656. * } );
  9657. *
  9658. * @example
  9659. * // Manipulate the data returned from the server - add a link to data
  9660. * // (note this can, should, be done using `render` for the column - this
  9661. * // is just a simple example of how the data can be manipulated).
  9662. * $('#example').dataTable( {
  9663. * "ajax": {
  9664. * "url": "data.json",
  9665. * "dataSrc": function ( json ) {
  9666. * for ( var i=0, ien=json.length ; i<ien ; i++ ) {
  9667. * json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
  9668. * }
  9669. * return json;
  9670. * }
  9671. * }
  9672. * } );
  9673. *
  9674. * @example
  9675. * // Add data to the request
  9676. * $('#example').dataTable( {
  9677. * "ajax": {
  9678. * "url": "data.json",
  9679. * "data": function ( d ) {
  9680. * return {
  9681. * "extra_search": $('#extra').val()
  9682. * };
  9683. * }
  9684. * }
  9685. * } );
  9686. *
  9687. * @example
  9688. * // Send request as POST
  9689. * $('#example').dataTable( {
  9690. * "ajax": {
  9691. * "url": "data.json",
  9692. * "type": "POST"
  9693. * }
  9694. * } );
  9695. *
  9696. * @example
  9697. * // Get the data from localStorage (could interface with a form for
  9698. * // adding, editing and removing rows).
  9699. * $('#example').dataTable( {
  9700. * "ajax": function (data, callback, settings) {
  9701. * callback(
  9702. * JSON.parse( localStorage.getItem('dataTablesData') )
  9703. * );
  9704. * }
  9705. * } );
  9706. */
  9707. "ajax": null,
  9708.  
  9709.  
  9710. /**
  9711. * This parameter allows you to readily specify the entries in the length drop
  9712. * down menu that DataTables shows when pagination is enabled. It can be
  9713. * either a 1D array of options which will be used for both the displayed
  9714. * option and the value, or a 2D array which will use the array in the first
  9715. * position as the value, and the array in the second position as the
  9716. * displayed options (useful for language strings such as 'All').
  9717. *
  9718. * Note that the `pageLength` property will be automatically set to the
  9719. * first value given in this array, unless `pageLength` is also provided.
  9720. * @type array
  9721. * @default [ 10, 25, 50, 100 ]
  9722. *
  9723. * @dtopt Option
  9724. * @name DataTable.defaults.lengthMenu
  9725. *
  9726. * @example
  9727. * $(document).ready( function() {
  9728. * $('#example').dataTable( {
  9729. * "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
  9730. * } );
  9731. * } );
  9732. */
  9733. "aLengthMenu": [ 10, 25, 50, 100 ],
  9734.  
  9735.  
  9736. /**
  9737. * The `columns` option in the initialisation parameter allows you to define
  9738. * details about the way individual columns behave. For a full list of
  9739. * column options that can be set, please see
  9740. * {@link DataTable.defaults.column}. Note that if you use `columns` to
  9741. * define your columns, you must have an entry in the array for every single
  9742. * column that you have in your table (these can be null if you don't which
  9743. * to specify any options).
  9744. * @member
  9745. *
  9746. * @name DataTable.defaults.column
  9747. */
  9748. "aoColumns": null,
  9749.  
  9750. /**
  9751. * Very similar to `columns`, `columnDefs` allows you to target a specific
  9752. * column, multiple columns, or all columns, using the `targets` property of
  9753. * each object in the array. This allows great flexibility when creating
  9754. * tables, as the `columnDefs` arrays can be of any length, targeting the
  9755. * columns you specifically want. `columnDefs` may use any of the column
  9756. * options available: {@link DataTable.defaults.column}, but it _must_
  9757. * have `targets` defined in each object in the array. Values in the `targets`
  9758. * array may be:
  9759. * <ul>
  9760. * <li>a string - class name will be matched on the TH for the column</li>
  9761. * <li>0 or a positive integer - column index counting from the left</li>
  9762. * <li>a negative integer - column index counting from the right</li>
  9763. * <li>the string "_all" - all columns (i.e. assign a default)</li>
  9764. * </ul>
  9765. * @member
  9766. *
  9767. * @name DataTable.defaults.columnDefs
  9768. */
  9769. "aoColumnDefs": null,
  9770.  
  9771.  
  9772. /**
  9773. * Basically the same as `search`, this parameter defines the individual column
  9774. * filtering state at initialisation time. The array must be of the same size
  9775. * as the number of columns, and each element be an object with the parameters
  9776. * `search` and `escapeRegex` (the latter is optional). 'null' is also
  9777. * accepted and the default will be used.
  9778. * @type array
  9779. * @default []
  9780. *
  9781. * @dtopt Option
  9782. * @name DataTable.defaults.searchCols
  9783. *
  9784. * @example
  9785. * $(document).ready( function() {
  9786. * $('#example').dataTable( {
  9787. * "searchCols": [
  9788. * null,
  9789. * { "search": "My filter" },
  9790. * null,
  9791. * { "search": "^[0-9]", "escapeRegex": false }
  9792. * ]
  9793. * } );
  9794. * } )
  9795. */
  9796. "aoSearchCols": [],
  9797.  
  9798.  
  9799. /**
  9800. * An array of CSS classes that should be applied to displayed rows. This
  9801. * array may be of any length, and DataTables will apply each class
  9802. * sequentially, looping when required.
  9803. * @type array
  9804. * @default null <i>Will take the values determined by the `oClasses.stripe*`
  9805. * options</i>
  9806. *
  9807. * @dtopt Option
  9808. * @name DataTable.defaults.stripeClasses
  9809. *
  9810. * @example
  9811. * $(document).ready( function() {
  9812. * $('#example').dataTable( {
  9813. * "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
  9814. * } );
  9815. * } )
  9816. */
  9817. "asStripeClasses": null,
  9818.  
  9819.  
  9820. /**
  9821. * Enable or disable automatic column width calculation. This can be disabled
  9822. * as an optimisation (it takes some time to calculate the widths) if the
  9823. * tables widths are passed in using `columns`.
  9824. * @type boolean
  9825. * @default true
  9826. *
  9827. * @dtopt Features
  9828. * @name DataTable.defaults.autoWidth
  9829. *
  9830. * @example
  9831. * $(document).ready( function () {
  9832. * $('#example').dataTable( {
  9833. * "autoWidth": false
  9834. * } );
  9835. * } );
  9836. */
  9837. "bAutoWidth": true,
  9838.  
  9839.  
  9840. /**
  9841. * Deferred rendering can provide DataTables with a huge speed boost when you
  9842. * are using an Ajax or JS data source for the table. This option, when set to
  9843. * true, will cause DataTables to defer the creation of the table elements for
  9844. * each row until they are needed for a draw - saving a significant amount of
  9845. * time.
  9846. * @type boolean
  9847. * @default false
  9848. *
  9849. * @dtopt Features
  9850. * @name DataTable.defaults.deferRender
  9851. *
  9852. * @example
  9853. * $(document).ready( function() {
  9854. * $('#example').dataTable( {
  9855. * "ajax": "sources/arrays.txt",
  9856. * "deferRender": true
  9857. * } );
  9858. * } );
  9859. */
  9860. "bDeferRender": false,
  9861.  
  9862.  
  9863. /**
  9864. * Replace a DataTable which matches the given selector and replace it with
  9865. * one which has the properties of the new initialisation object passed. If no
  9866. * table matches the selector, then the new DataTable will be constructed as
  9867. * per normal.
  9868. * @type boolean
  9869. * @default false
  9870. *
  9871. * @dtopt Options
  9872. * @name DataTable.defaults.destroy
  9873. *
  9874. * @example
  9875. * $(document).ready( function() {
  9876. * $('#example').dataTable( {
  9877. * "srollY": "200px",
  9878. * "paginate": false
  9879. * } );
  9880. *
  9881. * // Some time later....
  9882. * $('#example').dataTable( {
  9883. * "filter": false,
  9884. * "destroy": true
  9885. * } );
  9886. * } );
  9887. */
  9888. "bDestroy": false,
  9889.  
  9890.  
  9891. /**
  9892. * Enable or disable filtering of data. Filtering in DataTables is "smart" in
  9893. * that it allows the end user to input multiple words (space separated) and
  9894. * will match a row containing those words, even if not in the order that was
  9895. * specified (this allow matching across multiple columns). Note that if you
  9896. * wish to use filtering in DataTables this must remain 'true' - to remove the
  9897. * default filtering input box and retain filtering abilities, please use
  9898. * {@link DataTable.defaults.dom}.
  9899. * @type boolean
  9900. * @default true
  9901. *
  9902. * @dtopt Features
  9903. * @name DataTable.defaults.searching
  9904. *
  9905. * @example
  9906. * $(document).ready( function () {
  9907. * $('#example').dataTable( {
  9908. * "searching": false
  9909. * } );
  9910. * } );
  9911. */
  9912. "bFilter": true,
  9913.  
  9914.  
  9915. /**
  9916. * Enable or disable the table information display. This shows information
  9917. * about the data that is currently visible on the page, including information
  9918. * about filtered data if that action is being performed.
  9919. * @type boolean
  9920. * @default true
  9921. *
  9922. * @dtopt Features
  9923. * @name DataTable.defaults.info
  9924. *
  9925. * @example
  9926. * $(document).ready( function () {
  9927. * $('#example').dataTable( {
  9928. * "info": false
  9929. * } );
  9930. * } );
  9931. */
  9932. "bInfo": true,
  9933.  
  9934.  
  9935. /**
  9936. * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
  9937. * slightly different and additional mark-up from what DataTables has
  9938. * traditionally used).
  9939. * @type boolean
  9940. * @default false
  9941. *
  9942. * @dtopt Features
  9943. * @name DataTable.defaults.jQueryUI
  9944. *
  9945. * @example
  9946. * $(document).ready( function() {
  9947. * $('#example').dataTable( {
  9948. * "jQueryUI": true
  9949. * } );
  9950. * } );
  9951. */
  9952. "bJQueryUI": false,
  9953.  
  9954.  
  9955. /**
  9956. * Allows the end user to select the size of a formatted page from a select
  9957. * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
  9958. * @type boolean
  9959. * @default true
  9960. *
  9961. * @dtopt Features
  9962. * @name DataTable.defaults.lengthChange
  9963. *
  9964. * @example
  9965. * $(document).ready( function () {
  9966. * $('#example').dataTable( {
  9967. * "lengthChange": false
  9968. * } );
  9969. * } );
  9970. */
  9971. "bLengthChange": true,
  9972.  
  9973.  
  9974. /**
  9975. * Enable or disable pagination.
  9976. * @type boolean
  9977. * @default true
  9978. *
  9979. * @dtopt Features
  9980. * @name DataTable.defaults.paging
  9981. *
  9982. * @example
  9983. * $(document).ready( function () {
  9984. * $('#example').dataTable( {
  9985. * "paging": false
  9986. * } );
  9987. * } );
  9988. */
  9989. "bPaginate": true,
  9990.  
  9991.  
  9992. /**
  9993. * Enable or disable the display of a 'processing' indicator when the table is
  9994. * being processed (e.g. a sort). This is particularly useful for tables with
  9995. * large amounts of data where it can take a noticeable amount of time to sort
  9996. * the entries.
  9997. * @type boolean
  9998. * @default false
  9999. *
  10000. * @dtopt Features
  10001. * @name DataTable.defaults.processing
  10002. *
  10003. * @example
  10004. * $(document).ready( function () {
  10005. * $('#example').dataTable( {
  10006. * "processing": true
  10007. * } );
  10008. * } );
  10009. */
  10010. "bProcessing": false,
  10011.  
  10012.  
  10013. /**
  10014. * Retrieve the DataTables object for the given selector. Note that if the
  10015. * table has already been initialised, this parameter will cause DataTables
  10016. * to simply return the object that has already been set up - it will not take
  10017. * account of any changes you might have made to the initialisation object
  10018. * passed to DataTables (setting this parameter to true is an acknowledgement
  10019. * that you understand this). `destroy` can be used to reinitialise a table if
  10020. * you need.
  10021. * @type boolean
  10022. * @default false
  10023. *
  10024. * @dtopt Options
  10025. * @name DataTable.defaults.retrieve
  10026. *
  10027. * @example
  10028. * $(document).ready( function() {
  10029. * initTable();
  10030. * tableActions();
  10031. * } );
  10032. *
  10033. * function initTable ()
  10034. * {
  10035. * return $('#example').dataTable( {
  10036. * "scrollY": "200px",
  10037. * "paginate": false,
  10038. * "retrieve": true
  10039. * } );
  10040. * }
  10041. *
  10042. * function tableActions ()
  10043. * {
  10044. * var table = initTable();
  10045. * // perform API operations with oTable
  10046. * }
  10047. */
  10048. "bRetrieve": false,
  10049.  
  10050.  
  10051. /**
  10052. * When vertical (y) scrolling is enabled, DataTables will force the height of
  10053. * the table's viewport to the given height at all times (useful for layout).
  10054. * However, this can look odd when filtering data down to a small data set,
  10055. * and the footer is left "floating" further down. This parameter (when
  10056. * enabled) will cause DataTables to collapse the table's viewport down when
  10057. * the result set will fit within the given Y height.
  10058. * @type boolean
  10059. * @default false
  10060. *
  10061. * @dtopt Options
  10062. * @name DataTable.defaults.scrollCollapse
  10063. *
  10064. * @example
  10065. * $(document).ready( function() {
  10066. * $('#example').dataTable( {
  10067. * "scrollY": "200",
  10068. * "scrollCollapse": true
  10069. * } );
  10070. * } );
  10071. */
  10072. "bScrollCollapse": false,
  10073.  
  10074.  
  10075. /**
  10076. * Configure DataTables to use server-side processing. Note that the
  10077. * `ajax` parameter must also be given in order to give DataTables a
  10078. * source to obtain the required data for each draw.
  10079. * @type boolean
  10080. * @default false
  10081. *
  10082. * @dtopt Features
  10083. * @dtopt Server-side
  10084. * @name DataTable.defaults.serverSide
  10085. *
  10086. * @example
  10087. * $(document).ready( function () {
  10088. * $('#example').dataTable( {
  10089. * "serverSide": true,
  10090. * "ajax": "xhr.php"
  10091. * } );
  10092. * } );
  10093. */
  10094. "bServerSide": false,
  10095.  
  10096.  
  10097. /**
  10098. * Enable or disable sorting of columns. Sorting of individual columns can be
  10099. * disabled by the `sortable` option for each column.
  10100. * @type boolean
  10101. * @default true
  10102. *
  10103. * @dtopt Features
  10104. * @name DataTable.defaults.ordering
  10105. *
  10106. * @example
  10107. * $(document).ready( function () {
  10108. * $('#example').dataTable( {
  10109. * "ordering": false
  10110. * } );
  10111. * } );
  10112. */
  10113. "bSort": true,
  10114.  
  10115.  
  10116. /**
  10117. * Enable or display DataTables' ability to sort multiple columns at the
  10118. * same time (activated by shift-click by the user).
  10119. * @type boolean
  10120. * @default true
  10121. *
  10122. * @dtopt Options
  10123. * @name DataTable.defaults.orderMulti
  10124. *
  10125. * @example
  10126. * // Disable multiple column sorting ability
  10127. * $(document).ready( function () {
  10128. * $('#example').dataTable( {
  10129. * "orderMulti": false
  10130. * } );
  10131. * } );
  10132. */
  10133. "bSortMulti": true,
  10134.  
  10135.  
  10136. /**
  10137. * Allows control over whether DataTables should use the top (true) unique
  10138. * cell that is found for a single column, or the bottom (false - default).
  10139. * This is useful when using complex headers.
  10140. * @type boolean
  10141. * @default false
  10142. *
  10143. * @dtopt Options
  10144. * @name DataTable.defaults.orderCellsTop
  10145. *
  10146. * @example
  10147. * $(document).ready( function() {
  10148. * $('#example').dataTable( {
  10149. * "orderCellsTop": true
  10150. * } );
  10151. * } );
  10152. */
  10153. "bSortCellsTop": false,
  10154.  
  10155.  
  10156. /**
  10157. * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
  10158. * `sorting\_3` to the columns which are currently being sorted on. This is
  10159. * presented as a feature switch as it can increase processing time (while
  10160. * classes are removed and added) so for large data sets you might want to
  10161. * turn this off.
  10162. * @type boolean
  10163. * @default true
  10164. *
  10165. * @dtopt Features
  10166. * @name DataTable.defaults.orderClasses
  10167. *
  10168. * @example
  10169. * $(document).ready( function () {
  10170. * $('#example').dataTable( {
  10171. * "orderClasses": false
  10172. * } );
  10173. * } );
  10174. */
  10175. "bSortClasses": true,
  10176.  
  10177.  
  10178. /**
  10179. * Enable or disable state saving. When enabled HTML5 `localStorage` will be
  10180. * used to save table display information such as pagination information,
  10181. * display length, filtering and sorting. As such when the end user reloads
  10182. * the page the display display will match what thy had previously set up.
  10183. *
  10184. * Due to the use of `localStorage` the default state saving is not supported
  10185. * in IE6 or 7. If state saving is required in those browsers, use
  10186. * `stateSaveCallback` to provide a storage solution such as cookies.
  10187. * @type boolean
  10188. * @default false
  10189. *
  10190. * @dtopt Features
  10191. * @name DataTable.defaults.stateSave
  10192. *
  10193. * @example
  10194. * $(document).ready( function () {
  10195. * $('#example').dataTable( {
  10196. * "stateSave": true
  10197. * } );
  10198. * } );
  10199. */
  10200. "bStateSave": false,
  10201.  
  10202.  
  10203. /**
  10204. * This function is called when a TR element is created (and all TD child
  10205. * elements have been inserted), or registered if using a DOM source, allowing
  10206. * manipulation of the TR element (adding classes etc).
  10207. * @type function
  10208. * @param {node} row "TR" element for the current row
  10209. * @param {array} data Raw data array for this row
  10210. * @param {int} dataIndex The index of this row in the internal aoData array
  10211. *
  10212. * @dtopt Callbacks
  10213. * @name DataTable.defaults.createdRow
  10214. *
  10215. * @example
  10216. * $(document).ready( function() {
  10217. * $('#example').dataTable( {
  10218. * "createdRow": function( row, data, dataIndex ) {
  10219. * // Bold the grade for all 'A' grade browsers
  10220. * if ( data[4] == "A" )
  10221. * {
  10222. * $('td:eq(4)', row).html( '<b>A</b>' );
  10223. * }
  10224. * }
  10225. * } );
  10226. * } );
  10227. */
  10228. "fnCreatedRow": null,
  10229.  
  10230.  
  10231. /**
  10232. * This function is called on every 'draw' event, and allows you to
  10233. * dynamically modify any aspect you want about the created DOM.
  10234. * @type function
  10235. * @param {object} settings DataTables settings object
  10236. *
  10237. * @dtopt Callbacks
  10238. * @name DataTable.defaults.drawCallback
  10239. *
  10240. * @example
  10241. * $(document).ready( function() {
  10242. * $('#example').dataTable( {
  10243. * "drawCallback": function( settings ) {
  10244. * alert( 'DataTables has redrawn the table' );
  10245. * }
  10246. * } );
  10247. * } );
  10248. */
  10249. "fnDrawCallback": null,
  10250.  
  10251.  
  10252. /**
  10253. * Identical to fnHeaderCallback() but for the table footer this function
  10254. * allows you to modify the table footer on every 'draw' event.
  10255. * @type function
  10256. * @param {node} foot "TR" element for the footer
  10257. * @param {array} data Full table data (as derived from the original HTML)
  10258. * @param {int} start Index for the current display starting point in the
  10259. * display array
  10260. * @param {int} end Index for the current display ending point in the
  10261. * display array
  10262. * @param {array int} display Index array to translate the visual position
  10263. * to the full data array
  10264. *
  10265. * @dtopt Callbacks
  10266. * @name DataTable.defaults.footerCallback
  10267. *
  10268. * @example
  10269. * $(document).ready( function() {
  10270. * $('#example').dataTable( {
  10271. * "footerCallback": function( tfoot, data, start, end, display ) {
  10272. * tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
  10273. * }
  10274. * } );
  10275. * } )
  10276. */
  10277. "fnFooterCallback": null,
  10278.  
  10279.  
  10280. /**
  10281. * When rendering large numbers in the information element for the table
  10282. * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
  10283. * to have a comma separator for the 'thousands' units (e.g. 1 million is
  10284. * rendered as "1,000,000") to help readability for the end user. This
  10285. * function will override the default method DataTables uses.
  10286. * @type function
  10287. * @member
  10288. * @param {int} toFormat number to be formatted
  10289. * @returns {string} formatted string for DataTables to show the number
  10290. *
  10291. * @dtopt Callbacks
  10292. * @name DataTable.defaults.formatNumber
  10293. *
  10294. * @example
  10295. * // Format a number using a single quote for the separator (note that
  10296. * // this can also be done with the language.thousands option)
  10297. * $(document).ready( function() {
  10298. * $('#example').dataTable( {
  10299. * "formatNumber": function ( toFormat ) {
  10300. * return toFormat.toString().replace(
  10301. * /\B(?=(\d{3})+(?!\d))/g, "'"
  10302. * );
  10303. * };
  10304. * } );
  10305. * } );
  10306. */
  10307. "fnFormatNumber": function ( toFormat ) {
  10308. return toFormat.toString().replace(
  10309. /\B(?=(\d{3})+(?!\d))/g,
  10310. this.oLanguage.sThousands
  10311. );
  10312. },
  10313.  
  10314.  
  10315. /**
  10316. * This function is called on every 'draw' event, and allows you to
  10317. * dynamically modify the header row. This can be used to calculate and
  10318. * display useful information about the table.
  10319. * @type function
  10320. * @param {node} head "TR" element for the header
  10321. * @param {array} data Full table data (as derived from the original HTML)
  10322. * @param {int} start Index for the current display starting point in the
  10323. * display array
  10324. * @param {int} end Index for the current display ending point in the
  10325. * display array
  10326. * @param {array int} display Index array to translate the visual position
  10327. * to the full data array
  10328. *
  10329. * @dtopt Callbacks
  10330. * @name DataTable.defaults.headerCallback
  10331. *
  10332. * @example
  10333. * $(document).ready( function() {
  10334. * $('#example').dataTable( {
  10335. * "fheaderCallback": function( head, data, start, end, display ) {
  10336. * head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
  10337. * }
  10338. * } );
  10339. * } )
  10340. */
  10341. "fnHeaderCallback": null,
  10342.  
  10343.  
  10344. /**
  10345. * The information element can be used to convey information about the current
  10346. * state of the table. Although the internationalisation options presented by
  10347. * DataTables are quite capable of dealing with most customisations, there may
  10348. * be times where you wish to customise the string further. This callback
  10349. * allows you to do exactly that.
  10350. * @type function
  10351. * @param {object} oSettings DataTables settings object
  10352. * @param {int} start Starting position in data for the draw
  10353. * @param {int} end End position in data for the draw
  10354. * @param {int} max Total number of rows in the table (regardless of
  10355. * filtering)
  10356. * @param {int} total Total number of rows in the data set, after filtering
  10357. * @param {string} pre The string that DataTables has formatted using it's
  10358. * own rules
  10359. * @returns {string} The string to be displayed in the information element.
  10360. *
  10361. * @dtopt Callbacks
  10362. * @name DataTable.defaults.infoCallback
  10363. *
  10364. * @example
  10365. * $('#example').dataTable( {
  10366. * "infoCallback": function( settings, start, end, max, total, pre ) {
  10367. * return start +" to "+ end;
  10368. * }
  10369. * } );
  10370. */
  10371. "fnInfoCallback": null,
  10372.  
  10373.  
  10374. /**
  10375. * Called when the table has been initialised. Normally DataTables will
  10376. * initialise sequentially and there will be no need for this function,
  10377. * however, this does not hold true when using external language information
  10378. * since that is obtained using an async XHR call.
  10379. * @type function
  10380. * @param {object} settings DataTables settings object
  10381. * @param {object} json The JSON object request from the server - only
  10382. * present if client-side Ajax sourced data is used
  10383. *
  10384. * @dtopt Callbacks
  10385. * @name DataTable.defaults.initComplete
  10386. *
  10387. * @example
  10388. * $(document).ready( function() {
  10389. * $('#example').dataTable( {
  10390. * "initComplete": function(settings, json) {
  10391. * alert( 'DataTables has finished its initialisation.' );
  10392. * }
  10393. * } );
  10394. * } )
  10395. */
  10396. "fnInitComplete": null,
  10397.  
  10398.  
  10399. /**
  10400. * Called at the very start of each table draw and can be used to cancel the
  10401. * draw by returning false, any other return (including undefined) results in
  10402. * the full draw occurring).
  10403. * @type function
  10404. * @param {object} settings DataTables settings object
  10405. * @returns {boolean} False will cancel the draw, anything else (including no
  10406. * return) will allow it to complete.
  10407. *
  10408. * @dtopt Callbacks
  10409. * @name DataTable.defaults.preDrawCallback
  10410. *
  10411. * @example
  10412. * $(document).ready( function() {
  10413. * $('#example').dataTable( {
  10414. * "preDrawCallback": function( settings ) {
  10415. * if ( $('#test').val() == 1 ) {
  10416. * return false;
  10417. * }
  10418. * }
  10419. * } );
  10420. * } );
  10421. */
  10422. "fnPreDrawCallback": null,
  10423.  
  10424.  
  10425. /**
  10426. * This function allows you to 'post process' each row after it have been
  10427. * generated for each table draw, but before it is rendered on screen. This
  10428. * function might be used for setting the row class name etc.
  10429. * @type function
  10430. * @param {node} row "TR" element for the current row
  10431. * @param {array} data Raw data array for this row
  10432. * @param {int} displayIndex The display index for the current table draw
  10433. * @param {int} displayIndexFull The index of the data in the full list of
  10434. * rows (after filtering)
  10435. *
  10436. * @dtopt Callbacks
  10437. * @name DataTable.defaults.rowCallback
  10438. *
  10439. * @example
  10440. * $(document).ready( function() {
  10441. * $('#example').dataTable( {
  10442. * "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
  10443. * // Bold the grade for all 'A' grade browsers
  10444. * if ( data[4] == "A" ) {
  10445. * $('td:eq(4)', row).html( '<b>A</b>' );
  10446. * }
  10447. * }
  10448. * } );
  10449. * } );
  10450. */
  10451. "fnRowCallback": null,
  10452.  
  10453.  
  10454. /**
  10455. * __Deprecated__ The functionality provided by this parameter has now been
  10456. * superseded by that provided through `ajax`, which should be used instead.
  10457. *
  10458. * This parameter allows you to override the default function which obtains
  10459. * the data from the server so something more suitable for your application.
  10460. * For example you could use POST data, or pull information from a Gears or
  10461. * AIR database.
  10462. * @type function
  10463. * @member
  10464. * @param {string} source HTTP source to obtain the data from (`ajax`)
  10465. * @param {array} data A key/value pair object containing the data to send
  10466. * to the server
  10467. * @param {function} callback to be called on completion of the data get
  10468. * process that will draw the data on the page.
  10469. * @param {object} settings DataTables settings object
  10470. *
  10471. * @dtopt Callbacks
  10472. * @dtopt Server-side
  10473. * @name DataTable.defaults.serverData
  10474. *
  10475. * @deprecated 1.10. Please use `ajax` for this functionality now.
  10476. */
  10477. "fnServerData": null,
  10478.  
  10479.  
  10480. /**
  10481. * __Deprecated__ The functionality provided by this parameter has now been
  10482. * superseded by that provided through `ajax`, which should be used instead.
  10483. *
  10484. * It is often useful to send extra data to the server when making an Ajax
  10485. * request - for example custom filtering information, and this callback
  10486. * function makes it trivial to send extra information to the server. The
  10487. * passed in parameter is the data set that has been constructed by
  10488. * DataTables, and you can add to this or modify it as you require.
  10489. * @type function
  10490. * @param {array} data Data array (array of objects which are name/value
  10491. * pairs) that has been constructed by DataTables and will be sent to the
  10492. * server. In the case of Ajax sourced data with server-side processing
  10493. * this will be an empty array, for server-side processing there will be a
  10494. * significant number of parameters!
  10495. * @returns {undefined} Ensure that you modify the data array passed in,
  10496. * as this is passed by reference.
  10497. *
  10498. * @dtopt Callbacks
  10499. * @dtopt Server-side
  10500. * @name DataTable.defaults.serverParams
  10501. *
  10502. * @deprecated 1.10. Please use `ajax` for this functionality now.
  10503. */
  10504. "fnServerParams": null,
  10505.  
  10506.  
  10507. /**
  10508. * Load the table state. With this function you can define from where, and how, the
  10509. * state of a table is loaded. By default DataTables will load from `localStorage`
  10510. * but you might wish to use a server-side database or cookies.
  10511. * @type function
  10512. * @member
  10513. * @param {object} settings DataTables settings object
  10514. * @return {object} The DataTables state object to be loaded
  10515. *
  10516. * @dtopt Callbacks
  10517. * @name DataTable.defaults.stateLoadCallback
  10518. *
  10519. * @example
  10520. * $(document).ready( function() {
  10521. * $('#example').dataTable( {
  10522. * "stateSave": true,
  10523. * "stateLoadCallback": function (settings) {
  10524. * var o;
  10525. *
  10526. * // Send an Ajax request to the server to get the data. Note that
  10527. * // this is a synchronous request.
  10528. * $.ajax( {
  10529. * "url": "/state_load",
  10530. * "async": false,
  10531. * "dataType": "json",
  10532. * "success": function (json) {
  10533. * o = json;
  10534. * }
  10535. * } );
  10536. *
  10537. * return o;
  10538. * }
  10539. * } );
  10540. * } );
  10541. */
  10542. "fnStateLoadCallback": function ( settings ) {
  10543. try {
  10544. return JSON.parse(
  10545. (settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
  10546. 'DataTables_'+settings.sInstance+'_'+location.pathname
  10547. )
  10548. );
  10549. } catch (e) {}
  10550. },
  10551.  
  10552.  
  10553. /**
  10554. * Callback which allows modification of the saved state prior to loading that state.
  10555. * This callback is called when the table is loading state from the stored data, but
  10556. * prior to the settings object being modified by the saved state. Note that for
  10557. * plug-in authors, you should use the `stateLoadParams` event to load parameters for
  10558. * a plug-in.
  10559. * @type function
  10560. * @param {object} settings DataTables settings object
  10561. * @param {object} data The state object that is to be loaded
  10562. *
  10563. * @dtopt Callbacks
  10564. * @name DataTable.defaults.stateLoadParams
  10565. *
  10566. * @example
  10567. * // Remove a saved filter, so filtering is never loaded
  10568. * $(document).ready( function() {
  10569. * $('#example').dataTable( {
  10570. * "stateSave": true,
  10571. * "stateLoadParams": function (settings, data) {
  10572. * data.oSearch.sSearch = "";
  10573. * }
  10574. * } );
  10575. * } );
  10576. *
  10577. * @example
  10578. * // Disallow state loading by returning false
  10579. * $(document).ready( function() {
  10580. * $('#example').dataTable( {
  10581. * "stateSave": true,
  10582. * "stateLoadParams": function (settings, data) {
  10583. * return false;
  10584. * }
  10585. * } );
  10586. * } );
  10587. */
  10588. "fnStateLoadParams": null,
  10589.  
  10590.  
  10591. /**
  10592. * Callback that is called when the state has been loaded from the state saving method
  10593. * and the DataTables settings object has been modified as a result of the loaded state.
  10594. * @type function
  10595. * @param {object} settings DataTables settings object
  10596. * @param {object} data The state object that was loaded
  10597. *
  10598. * @dtopt Callbacks
  10599. * @name DataTable.defaults.stateLoaded
  10600. *
  10601. * @example
  10602. * // Show an alert with the filtering value that was saved
  10603. * $(document).ready( function() {
  10604. * $('#example').dataTable( {
  10605. * "stateSave": true,
  10606. * "stateLoaded": function (settings, data) {
  10607. * alert( 'Saved filter was: '+data.oSearch.sSearch );
  10608. * }
  10609. * } );
  10610. * } );
  10611. */
  10612. "fnStateLoaded": null,
  10613.  
  10614.  
  10615. /**
  10616. * Save the table state. This function allows you to define where and how the state
  10617. * information for the table is stored By default DataTables will use `localStorage`
  10618. * but you might wish to use a server-side database or cookies.
  10619. * @type function
  10620. * @member
  10621. * @param {object} settings DataTables settings object
  10622. * @param {object} data The state object to be saved
  10623. *
  10624. * @dtopt Callbacks
  10625. * @name DataTable.defaults.stateSaveCallback
  10626. *
  10627. * @example
  10628. * $(document).ready( function() {
  10629. * $('#example').dataTable( {
  10630. * "stateSave": true,
  10631. * "stateSaveCallback": function (settings, data) {
  10632. * // Send an Ajax request to the server with the state object
  10633. * $.ajax( {
  10634. * "url": "/state_save",
  10635. * "data": data,
  10636. * "dataType": "json",
  10637. * "method": "POST"
  10638. * "success": function () {}
  10639. * } );
  10640. * }
  10641. * } );
  10642. * } );
  10643. */
  10644. "fnStateSaveCallback": function ( settings, data ) {
  10645. try {
  10646. (settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
  10647. 'DataTables_'+settings.sInstance+'_'+location.pathname,
  10648. JSON.stringify( data )
  10649. );
  10650. } catch (e) {}
  10651. },
  10652.  
  10653.  
  10654. /**
  10655. * Callback which allows modification of the state to be saved. Called when the table
  10656. * has changed state a new state save is required. This method allows modification of
  10657. * the state saving object prior to actually doing the save, including addition or
  10658. * other state properties or modification. Note that for plug-in authors, you should
  10659. * use the `stateSaveParams` event to save parameters for a plug-in.
  10660. * @type function
  10661. * @param {object} settings DataTables settings object
  10662. * @param {object} data The state object to be saved
  10663. *
  10664. * @dtopt Callbacks
  10665. * @name DataTable.defaults.stateSaveParams
  10666. *
  10667. * @example
  10668. * // Remove a saved filter, so filtering is never saved
  10669. * $(document).ready( function() {
  10670. * $('#example').dataTable( {
  10671. * "stateSave": true,
  10672. * "stateSaveParams": function (settings, data) {
  10673. * data.oSearch.sSearch = "";
  10674. * }
  10675. * } );
  10676. * } );
  10677. */
  10678. "fnStateSaveParams": null,
  10679.  
  10680.  
  10681. /**
  10682. * Duration for which the saved state information is considered valid. After this period
  10683. * has elapsed the state will be returned to the default.
  10684. * Value is given in seconds.
  10685. * @type int
  10686. * @default 7200 <i>(2 hours)</i>
  10687. *
  10688. * @dtopt Options
  10689. * @name DataTable.defaults.stateDuration
  10690. *
  10691. * @example
  10692. * $(document).ready( function() {
  10693. * $('#example').dataTable( {
  10694. * "stateDuration": 60*60*24; // 1 day
  10695. * } );
  10696. * } )
  10697. */
  10698. "iStateDuration": 7200,
  10699.  
  10700.  
  10701. /**
  10702. * When enabled DataTables will not make a request to the server for the first
  10703. * page draw - rather it will use the data already on the page (no sorting etc
  10704. * will be applied to it), thus saving on an XHR at load time. `deferLoading`
  10705. * is used to indicate that deferred loading is required, but it is also used
  10706. * to tell DataTables how many records there are in the full table (allowing
  10707. * the information element and pagination to be displayed correctly). In the case
  10708. * where a filtering is applied to the table on initial load, this can be
  10709. * indicated by giving the parameter as an array, where the first element is
  10710. * the number of records available after filtering and the second element is the
  10711. * number of records without filtering (allowing the table information element
  10712. * to be shown correctly).
  10713. * @type int | array
  10714. * @default null
  10715. *
  10716. * @dtopt Options
  10717. * @name DataTable.defaults.deferLoading
  10718. *
  10719. * @example
  10720. * // 57 records available in the table, no filtering applied
  10721. * $(document).ready( function() {
  10722. * $('#example').dataTable( {
  10723. * "serverSide": true,
  10724. * "ajax": "scripts/server_processing.php",
  10725. * "deferLoading": 57
  10726. * } );
  10727. * } );
  10728. *
  10729. * @example
  10730. * // 57 records after filtering, 100 without filtering (an initial filter applied)
  10731. * $(document).ready( function() {
  10732. * $('#example').dataTable( {
  10733. * "serverSide": true,
  10734. * "ajax": "scripts/server_processing.php",
  10735. * "deferLoading": [ 57, 100 ],
  10736. * "search": {
  10737. * "search": "my_filter"
  10738. * }
  10739. * } );
  10740. * } );
  10741. */
  10742. "iDeferLoading": null,
  10743.  
  10744.  
  10745. /**
  10746. * Number of rows to display on a single page when using pagination. If
  10747. * feature enabled (`lengthChange`) then the end user will be able to override
  10748. * this to a custom setting using a pop-up menu.
  10749. * @type int
  10750. * @default 10
  10751. *
  10752. * @dtopt Options
  10753. * @name DataTable.defaults.pageLength
  10754. *
  10755. * @example
  10756. * $(document).ready( function() {
  10757. * $('#example').dataTable( {
  10758. * "pageLength": 50
  10759. * } );
  10760. * } )
  10761. */
  10762. "iDisplayLength": 10,
  10763.  
  10764.  
  10765. /**
  10766. * Define the starting point for data display when using DataTables with
  10767. * pagination. Note that this parameter is the number of records, rather than
  10768. * the page number, so if you have 10 records per page and want to start on
  10769. * the third page, it should be "20".
  10770. * @type int
  10771. * @default 0
  10772. *
  10773. * @dtopt Options
  10774. * @name DataTable.defaults.displayStart
  10775. *
  10776. * @example
  10777. * $(document).ready( function() {
  10778. * $('#example').dataTable( {
  10779. * "displayStart": 20
  10780. * } );
  10781. * } )
  10782. */
  10783. "iDisplayStart": 0,
  10784.  
  10785.  
  10786. /**
  10787. * By default DataTables allows keyboard navigation of the table (sorting, paging,
  10788. * and filtering) by adding a `tabindex` attribute to the required elements. This
  10789. * allows you to tab through the controls and press the enter key to activate them.
  10790. * The tabindex is default 0, meaning that the tab follows the flow of the document.
  10791. * You can overrule this using this parameter if you wish. Use a value of -1 to
  10792. * disable built-in keyboard navigation.
  10793. * @type int
  10794. * @default 0
  10795. *
  10796. * @dtopt Options
  10797. * @name DataTable.defaults.tabIndex
  10798. *
  10799. * @example
  10800. * $(document).ready( function() {
  10801. * $('#example').dataTable( {
  10802. * "tabIndex": 1
  10803. * } );
  10804. * } );
  10805. */
  10806. "iTabIndex": 0,
  10807.  
  10808.  
  10809. /**
  10810. * Classes that DataTables assigns to the various components and features
  10811. * that it adds to the HTML table. This allows classes to be configured
  10812. * during initialisation in addition to through the static
  10813. * {@link DataTable.ext.oStdClasses} object).
  10814. * @namespace
  10815. * @name DataTable.defaults.classes
  10816. */
  10817. "oClasses": {},
  10818.  
  10819.  
  10820. /**
  10821. * All strings that DataTables uses in the user interface that it creates
  10822. * are defined in this object, allowing you to modified them individually or
  10823. * completely replace them all as required.
  10824. * @namespace
  10825. * @name DataTable.defaults.language
  10826. */
  10827. "oLanguage": {
  10828. /**
  10829. * Strings that are used for WAI-ARIA labels and controls only (these are not
  10830. * actually visible on the page, but will be read by screenreaders, and thus
  10831. * must be internationalised as well).
  10832. * @namespace
  10833. * @name DataTable.defaults.language.aria
  10834. */
  10835. "oAria": {
  10836. /**
  10837. * ARIA label that is added to the table headers when the column may be
  10838. * sorted ascending by activing the column (click or return when focused).
  10839. * Note that the column header is prefixed to this string.
  10840. * @type string
  10841. * @default : activate to sort column ascending
  10842. *
  10843. * @dtopt Language
  10844. * @name DataTable.defaults.language.aria.sortAscending
  10845. *
  10846. * @example
  10847. * $(document).ready( function() {
  10848. * $('#example').dataTable( {
  10849. * "language": {
  10850. * "aria": {
  10851. * "sortAscending": " - click/return to sort ascending"
  10852. * }
  10853. * }
  10854. * } );
  10855. * } );
  10856. */
  10857. "sSortAscending": ": activate to sort column ascending",
  10858.  
  10859. /**
  10860. * ARIA label that is added to the table headers when the column may be
  10861. * sorted descending by activing the column (click or return when focused).
  10862. * Note that the column header is prefixed to this string.
  10863. * @type string
  10864. * @default : activate to sort column ascending
  10865. *
  10866. * @dtopt Language
  10867. * @name DataTable.defaults.language.aria.sortDescending
  10868. *
  10869. * @example
  10870. * $(document).ready( function() {
  10871. * $('#example').dataTable( {
  10872. * "language": {
  10873. * "aria": {
  10874. * "sortDescending": " - click/return to sort descending"
  10875. * }
  10876. * }
  10877. * } );
  10878. * } );
  10879. */
  10880. "sSortDescending": ": activate to sort column descending"
  10881. },
  10882.  
  10883. /**
  10884. * Pagination string used by DataTables for the built-in pagination
  10885. * control types.
  10886. * @namespace
  10887. * @name DataTable.defaults.language.paginate
  10888. */
  10889. "oPaginate": {
  10890. /**
  10891. * Text to use when using the 'full_numbers' type of pagination for the
  10892. * button to take the user to the first page.
  10893. * @type string
  10894. * @default First
  10895. *
  10896. * @dtopt Language
  10897. * @name DataTable.defaults.language.paginate.first
  10898. *
  10899. * @example
  10900. * $(document).ready( function() {
  10901. * $('#example').dataTable( {
  10902. * "language": {
  10903. * "paginate": {
  10904. * "first": "First page"
  10905. * }
  10906. * }
  10907. * } );
  10908. * } );
  10909. */
  10910. "sFirst": "First",
  10911.  
  10912.  
  10913. /**
  10914. * Text to use when using the 'full_numbers' type of pagination for the
  10915. * button to take the user to the last page.
  10916. * @type string
  10917. * @default Last
  10918. *
  10919. * @dtopt Language
  10920. * @name DataTable.defaults.language.paginate.last
  10921. *
  10922. * @example
  10923. * $(document).ready( function() {
  10924. * $('#example').dataTable( {
  10925. * "language": {
  10926. * "paginate": {
  10927. * "last": "Last page"
  10928. * }
  10929. * }
  10930. * } );
  10931. * } );
  10932. */
  10933. "sLast": "Last",
  10934.  
  10935.  
  10936. /**
  10937. * Text to use for the 'next' pagination button (to take the user to the
  10938. * next page).
  10939. * @type string
  10940. * @default Next
  10941. *
  10942. * @dtopt Language
  10943. * @name DataTable.defaults.language.paginate.next
  10944. *
  10945. * @example
  10946. * $(document).ready( function() {
  10947. * $('#example').dataTable( {
  10948. * "language": {
  10949. * "paginate": {
  10950. * "next": "Next page"
  10951. * }
  10952. * }
  10953. * } );
  10954. * } );
  10955. */
  10956. "sNext": "Next",
  10957.  
  10958.  
  10959. /**
  10960. * Text to use for the 'previous' pagination button (to take the user to
  10961. * the previous page).
  10962. * @type string
  10963. * @default Previous
  10964. *
  10965. * @dtopt Language
  10966. * @name DataTable.defaults.language.paginate.previous
  10967. *
  10968. * @example
  10969. * $(document).ready( function() {
  10970. * $('#example').dataTable( {
  10971. * "language": {
  10972. * "paginate": {
  10973. * "previous": "Previous page"
  10974. * }
  10975. * }
  10976. * } );
  10977. * } );
  10978. */
  10979. "sPrevious": "Previous"
  10980. },
  10981.  
  10982. /**
  10983. * This string is shown in preference to `zeroRecords` when the table is
  10984. * empty of data (regardless of filtering). Note that this is an optional
  10985. * parameter - if it is not given, the value of `zeroRecords` will be used
  10986. * instead (either the default or given value).
  10987. * @type string
  10988. * @default No data available in table
  10989. *
  10990. * @dtopt Language
  10991. * @name DataTable.defaults.language.emptyTable
  10992. *
  10993. * @example
  10994. * $(document).ready( function() {
  10995. * $('#example').dataTable( {
  10996. * "language": {
  10997. * "emptyTable": "No data available in table"
  10998. * }
  10999. * } );
  11000. * } );
  11001. */
  11002. "sEmptyTable": "No data available in table",
  11003.  
  11004.  
  11005. /**
  11006. * This string gives information to the end user about the information
  11007. * that is current on display on the page. The following tokens can be
  11008. * used in the string and will be dynamically replaced as the table
  11009. * display updates. This tokens can be placed anywhere in the string, or
  11010. * removed as needed by the language requires:
  11011. *
  11012. * * `\_START\_` - Display index of the first record on the current page
  11013. * * `\_END\_` - Display index of the last record on the current page
  11014. * * `\_TOTAL\_` - Number of records in the table after filtering
  11015. * * `\_MAX\_` - Number of records in the table without filtering
  11016. * * `\_PAGE\_` - Current page number
  11017. * * `\_PAGES\_` - Total number of pages of data in the table
  11018. *
  11019. * @type string
  11020. * @default Showing _START_ to _END_ of _TOTAL_ entries
  11021. *
  11022. * @dtopt Language
  11023. * @name DataTable.defaults.language.info
  11024. *
  11025. * @example
  11026. * $(document).ready( function() {
  11027. * $('#example').dataTable( {
  11028. * "language": {
  11029. * "info": "Showing page _PAGE_ of _PAGES_"
  11030. * }
  11031. * } );
  11032. * } );
  11033. */
  11034. "sInfo": "Ostatnia aktualizacja:",
  11035.  
  11036.  
  11037. /**
  11038. * Display information string for when the table is empty. Typically the
  11039. * format of this string should match `info`.
  11040. * @type string
  11041. * @default Showing 0 to 0 of 0 entries
  11042. *
  11043. * @dtopt Language
  11044. * @name DataTable.defaults.language.infoEmpty
  11045. *
  11046. * @example
  11047. * $(document).ready( function() {
  11048. * $('#example').dataTable( {
  11049. * "language": {
  11050. * "infoEmpty": "No entries to show"
  11051. * }
  11052. * } );
  11053. * } );
  11054. */
  11055. "sInfoEmpty": "Showing 0 to 0 of 0 entries",
  11056.  
  11057.  
  11058. /**
  11059. * When a user filters the information in a table, this string is appended
  11060. * to the information (`info`) to give an idea of how strong the filtering
  11061. * is. The variable _MAX_ is dynamically updated.
  11062. * @type string
  11063. * @default (filtered from _MAX_ total entries)
  11064. *
  11065. * @dtopt Language
  11066. * @name DataTable.defaults.language.infoFiltered
  11067. *
  11068. * @example
  11069. * $(document).ready( function() {
  11070. * $('#example').dataTable( {
  11071. * "language": {
  11072. * "infoFiltered": " - filtering from _MAX_ records"
  11073. * }
  11074. * } );
  11075. * } );
  11076. */
  11077. "sInfoFiltered": "(filtered from _MAX_ total entries)",
  11078.  
  11079.  
  11080. /**
  11081. * If can be useful to append extra information to the info string at times,
  11082. * and this variable does exactly that. This information will be appended to
  11083. * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
  11084. * being used) at all times.
  11085. * @type string
  11086. * @default <i>Empty string</i>
  11087. *
  11088. * @dtopt Language
  11089. * @name DataTable.defaults.language.infoPostFix
  11090. *
  11091. * @example
  11092. * $(document).ready( function() {
  11093. * $('#example').dataTable( {
  11094. * "language": {
  11095. * "infoPostFix": "All records shown are derived from real information."
  11096. * }
  11097. * } );
  11098. * } );
  11099. */
  11100. "sInfoPostFix": "",
  11101.  
  11102.  
  11103. /**
  11104. * This decimal place operator is a little different from the other
  11105. * language options since DataTables doesn't output floating point
  11106. * numbers, so it won't ever use this for display of a number. Rather,
  11107. * what this parameter does is modify the sort methods of the table so
  11108. * that numbers which are in a format which has a character other than
  11109. * a period (`.`) as a decimal place will be sorted numerically.
  11110. *
  11111. * Note that numbers with different decimal places cannot be shown in
  11112. * the same table and still be sortable, the table must be consistent.
  11113. * However, multiple different tables on the page can use different
  11114. * decimal place characters.
  11115. * @type string
  11116. * @default
  11117. *
  11118. * @dtopt Language
  11119. * @name DataTable.defaults.language.decimal
  11120. *
  11121. * @example
  11122. * $(document).ready( function() {
  11123. * $('#example').dataTable( {
  11124. * "language": {
  11125. * "decimal": ","
  11126. * "thousands": "."
  11127. * }
  11128. * } );
  11129. * } );
  11130. */
  11131. "sDecimal": "",
  11132.  
  11133.  
  11134. /**
  11135. * DataTables has a build in number formatter (`formatNumber`) which is
  11136. * used to format large numbers that are used in the table information.
  11137. * By default a comma is used, but this can be trivially changed to any
  11138. * character you wish with this parameter.
  11139. * @type string
  11140. * @default ,
  11141. *
  11142. * @dtopt Language
  11143. * @name DataTable.defaults.language.thousands
  11144. *
  11145. * @example
  11146. * $(document).ready( function() {
  11147. * $('#example').dataTable( {
  11148. * "language": {
  11149. * "thousands": "'"
  11150. * }
  11151. * } );
  11152. * } );
  11153. */
  11154. "sThousands": ",",
  11155.  
  11156.  
  11157. /**
  11158. * Detail the action that will be taken when the drop down menu for the
  11159. * pagination length option is changed. The '_MENU_' variable is replaced
  11160. * with a default select list of 10, 25, 50 and 100, and can be replaced
  11161. * with a custom select box if required.
  11162. * @type string
  11163. * @default Show _MENU_ entries
  11164. *
  11165. * @dtopt Language
  11166. * @name DataTable.defaults.language.lengthMenu
  11167. *
  11168. * @example
  11169. * // Language change only
  11170. * $(document).ready( function() {
  11171. * $('#example').dataTable( {
  11172. * "language": {
  11173. * "lengthMenu": "Display _MENU_ records"
  11174. * }
  11175. * } );
  11176. * } );
  11177. *
  11178. * @example
  11179. * // Language and options change
  11180. * $(document).ready( function() {
  11181. * $('#example').dataTable( {
  11182. * "language": {
  11183. * "lengthMenu": 'Display <select>'+
  11184. * '<option value="10">10</option>'+
  11185. * '<option value="20">20</option>'+
  11186. * '<option value="30">30</option>'+
  11187. * '<option value="40">40</option>'+
  11188. * '<option value="50">50</option>'+
  11189. * '<option value="-1">All</option>'+
  11190. * '</select> records'
  11191. * }
  11192. * } );
  11193. * } );
  11194. */
  11195. "sLengthMenu": "Show _MENU_ entries",
  11196.  
  11197.  
  11198. /**
  11199. * When using Ajax sourced data and during the first draw when DataTables is
  11200. * gathering the data, this message is shown in an empty row in the table to
  11201. * indicate to the end user the the data is being loaded. Note that this
  11202. * parameter is not used when loading data by server-side processing, just
  11203. * Ajax sourced data with client-side processing.
  11204. * @type string
  11205. * @default Loading...
  11206. *
  11207. * @dtopt Language
  11208. * @name DataTable.defaults.language.loadingRecords
  11209. *
  11210. * @example
  11211. * $(document).ready( function() {
  11212. * $('#example').dataTable( {
  11213. * "language": {
  11214. * "loadingRecords": "Please wait - loading..."
  11215. * }
  11216. * } );
  11217. * } );
  11218. */
  11219. "sLoadingRecords": "Loading...",
  11220.  
  11221.  
  11222. /**
  11223. * Text which is displayed when the table is processing a user action
  11224. * (usually a sort command or similar).
  11225. * @type string
  11226. * @default Processing...
  11227. *
  11228. * @dtopt Language
  11229. * @name DataTable.defaults.language.processing
  11230. *
  11231. * @example
  11232. * $(document).ready( function() {
  11233. * $('#example').dataTable( {
  11234. * "language": {
  11235. * "processing": "DataTables is currently busy"
  11236. * }
  11237. * } );
  11238. * } );
  11239. */
  11240. "sProcessing": "Processing...",
  11241.  
  11242.  
  11243. /**
  11244. * Details the actions that will be taken when the user types into the
  11245. * filtering input text box. The variable "_INPUT_", if used in the string,
  11246. * is replaced with the HTML text box for the filtering input allowing
  11247. * control over where it appears in the string. If "_INPUT_" is not given
  11248. * then the input box is appended to the string automatically.
  11249. * @type string
  11250. * @default Search:
  11251. *
  11252. * @dtopt Language
  11253. * @name DataTable.defaults.language.search
  11254. *
  11255. * @example
  11256. * // Input text box will be appended at the end automatically
  11257. * $(document).ready( function() {
  11258. * $('#example').dataTable( {
  11259. * "language": {
  11260. * "search": "Filter records:"
  11261. * }
  11262. * } );
  11263. * } );
  11264. *
  11265. * @example
  11266. * // Specify where the filter should appear
  11267. * $(document).ready( function() {
  11268. * $('#example').dataTable( {
  11269. * "language": {
  11270. * "search": "Apply filter _INPUT_ to table"
  11271. * }
  11272. * } );
  11273. * } );
  11274. */
  11275. "sSearch": "",
  11276.  
  11277.  
  11278. /**
  11279. * Assign a `placeholder` attribute to the search `input` element
  11280. * @type string
  11281. * @default
  11282. *
  11283. * @dtopt Language
  11284. * @name DataTable.defaults.language.searchPlaceholder
  11285. */
  11286. "sSearchPlaceholder": "",
  11287.  
  11288.  
  11289. /**
  11290. * All of the language information can be stored in a file on the
  11291. * server-side, which DataTables will look up if this parameter is passed.
  11292. * It must store the URL of the language file, which is in a JSON format,
  11293. * and the object has the same properties as the oLanguage object in the
  11294. * initialiser object (i.e. the above parameters). Please refer to one of
  11295. * the example language files to see how this works in action.
  11296. * @type string
  11297. * @default <i>Empty string - i.e. disabled</i>
  11298. *
  11299. * @dtopt Language
  11300. * @name DataTable.defaults.language.url
  11301. *
  11302. * @example
  11303. * $(document).ready( function() {
  11304. * $('#example').dataTable( {
  11305. * "language": {
  11306. * "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
  11307. * }
  11308. * } );
  11309. * } );
  11310. */
  11311. "sUrl": "",
  11312.  
  11313.  
  11314. /**
  11315. * Text shown inside the table records when the is no information to be
  11316. * displayed after filtering. `emptyTable` is shown when there is simply no
  11317. * information in the table at all (regardless of filtering).
  11318. * @type string
  11319. * @default No matching records found
  11320. *
  11321. * @dtopt Language
  11322. * @name DataTable.defaults.language.zeroRecords
  11323. *
  11324. * @example
  11325. * $(document).ready( function() {
  11326. * $('#example').dataTable( {
  11327. * "language": {
  11328. * "zeroRecords": "No records to display"
  11329. * }
  11330. * } );
  11331. * } );
  11332. */
  11333. "sZeroRecords": "No matching records found"
  11334. },
  11335.  
  11336.  
  11337. /**
  11338. * This parameter allows you to have define the global filtering state at
  11339. * initialisation time. As an object the `search` parameter must be
  11340. * defined, but all other parameters are optional. When `regex` is true,
  11341. * the search string will be treated as a regular expression, when false
  11342. * (default) it will be treated as a straight string. When `smart`
  11343. * DataTables will use it's smart filtering methods (to word match at
  11344. * any point in the data), when false this will not be done.
  11345. * @namespace
  11346. * @extends DataTable.models.oSearch
  11347. *
  11348. * @dtopt Options
  11349. * @name DataTable.defaults.search
  11350. *
  11351. * @example
  11352. * $(document).ready( function() {
  11353. * $('#example').dataTable( {
  11354. * "search": {"search": "Initial search"}
  11355. * } );
  11356. * } )
  11357. */
  11358. "oSearch": $.extend( {}, DataTable.models.oSearch ),
  11359.  
  11360.  
  11361. /**
  11362. * __Deprecated__ The functionality provided by this parameter has now been
  11363. * superseded by that provided through `ajax`, which should be used instead.
  11364. *
  11365. * By default DataTables will look for the property `data` (or `aaData` for
  11366. * compatibility with DataTables 1.9-) when obtaining data from an Ajax
  11367. * source or for server-side processing - this parameter allows that
  11368. * property to be changed. You can use Javascript dotted object notation to
  11369. * get a data source for multiple levels of nesting.
  11370. * @type string
  11371. * @default data
  11372. *
  11373. * @dtopt Options
  11374. * @dtopt Server-side
  11375. * @name DataTable.defaults.ajaxDataProp
  11376. *
  11377. * @deprecated 1.10. Please use `ajax` for this functionality now.
  11378. */
  11379. "sAjaxDataProp": "data",
  11380.  
  11381.  
  11382. /**
  11383. * __Deprecated__ The functionality provided by this parameter has now been
  11384. * superseded by that provided through `ajax`, which should be used instead.
  11385. *
  11386. * You can instruct DataTables to load data from an external
  11387. * source using this parameter (use aData if you want to pass data in you
  11388. * already have). Simply provide a url a JSON object can be obtained from.
  11389. * @type string
  11390. * @default null
  11391. *
  11392. * @dtopt Options
  11393. * @dtopt Server-side
  11394. * @name DataTable.defaults.ajaxSource
  11395. *
  11396. * @deprecated 1.10. Please use `ajax` for this functionality now.
  11397. */
  11398. "sAjaxSource": null,
  11399.  
  11400.  
  11401. /**
  11402. * This initialisation variable allows you to specify exactly where in the
  11403. * DOM you want DataTables to inject the various controls it adds to the page
  11404. * (for example you might want the pagination controls at the top of the
  11405. * table). DIV elements (with or without a custom class) can also be added to
  11406. * aid styling. The follow syntax is used:
  11407. * <ul>
  11408. * <li>The following options are allowed:
  11409. * <ul>
  11410. * <li>'l' - Length changing</li>
  11411. * <li>'f' - Filtering input</li>
  11412. * <li>'t' - The table!</li>
  11413. * <li>'i' - Information</li>
  11414. * <li>'p' - Pagination</li>
  11415. * <li>'r' - pRocessing</li>
  11416. * </ul>
  11417. * </li>
  11418. * <li>The following constants are allowed:
  11419. * <ul>
  11420. * <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
  11421. * <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
  11422. * </ul>
  11423. * </li>
  11424. * <li>The following syntax is expected:
  11425. * <ul>
  11426. * <li>'&lt;' and '&gt;' - div elements</li>
  11427. * <li>'&lt;"class" and '&gt;' - div with a class</li>
  11428. * <li>'&lt;"#id" and '&gt;' - div with an ID</li>
  11429. * </ul>
  11430. * </li>
  11431. * <li>Examples:
  11432. * <ul>
  11433. * <li>'&lt;"wrapper"flipt&gt;'</li>
  11434. * <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
  11435. * </ul>
  11436. * </li>
  11437. * </ul>
  11438. * @type string
  11439. * @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
  11440. * <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
  11441. *
  11442. * @dtopt Options
  11443. * @name DataTable.defaults.dom
  11444. *
  11445. * @example
  11446. * $(document).ready( function() {
  11447. * $('#example').dataTable( {
  11448. * "dom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
  11449. * } );
  11450. * } );
  11451. */
  11452. "sDom": "lfrtip",
  11453.  
  11454.  
  11455. /**
  11456. * Search delay option. This will throttle full table searches that use the
  11457. * DataTables provided search input element (it does not effect calls to
  11458. * `dt-api search()`, providing a delay before the search is made.
  11459. * @type integer
  11460. * @default 0
  11461. *
  11462. * @dtopt Options
  11463. * @name DataTable.defaults.searchDelay
  11464. *
  11465. * @example
  11466. * $(document).ready( function() {
  11467. * $('#example').dataTable( {
  11468. * "searchDelay": 200
  11469. * } );
  11470. * } )
  11471. */
  11472. "searchDelay": null,
  11473.  
  11474.  
  11475. /**
  11476. * DataTables features four different built-in options for the buttons to
  11477. * display for pagination control:
  11478. *
  11479. * * `simple` - 'Previous' and 'Next' buttons only
  11480. * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
  11481. * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
  11482. * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus
  11483. * page numbers
  11484. *
  11485. * Further methods can be added using {@link DataTable.ext.oPagination}.
  11486. * @type string
  11487. * @default simple_numbers
  11488. *
  11489. * @dtopt Options
  11490. * @name DataTable.defaults.pagingType
  11491. *
  11492. * @example
  11493. * $(document).ready( function() {
  11494. * $('#example').dataTable( {
  11495. * "pagingType": "full_numbers"
  11496. * } );
  11497. * } )
  11498. */
  11499. "sPaginationType": "simple_numbers",
  11500.  
  11501.  
  11502. /**
  11503. * Enable horizontal scrolling. When a table is too wide to fit into a
  11504. * certain layout, or you have a large number of columns in the table, you
  11505. * can enable x-scrolling to show the table in a viewport, which can be
  11506. * scrolled. This property can be `true` which will allow the table to
  11507. * scroll horizontally when needed, or any CSS unit, or a number (in which
  11508. * case it will be treated as a pixel measurement). Setting as simply `true`
  11509. * is recommended.
  11510. * @type boolean|string
  11511. * @default <i>blank string - i.e. disabled</i>
  11512. *
  11513. * @dtopt Features
  11514. * @name DataTable.defaults.scrollX
  11515. *
  11516. * @example
  11517. * $(document).ready( function() {
  11518. * $('#example').dataTable( {
  11519. * "scrollX": true,
  11520. * "scrollCollapse": true
  11521. * } );
  11522. * } );
  11523. */
  11524. "sScrollX": "",
  11525.  
  11526.  
  11527. /**
  11528. * This property can be used to force a DataTable to use more width than it
  11529. * might otherwise do when x-scrolling is enabled. For example if you have a
  11530. * table which requires to be well spaced, this parameter is useful for
  11531. * "over-sizing" the table, and thus forcing scrolling. This property can by
  11532. * any CSS unit, or a number (in which case it will be treated as a pixel
  11533. * measurement).
  11534. * @type string
  11535. * @default <i>blank string - i.e. disabled</i>
  11536. *
  11537. * @dtopt Options
  11538. * @name DataTable.defaults.scrollXInner
  11539. *
  11540. * @example
  11541. * $(document).ready( function() {
  11542. * $('#example').dataTable( {
  11543. * "scrollX": "100%",
  11544. * "scrollXInner": "110%"
  11545. * } );
  11546. * } );
  11547. */
  11548. "sScrollXInner": "",
  11549.  
  11550.  
  11551. /**
  11552. * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
  11553. * to the given height, and enable scrolling for any data which overflows the
  11554. * current viewport. This can be used as an alternative to paging to display
  11555. * a lot of data in a small area (although paging and scrolling can both be
  11556. * enabled at the same time). This property can be any CSS unit, or a number
  11557. * (in which case it will be treated as a pixel measurement).
  11558. * @type string
  11559. * @default <i>blank string - i.e. disabled</i>
  11560. *
  11561. * @dtopt Features
  11562. * @name DataTable.defaults.scrollY
  11563. *
  11564. * @example
  11565. * $(document).ready( function() {
  11566. * $('#example').dataTable( {
  11567. * "scrollY": "200px",
  11568. * "paginate": false
  11569. * } );
  11570. * } );
  11571. */
  11572. "sScrollY": "",
  11573.  
  11574.  
  11575. /**
  11576. * __Deprecated__ The functionality provided by this parameter has now been
  11577. * superseded by that provided through `ajax`, which should be used instead.
  11578. *
  11579. * Set the HTTP method that is used to make the Ajax call for server-side
  11580. * processing or Ajax sourced data.
  11581. * @type string
  11582. * @default GET
  11583. *
  11584. * @dtopt Options
  11585. * @dtopt Server-side
  11586. * @name DataTable.defaults.serverMethod
  11587. *
  11588. * @deprecated 1.10. Please use `ajax` for this functionality now.
  11589. */
  11590. "sServerMethod": "GET",
  11591.  
  11592.  
  11593. /**
  11594. * DataTables makes use of renderers when displaying HTML elements for
  11595. * a table. These renderers can be added or modified by plug-ins to
  11596. * generate suitable mark-up for a site. For example the Bootstrap
  11597. * integration plug-in for DataTables uses a paging button renderer to
  11598. * display pagination buttons in the mark-up required by Bootstrap.
  11599. *
  11600. * For further information about the renderers available see
  11601. * DataTable.ext.renderer
  11602. * @type string|object
  11603. * @default null
  11604. *
  11605. * @name DataTable.defaults.renderer
  11606. *
  11607. */
  11608. "renderer": null
  11609. };
  11610.  
  11611. _fnHungarianMap( DataTable.defaults );
  11612.  
  11613.  
  11614.  
  11615. /*
  11616. * Developer note - See note in model.defaults.js about the use of Hungarian
  11617. * notation and camel case.
  11618. */
  11619.  
  11620. /**
  11621. * Column options that can be given to DataTables at initialisation time.
  11622. * @namespace
  11623. */
  11624. DataTable.defaults.column = {
  11625. /**
  11626. * Define which column(s) an order will occur on for this column. This
  11627. * allows a column's ordering to take multiple columns into account when
  11628. * doing a sort or use the data from a different column. For example first
  11629. * name / last name columns make sense to do a multi-column sort over the
  11630. * two columns.
  11631. * @type array|int
  11632. * @default null <i>Takes the value of the column index automatically</i>
  11633. *
  11634. * @name DataTable.defaults.column.orderData
  11635. * @dtopt Columns
  11636. *
  11637. * @example
  11638. * // Using `columnDefs`
  11639. * $(document).ready( function() {
  11640. * $('#example').dataTable( {
  11641. * "columnDefs": [
  11642. * { "orderData": [ 0, 1 ], "targets": [ 0 ] },
  11643. * { "orderData": [ 1, 0 ], "targets": [ 1 ] },
  11644. * { "orderData": 2, "targets": [ 2 ] }
  11645. * ]
  11646. * } );
  11647. * } );
  11648. *
  11649. * @example
  11650. * // Using `columns`
  11651. * $(document).ready( function() {
  11652. * $('#example').dataTable( {
  11653. * "columns": [
  11654. * { "orderData": [ 0, 1 ] },
  11655. * { "orderData": [ 1, 0 ] },
  11656. * { "orderData": 2 },
  11657. * null,
  11658. * null
  11659. * ]
  11660. * } );
  11661. * } );
  11662. */
  11663. "aDataSort": null,
  11664. "iDataSort": -1,
  11665.  
  11666.  
  11667. /**
  11668. * You can control the default ordering direction, and even alter the
  11669. * behaviour of the sort handler (i.e. only allow ascending ordering etc)
  11670. * using this parameter.
  11671. * @type array
  11672. * @default [ 'asc', 'desc' ]
  11673. *
  11674. * @name DataTable.defaults.column.orderSequence
  11675. * @dtopt Columns
  11676. *
  11677. * @example
  11678. * // Using `columnDefs`
  11679. * $(document).ready( function() {
  11680. * $('#example').dataTable( {
  11681. * "columnDefs": [
  11682. * { "orderSequence": [ "asc" ], "targets": [ 1 ] },
  11683. * { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
  11684. * { "orderSequence": [ "desc" ], "targets": [ 3 ] }
  11685. * ]
  11686. * } );
  11687. * } );
  11688. *
  11689. * @example
  11690. * // Using `columns`
  11691. * $(document).ready( function() {
  11692. * $('#example').dataTable( {
  11693. * "columns": [
  11694. * null,
  11695. * { "orderSequence": [ "asc" ] },
  11696. * { "orderSequence": [ "desc", "asc", "asc" ] },
  11697. * { "orderSequence": [ "desc" ] },
  11698. * null
  11699. * ]
  11700. * } );
  11701. * } );
  11702. */
  11703. "asSorting": [ 'asc', 'desc' ],
  11704.  
  11705.  
  11706. /**
  11707. * Enable or disable filtering on the data in this column.
  11708. * @type boolean
  11709. * @default true
  11710. *
  11711. * @name DataTable.defaults.column.searchable
  11712. * @dtopt Columns
  11713. *
  11714. * @example
  11715. * // Using `columnDefs`
  11716. * $(document).ready( function() {
  11717. * $('#example').dataTable( {
  11718. * "columnDefs": [
  11719. * { "searchable": false, "targets": [ 0 ] }
  11720. * ] } );
  11721. * } );
  11722. *
  11723. * @example
  11724. * // Using `columns`
  11725. * $(document).ready( function() {
  11726. * $('#example').dataTable( {
  11727. * "columns": [
  11728. * { "searchable": false },
  11729. * null,
  11730. * null,
  11731. * null,
  11732. * null
  11733. * ] } );
  11734. * } );
  11735. */
  11736. "bSearchable": true,
  11737.  
  11738.  
  11739. /**
  11740. * Enable or disable ordering on this column.
  11741. * @type boolean
  11742. * @default true
  11743. *
  11744. * @name DataTable.defaults.column.orderable
  11745. * @dtopt Columns
  11746. *
  11747. * @example
  11748. * // Using `columnDefs`
  11749. * $(document).ready( function() {
  11750. * $('#example').dataTable( {
  11751. * "columnDefs": [
  11752. * { "orderable": false, "targets": [ 0 ] }
  11753. * ] } );
  11754. * } );
  11755. *
  11756. * @example
  11757. * // Using `columns`
  11758. * $(document).ready( function() {
  11759. * $('#example').dataTable( {
  11760. * "columns": [
  11761. * { "orderable": false },
  11762. * null,
  11763. * null,
  11764. * null,
  11765. * null
  11766. * ] } );
  11767. * } );
  11768. */
  11769. "bSortable": true,
  11770.  
  11771.  
  11772. /**
  11773. * Enable or disable the display of this column.
  11774. * @type boolean
  11775. * @default true
  11776. *
  11777. * @name DataTable.defaults.column.visible
  11778. * @dtopt Columns
  11779. *
  11780. * @example
  11781. * // Using `columnDefs`
  11782. * $(document).ready( function() {
  11783. * $('#example').dataTable( {
  11784. * "columnDefs": [
  11785. * { "visible": false, "targets": [ 0 ] }
  11786. * ] } );
  11787. * } );
  11788. *
  11789. * @example
  11790. * // Using `columns`
  11791. * $(document).ready( function() {
  11792. * $('#example').dataTable( {
  11793. * "columns": [
  11794. * { "visible": false },
  11795. * null,
  11796. * null,
  11797. * null,
  11798. * null
  11799. * ] } );
  11800. * } );
  11801. */
  11802. "bVisible": true,
  11803.  
  11804.  
  11805. /**
  11806. * Developer definable function that is called whenever a cell is created (Ajax source,
  11807. * etc) or processed for input (DOM source). This can be used as a compliment to mRender
  11808. * allowing you to modify the DOM element (add background colour for example) when the
  11809. * element is available.
  11810. * @type function
  11811. * @param {element} td The TD node that has been created
  11812. * @param {*} cellData The Data for the cell
  11813. * @param {array|object} rowData The data for the whole row
  11814. * @param {int} row The row index for the aoData data store
  11815. * @param {int} col The column index for aoColumns
  11816. *
  11817. * @name DataTable.defaults.column.createdCell
  11818. * @dtopt Columns
  11819. *
  11820. * @example
  11821. * $(document).ready( function() {
  11822. * $('#example').dataTable( {
  11823. * "columnDefs": [ {
  11824. * "targets": [3],
  11825. * "createdCell": function (td, cellData, rowData, row, col) {
  11826. * if ( cellData == "1.7" ) {
  11827. * $(td).css('color', 'blue')
  11828. * }
  11829. * }
  11830. * } ]
  11831. * });
  11832. * } );
  11833. */
  11834. "fnCreatedCell": null,
  11835.  
  11836.  
  11837. /**
  11838. * This parameter has been replaced by `data` in DataTables to ensure naming
  11839. * consistency. `dataProp` can still be used, as there is backwards
  11840. * compatibility in DataTables for this option, but it is strongly
  11841. * recommended that you use `data` in preference to `dataProp`.
  11842. * @name DataTable.defaults.column.dataProp
  11843. */
  11844.  
  11845.  
  11846. /**
  11847. * This property can be used to read data from any data source property,
  11848. * including deeply nested objects / properties. `data` can be given in a
  11849. * number of different ways which effect its behaviour:
  11850. *
  11851. * * `integer` - treated as an array index for the data source. This is the
  11852. * default that DataTables uses (incrementally increased for each column).
  11853. * * `string` - read an object property from the data source. There are
  11854. * three 'special' options that can be used in the string to alter how
  11855. * DataTables reads the data from the source object:
  11856. * * `.` - Dotted Javascript notation. Just as you use a `.` in
  11857. * Javascript to read from nested objects, so to can the options
  11858. * specified in `data`. For example: `browser.version` or
  11859. * `browser.name`. If your object parameter name contains a period, use
  11860. * `\\` to escape it - i.e. `first\\.name`.
  11861. * * `[]` - Array notation. DataTables can automatically combine data
  11862. * from and array source, joining the data with the characters provided
  11863. * between the two brackets. For example: `name[, ]` would provide a
  11864. * comma-space separated list from the source array. If no characters
  11865. * are provided between the brackets, the original array source is
  11866. * returned.
  11867. * * `()` - Function notation. Adding `()` to the end of a parameter will
  11868. * execute a function of the name given. For example: `browser()` for a
  11869. * simple function on the data source, `browser.version()` for a
  11870. * function in a nested property or even `browser().version` to get an
  11871. * object property if the function called returns an object. Note that
  11872. * function notation is recommended for use in `render` rather than
  11873. * `data` as it is much simpler to use as a renderer.
  11874. * * `null` - use the original data source for the row rather than plucking
  11875. * data directly from it. This action has effects on two other
  11876. * initialisation options:
  11877. * * `defaultContent` - When null is given as the `data` option and
  11878. * `defaultContent` is specified for the column, the value defined by
  11879. * `defaultContent` will be used for the cell.
  11880. * * `render` - When null is used for the `data` option and the `render`
  11881. * option is specified for the column, the whole data source for the
  11882. * row is used for the renderer.
  11883. * * `function` - the function given will be executed whenever DataTables
  11884. * needs to set or get the data for a cell in the column. The function
  11885. * takes three parameters:
  11886. * * Parameters:
  11887. * * `{array|object}` The data source for the row
  11888. * * `{string}` The type call data requested - this will be 'set' when
  11889. * setting data or 'filter', 'display', 'type', 'sort' or undefined
  11890. * when gathering data. Note that when `undefined` is given for the
  11891. * type DataTables expects to get the raw data for the object back<
  11892. * * `{*}` Data to set when the second parameter is 'set'.
  11893. * * Return:
  11894. * * The return value from the function is not required when 'set' is
  11895. * the type of call, but otherwise the return is what will be used
  11896. * for the data requested.
  11897. *
  11898. * Note that `data` is a getter and setter option. If you just require
  11899. * formatting of data for output, you will likely want to use `render` which
  11900. * is simply a getter and thus simpler to use.
  11901. *
  11902. * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
  11903. * name change reflects the flexibility of this property and is consistent
  11904. * with the naming of mRender. If 'mDataProp' is given, then it will still
  11905. * be used by DataTables, as it automatically maps the old name to the new
  11906. * if required.
  11907. *
  11908. * @type string|int|function|null
  11909. * @default null <i>Use automatically calculated column index</i>
  11910. *
  11911. * @name DataTable.defaults.column.data
  11912. * @dtopt Columns
  11913. *
  11914. * @example
  11915. * // Read table data from objects
  11916. * // JSON structure for each row:
  11917. * // {
  11918. * // "engine": {value},
  11919. * // "browser": {value},
  11920. * // "platform": {value},
  11921. * // "version": {value},
  11922. * // "grade": {value}
  11923. * // }
  11924. * $(document).ready( function() {
  11925. * $('#example').dataTable( {
  11926. * "ajaxSource": "sources/objects.txt",
  11927. * "columns": [
  11928. * { "data": "engine" },
  11929. * { "data": "browser" },
  11930. * { "data": "platform" },
  11931. * { "data": "version" },
  11932. * { "data": "grade" }
  11933. * ]
  11934. * } );
  11935. * } );
  11936. *
  11937. * @example
  11938. * // Read information from deeply nested objects
  11939. * // JSON structure for each row:
  11940. * // {
  11941. * // "engine": {value},
  11942. * // "browser": {value},
  11943. * // "platform": {
  11944. * // "inner": {value}
  11945. * // },
  11946. * // "details": [
  11947. * // {value}, {value}
  11948. * // ]
  11949. * // }
  11950. * $(document).ready( function() {
  11951. * $('#example').dataTable( {
  11952. * "ajaxSource": "sources/deep.txt",
  11953. * "columns": [
  11954. * { "data": "engine" },
  11955. * { "data": "browser" },
  11956. * { "data": "platform.inner" },
  11957. * { "data": "platform.details.0" },
  11958. * { "data": "platform.details.1" }
  11959. * ]
  11960. * } );
  11961. * } );
  11962. *
  11963. * @example
  11964. * // Using `data` as a function to provide different information for
  11965. * // sorting, filtering and display. In this case, currency (price)
  11966. * $(document).ready( function() {
  11967. * $('#example').dataTable( {
  11968. * "columnDefs": [ {
  11969. * "targets": [ 0 ],
  11970. * "data": function ( source, type, val ) {
  11971. * if (type === 'set') {
  11972. * source.price = val;
  11973. * // Store the computed dislay and filter values for efficiency
  11974. * source.price_display = val=="" ? "" : "$"+numberFormat(val);
  11975. * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val;
  11976. * return;
  11977. * }
  11978. * else if (type === 'display') {
  11979. * return source.price_display;
  11980. * }
  11981. * else if (type === 'filter') {
  11982. * return source.price_filter;
  11983. * }
  11984. * // 'sort', 'type' and undefined all just use the integer
  11985. * return source.price;
  11986. * }
  11987. * } ]
  11988. * } );
  11989. * } );
  11990. *
  11991. * @example
  11992. * // Using default content
  11993. * $(document).ready( function() {
  11994. * $('#example').dataTable( {
  11995. * "columnDefs": [ {
  11996. * "targets": [ 0 ],
  11997. * "data": null,
  11998. * "defaultContent": "Click to edit"
  11999. * } ]
  12000. * } );
  12001. * } );
  12002. *
  12003. * @example
  12004. * // Using array notation - outputting a list from an array
  12005. * $(document).ready( function() {
  12006. * $('#example').dataTable( {
  12007. * "columnDefs": [ {
  12008. * "targets": [ 0 ],
  12009. * "data": "name[, ]"
  12010. * } ]
  12011. * } );
  12012. * } );
  12013. *
  12014. */
  12015. "mData": null,
  12016.  
  12017.  
  12018. /**
  12019. * This property is the rendering partner to `data` and it is suggested that
  12020. * when you want to manipulate data for display (including filtering,
  12021. * sorting etc) without altering the underlying data for the table, use this
  12022. * property. `render` can be considered to be the the read only companion to
  12023. * `data` which is read / write (then as such more complex). Like `data`
  12024. * this option can be given in a number of different ways to effect its
  12025. * behaviour:
  12026. *
  12027. * * `integer` - treated as an array index for the data source. This is the
  12028. * default that DataTables uses (incrementally increased for each column).
  12029. * * `string` - read an object property from the data source. There are
  12030. * three 'special' options that can be used in the string to alter how
  12031. * DataTables reads the data from the source object:
  12032. * * `.` - Dotted Javascript notation. Just as you use a `.` in
  12033. * Javascript to read from nested objects, so to can the options
  12034. * specified in `data`. For example: `browser.version` or
  12035. * `browser.name`. If your object parameter name contains a period, use
  12036. * `\\` to escape it - i.e. `first\\.name`.
  12037. * * `[]` - Array notation. DataTables can automatically combine data
  12038. * from and array source, joining the data with the characters provided
  12039. * between the two brackets. For example: `name[, ]` would provide a
  12040. * comma-space separated list from the source array. If no characters
  12041. * are provided between the brackets, the original array source is
  12042. * returned.
  12043. * * `()` - Function notation. Adding `()` to the end of a parameter will
  12044. * execute a function of the name given. For example: `browser()` for a
  12045. * simple function on the data source, `browser.version()` for a
  12046. * function in a nested property or even `browser().version` to get an
  12047. * object property if the function called returns an object.
  12048. * * `object` - use different data for the different data types requested by
  12049. * DataTables ('filter', 'display', 'type' or 'sort'). The property names
  12050. * of the object is the data type the property refers to and the value can
  12051. * defined using an integer, string or function using the same rules as
  12052. * `render` normally does. Note that an `_` option _must_ be specified.
  12053. * This is the default value to use if you haven't specified a value for
  12054. * the data type requested by DataTables.
  12055. * * `function` - the function given will be executed whenever DataTables
  12056. * needs to set or get the data for a cell in the column. The function
  12057. * takes three parameters:
  12058. * * Parameters:
  12059. * * {array|object} The data source for the row (based on `data`)
  12060. * * {string} The type call data requested - this will be 'filter',
  12061. * 'display', 'type' or 'sort'.
  12062. * * {array|object} The full data source for the row (not based on
  12063. * `data`)
  12064. * * Return:
  12065. * * The return value from the function is what will be used for the
  12066. * data requested.
  12067. *
  12068. * @type string|int|function|object|null
  12069. * @default null Use the data source value.
  12070. *
  12071. * @name DataTable.defaults.column.render
  12072. * @dtopt Columns
  12073. *
  12074. * @example
  12075. * // Create a comma separated list from an array of objects
  12076. * $(document).ready( function() {
  12077. * $('#example').dataTable( {
  12078. * "ajaxSource": "sources/deep.txt",
  12079. * "columns": [
  12080. * { "data": "engine" },
  12081. * { "data": "browser" },
  12082. * {
  12083. * "data": "platform",
  12084. * "render": "[, ].name"
  12085. * }
  12086. * ]
  12087. * } );
  12088. * } );
  12089. *
  12090. * @example
  12091. * // Execute a function to obtain data
  12092. * $(document).ready( function() {
  12093. * $('#example').dataTable( {
  12094. * "columnDefs": [ {
  12095. * "targets": [ 0 ],
  12096. * "data": null, // Use the full data source object for the renderer's source
  12097. * "render": "browserName()"
  12098. * } ]
  12099. * } );
  12100. * } );
  12101. *
  12102. * @example
  12103. * // As an object, extracting different data for the different types
  12104. * // This would be used with a data source such as:
  12105. * // { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
  12106. * // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
  12107. * // (which has both forms) is used for filtering for if a user inputs either format, while
  12108. * // the formatted phone number is the one that is shown in the table.
  12109. * $(document).ready( function() {
  12110. * $('#example').dataTable( {
  12111. * "columnDefs": [ {
  12112. * "targets": [ 0 ],
  12113. * "data": null, // Use the full data source object for the renderer's source
  12114. * "render": {
  12115. * "_": "phone",
  12116. * "filter": "phone_filter",
  12117. * "display": "phone_display"
  12118. * }
  12119. * } ]
  12120. * } );
  12121. * } );
  12122. *
  12123. * @example
  12124. * // Use as a function to create a link from the data source
  12125. * $(document).ready( function() {
  12126. * $('#example').dataTable( {
  12127. * "columnDefs": [ {
  12128. * "targets": [ 0 ],
  12129. * "data": "download_link",
  12130. * "render": function ( data, type, full ) {
  12131. * return '<a href="'+data+'">Download</a>';
  12132. * }
  12133. * } ]
  12134. * } );
  12135. * } );
  12136. */
  12137. "mRender": null,
  12138.  
  12139.  
  12140. /**
  12141. * Change the cell type created for the column - either TD cells or TH cells. This
  12142. * can be useful as TH cells have semantic meaning in the table body, allowing them
  12143. * to act as a header for a row (you may wish to add scope='row' to the TH elements).
  12144. * @type string
  12145. * @default td
  12146. *
  12147. * @name DataTable.defaults.column.cellType
  12148. * @dtopt Columns
  12149. *
  12150. * @example
  12151. * // Make the first column use TH cells
  12152. * $(document).ready( function() {
  12153. * $('#example').dataTable( {
  12154. * "columnDefs": [ {
  12155. * "targets": [ 0 ],
  12156. * "cellType": "th"
  12157. * } ]
  12158. * } );
  12159. * } );
  12160. */
  12161. "sCellType": "td",
  12162.  
  12163.  
  12164. /**
  12165. * Class to give to each cell in this column.
  12166. * @type string
  12167. * @default <i>Empty string</i>
  12168. *
  12169. * @name DataTable.defaults.column.class
  12170. * @dtopt Columns
  12171. *
  12172. * @example
  12173. * // Using `columnDefs`
  12174. * $(document).ready( function() {
  12175. * $('#example').dataTable( {
  12176. * "columnDefs": [
  12177. * { "class": "my_class", "targets": [ 0 ] }
  12178. * ]
  12179. * } );
  12180. * } );
  12181. *
  12182. * @example
  12183. * // Using `columns`
  12184. * $(document).ready( function() {
  12185. * $('#example').dataTable( {
  12186. * "columns": [
  12187. * { "class": "my_class" },
  12188. * null,
  12189. * null,
  12190. * null,
  12191. * null
  12192. * ]
  12193. * } );
  12194. * } );
  12195. */
  12196. "sClass": "",
  12197.  
  12198. /**
  12199. * When DataTables calculates the column widths to assign to each column,
  12200. * it finds the longest string in each column and then constructs a
  12201. * temporary table and reads the widths from that. The problem with this
  12202. * is that "mmm" is much wider then "iiii", but the latter is a longer
  12203. * string - thus the calculation can go wrong (doing it properly and putting
  12204. * it into an DOM object and measuring that is horribly(!) slow). Thus as
  12205. * a "work around" we provide this option. It will append its value to the
  12206. * text that is found to be the longest string for the column - i.e. padding.
  12207. * Generally you shouldn't need this!
  12208. * @type string
  12209. * @default <i>Empty string<i>
  12210. *
  12211. * @name DataTable.defaults.column.contentPadding
  12212. * @dtopt Columns
  12213. *
  12214. * @example
  12215. * // Using `columns`
  12216. * $(document).ready( function() {
  12217. * $('#example').dataTable( {
  12218. * "columns": [
  12219. * null,
  12220. * null,
  12221. * null,
  12222. * {
  12223. * "contentPadding": "mmm"
  12224. * }
  12225. * ]
  12226. * } );
  12227. * } );
  12228. */
  12229. "sContentPadding": "",
  12230.  
  12231.  
  12232. /**
  12233. * Allows a default value to be given for a column's data, and will be used
  12234. * whenever a null data source is encountered (this can be because `data`
  12235. * is set to null, or because the data source itself is null).
  12236. * @type string
  12237. * @default null
  12238. *
  12239. * @name DataTable.defaults.column.defaultContent
  12240. * @dtopt Columns
  12241. *
  12242. * @example
  12243. * // Using `columnDefs`
  12244. * $(document).ready( function() {
  12245. * $('#example').dataTable( {
  12246. * "columnDefs": [
  12247. * {
  12248. * "data": null,
  12249. * "defaultContent": "Edit",
  12250. * "targets": [ -1 ]
  12251. * }
  12252. * ]
  12253. * } );
  12254. * } );
  12255. *
  12256. * @example
  12257. * // Using `columns`
  12258. * $(document).ready( function() {
  12259. * $('#example').dataTable( {
  12260. * "columns": [
  12261. * null,
  12262. * null,
  12263. * null,
  12264. * {
  12265. * "data": null,
  12266. * "defaultContent": "Edit"
  12267. * }
  12268. * ]
  12269. * } );
  12270. * } );
  12271. */
  12272. "sDefaultContent": null,
  12273.  
  12274.  
  12275. /**
  12276. * This parameter is only used in DataTables' server-side processing. It can
  12277. * be exceptionally useful to know what columns are being displayed on the
  12278. * client side, and to map these to database fields. When defined, the names
  12279. * also allow DataTables to reorder information from the server if it comes
  12280. * back in an unexpected order (i.e. if you switch your columns around on the
  12281. * client-side, your server-side code does not also need updating).
  12282. * @type string
  12283. * @default <i>Empty string</i>
  12284. *
  12285. * @name DataTable.defaults.column.name
  12286. * @dtopt Columns
  12287. *
  12288. * @example
  12289. * // Using `columnDefs`
  12290. * $(document).ready( function() {
  12291. * $('#example').dataTable( {
  12292. * "columnDefs": [
  12293. * { "name": "engine", "targets": [ 0 ] },
  12294. * { "name": "browser", "targets": [ 1 ] },
  12295. * { "name": "platform", "targets": [ 2 ] },
  12296. * { "name": "version", "targets": [ 3 ] },
  12297. * { "name": "grade", "targets": [ 4 ] }
  12298. * ]
  12299. * } );
  12300. * } );
  12301. *
  12302. * @example
  12303. * // Using `columns`
  12304. * $(document).ready( function() {
  12305. * $('#example').dataTable( {
  12306. * "columns": [
  12307. * { "name": "engine" },
  12308. * { "name": "browser" },
  12309. * { "name": "platform" },
  12310. * { "name": "version" },
  12311. * { "name": "grade" }
  12312. * ]
  12313. * } );
  12314. * } );
  12315. */
  12316. "sName": "",
  12317.  
  12318.  
  12319. /**
  12320. * Defines a data source type for the ordering which can be used to read
  12321. * real-time information from the table (updating the internally cached
  12322. * version) prior to ordering. This allows ordering to occur on user
  12323. * editable elements such as form inputs.
  12324. * @type string
  12325. * @default std
  12326. *
  12327. * @name DataTable.defaults.column.orderDataType
  12328. * @dtopt Columns
  12329. *
  12330. * @example
  12331. * // Using `columnDefs`
  12332. * $(document).ready( function() {
  12333. * $('#example').dataTable( {
  12334. * "columnDefs": [
  12335. * { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
  12336. * { "type": "numeric", "targets": [ 3 ] },
  12337. * { "orderDataType": "dom-select", "targets": [ 4 ] },
  12338. * { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
  12339. * ]
  12340. * } );
  12341. * } );
  12342. *
  12343. * @example
  12344. * // Using `columns`
  12345. * $(document).ready( function() {
  12346. * $('#example').dataTable( {
  12347. * "columns": [
  12348. * null,
  12349. * null,
  12350. * { "orderDataType": "dom-text" },
  12351. * { "orderDataType": "dom-text", "type": "numeric" },
  12352. * { "orderDataType": "dom-select" },
  12353. * { "orderDataType": "dom-checkbox" }
  12354. * ]
  12355. * } );
  12356. * } );
  12357. */
  12358. "sSortDataType": "std",
  12359.  
  12360.  
  12361. /**
  12362. * The title of this column.
  12363. * @type string
  12364. * @default null <i>Derived from the 'TH' value for this column in the
  12365. * original HTML table.</i>
  12366. *
  12367. * @name DataTable.defaults.column.title
  12368. * @dtopt Columns
  12369. *
  12370. * @example
  12371. * // Using `columnDefs`
  12372. * $(document).ready( function() {
  12373. * $('#example').dataTable( {
  12374. * "columnDefs": [
  12375. * { "title": "My column title", "targets": [ 0 ] }
  12376. * ]
  12377. * } );
  12378. * } );
  12379. *
  12380. * @example
  12381. * // Using `columns`
  12382. * $(document).ready( function() {
  12383. * $('#example').dataTable( {
  12384. * "columns": [
  12385. * { "title": "My column title" },
  12386. * null,
  12387. * null,
  12388. * null,
  12389. * null
  12390. * ]
  12391. * } );
  12392. * } );
  12393. */
  12394. "sTitle": null,
  12395.  
  12396.  
  12397. /**
  12398. * The type allows you to specify how the data for this column will be
  12399. * ordered. Four types (string, numeric, date and html (which will strip
  12400. * HTML tags before ordering)) are currently available. Note that only date
  12401. * formats understood by Javascript's Date() object will be accepted as type
  12402. * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
  12403. * 'numeric', 'date' or 'html' (by default). Further types can be adding
  12404. * through plug-ins.
  12405. * @type string
  12406. * @default null <i>Auto-detected from raw data</i>
  12407. *
  12408. * @name DataTable.defaults.column.type
  12409. * @dtopt Columns
  12410. *
  12411. * @example
  12412. * // Using `columnDefs`
  12413. * $(document).ready( function() {
  12414. * $('#example').dataTable( {
  12415. * "columnDefs": [
  12416. * { "type": "html", "targets": [ 0 ] }
  12417. * ]
  12418. * } );
  12419. * } );
  12420. *
  12421. * @example
  12422. * // Using `columns`
  12423. * $(document).ready( function() {
  12424. * $('#example').dataTable( {
  12425. * "columns": [
  12426. * { "type": "html" },
  12427. * null,
  12428. * null,
  12429. * null,
  12430. * null
  12431. * ]
  12432. * } );
  12433. * } );
  12434. */
  12435. "sType": null,
  12436.  
  12437.  
  12438. /**
  12439. * Defining the width of the column, this parameter may take any CSS value
  12440. * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
  12441. * been given a specific width through this interface ensuring that the table
  12442. * remains readable.
  12443. * @type string
  12444. * @default null <i>Automatic</i>
  12445. *
  12446. * @name DataTable.defaults.column.width
  12447. * @dtopt Columns
  12448. *
  12449. * @example
  12450. * // Using `columnDefs`
  12451. * $(document).ready( function() {
  12452. * $('#example').dataTable( {
  12453. * "columnDefs": [
  12454. * { "width": "20%", "targets": [ 0 ] }
  12455. * ]
  12456. * } );
  12457. * } );
  12458. *
  12459. * @example
  12460. * // Using `columns`
  12461. * $(document).ready( function() {
  12462. * $('#example').dataTable( {
  12463. * "columns": [
  12464. * { "width": "20%" },
  12465. * null,
  12466. * null,
  12467. * null,
  12468. * null
  12469. * ]
  12470. * } );
  12471. * } );
  12472. */
  12473. "sWidth": null
  12474. };
  12475.  
  12476. _fnHungarianMap( DataTable.defaults.column );
  12477.  
  12478.  
  12479.  
  12480. /**
  12481. * DataTables settings object - this holds all the information needed for a
  12482. * given table, including configuration, data and current application of the
  12483. * table options. DataTables does not have a single instance for each DataTable
  12484. * with the settings attached to that instance, but rather instances of the
  12485. * DataTable "class" are created on-the-fly as needed (typically by a
  12486. * $().dataTable() call) and the settings object is then applied to that
  12487. * instance.
  12488. *
  12489. * Note that this object is related to {@link DataTable.defaults} but this
  12490. * one is the internal data store for DataTables's cache of columns. It should
  12491. * NOT be manipulated outside of DataTables. Any configuration should be done
  12492. * through the initialisation options.
  12493. * @namespace
  12494. * @todo Really should attach the settings object to individual instances so we
  12495. * don't need to create new instances on each $().dataTable() call (if the
  12496. * table already exists). It would also save passing oSettings around and
  12497. * into every single function. However, this is a very significant
  12498. * architecture change for DataTables and will almost certainly break
  12499. * backwards compatibility with older installations. This is something that
  12500. * will be done in 2.0.
  12501. */
  12502. DataTable.models.oSettings = {
  12503. /**
  12504. * Primary features of DataTables and their enablement state.
  12505. * @namespace
  12506. */
  12507. "oFeatures": {
  12508.  
  12509. /**
  12510. * Flag to say if DataTables should automatically try to calculate the
  12511. * optimum table and columns widths (true) or not (false).
  12512. * Note that this parameter will be set by the initialisation routine. To
  12513. * set a default use {@link DataTable.defaults}.
  12514. * @type boolean
  12515. */
  12516. "bAutoWidth": null,
  12517.  
  12518. /**
  12519. * Delay the creation of TR and TD elements until they are actually
  12520. * needed by a driven page draw. This can give a significant speed
  12521. * increase for Ajax source and Javascript source data, but makes no
  12522. * difference at all fro DOM and server-side processing tables.
  12523. * Note that this parameter will be set by the initialisation routine. To
  12524. * set a default use {@link DataTable.defaults}.
  12525. * @type boolean
  12526. */
  12527. "bDeferRender": null,
  12528.  
  12529. /**
  12530. * Enable filtering on the table or not. Note that if this is disabled
  12531. * then there is no filtering at all on the table, including fnFilter.
  12532. * To just remove the filtering input use sDom and remove the 'f' option.
  12533. * Note that this parameter will be set by the initialisation routine. To
  12534. * set a default use {@link DataTable.defaults}.
  12535. * @type boolean
  12536. */
  12537. "bFilter": null,
  12538.  
  12539. /**
  12540. * Table information element (the 'Showing x of y records' div) enable
  12541. * flag.
  12542. * Note that this parameter will be set by the initialisation routine. To
  12543. * set a default use {@link DataTable.defaults}.
  12544. * @type boolean
  12545. */
  12546. "bInfo": null,
  12547.  
  12548. /**
  12549. * Present a user control allowing the end user to change the page size
  12550. * when pagination is enabled.
  12551. * Note that this parameter will be set by the initialisation routine. To
  12552. * set a default use {@link DataTable.defaults}.
  12553. * @type boolean
  12554. */
  12555. "bLengthChange": null,
  12556.  
  12557. /**
  12558. * Pagination enabled or not. Note that if this is disabled then length
  12559. * changing must also be disabled.
  12560. * Note that this parameter will be set by the initialisation routine. To
  12561. * set a default use {@link DataTable.defaults}.
  12562. * @type boolean
  12563. */
  12564. "bPaginate": null,
  12565.  
  12566. /**
  12567. * Processing indicator enable flag whenever DataTables is enacting a
  12568. * user request - typically an Ajax request for server-side processing.
  12569. * Note that this parameter will be set by the initialisation routine. To
  12570. * set a default use {@link DataTable.defaults}.
  12571. * @type boolean
  12572. */
  12573. "bProcessing": null,
  12574.  
  12575. /**
  12576. * Server-side processing enabled flag - when enabled DataTables will
  12577. * get all data from the server for every draw - there is no filtering,
  12578. * sorting or paging done on the client-side.
  12579. * Note that this parameter will be set by the initialisation routine. To
  12580. * set a default use {@link DataTable.defaults}.
  12581. * @type boolean
  12582. */
  12583. "bServerSide": null,
  12584.  
  12585. /**
  12586. * Sorting enablement flag.
  12587. * Note that this parameter will be set by the initialisation routine. To
  12588. * set a default use {@link DataTable.defaults}.
  12589. * @type boolean
  12590. */
  12591. "bSort": null,
  12592.  
  12593. /**
  12594. * Multi-column sorting
  12595. * Note that this parameter will be set by the initialisation routine. To
  12596. * set a default use {@link DataTable.defaults}.
  12597. * @type boolean
  12598. */
  12599. "bSortMulti": null,
  12600.  
  12601. /**
  12602. * Apply a class to the columns which are being sorted to provide a
  12603. * visual highlight or not. This can slow things down when enabled since
  12604. * there is a lot of DOM interaction.
  12605. * Note that this parameter will be set by the initialisation routine. To
  12606. * set a default use {@link DataTable.defaults}.
  12607. * @type boolean
  12608. */
  12609. "bSortClasses": null,
  12610.  
  12611. /**
  12612. * State saving enablement flag.
  12613. * Note that this parameter will be set by the initialisation routine. To
  12614. * set a default use {@link DataTable.defaults}.
  12615. * @type boolean
  12616. */
  12617. "bStateSave": null
  12618. },
  12619.  
  12620.  
  12621. /**
  12622. * Scrolling settings for a table.
  12623. * @namespace
  12624. */
  12625. "oScroll": {
  12626. /**
  12627. * When the table is shorter in height than sScrollY, collapse the
  12628. * table container down to the height of the table (when true).
  12629. * Note that this parameter will be set by the initialisation routine. To
  12630. * set a default use {@link DataTable.defaults}.
  12631. * @type boolean
  12632. */
  12633. "bCollapse": null,
  12634.  
  12635. /**
  12636. * Width of the scrollbar for the web-browser's platform. Calculated
  12637. * during table initialisation.
  12638. * @type int
  12639. * @default 0
  12640. */
  12641. "iBarWidth": 0,
  12642.  
  12643. /**
  12644. * Viewport width for horizontal scrolling. Horizontal scrolling is
  12645. * disabled if an empty string.
  12646. * Note that this parameter will be set by the initialisation routine. To
  12647. * set a default use {@link DataTable.defaults}.
  12648. * @type string
  12649. */
  12650. "sX": null,
  12651.  
  12652. /**
  12653. * Width to expand the table to when using x-scrolling. Typically you
  12654. * should not need to use this.
  12655. * Note that this parameter will be set by the initialisation routine. To
  12656. * set a default use {@link DataTable.defaults}.
  12657. * @type string
  12658. * @deprecated
  12659. */
  12660. "sXInner": null,
  12661.  
  12662. /**
  12663. * Viewport height for vertical scrolling. Vertical scrolling is disabled
  12664. * if an empty string.
  12665. * Note that this parameter will be set by the initialisation routine. To
  12666. * set a default use {@link DataTable.defaults}.
  12667. * @type string
  12668. */
  12669. "sY": null
  12670. },
  12671.  
  12672. /**
  12673. * Language information for the table.
  12674. * @namespace
  12675. * @extends DataTable.defaults.oLanguage
  12676. */
  12677. "oLanguage": {
  12678. /**
  12679. * Information callback function. See
  12680. * {@link DataTable.defaults.fnInfoCallback}
  12681. * @type function
  12682. * @default null
  12683. */
  12684. "fnInfoCallback": null
  12685. },
  12686.  
  12687. /**
  12688. * Browser support parameters
  12689. * @namespace
  12690. */
  12691. "oBrowser": {
  12692. /**
  12693. * Indicate if the browser incorrectly calculates width:100% inside a
  12694. * scrolling element (IE6/7)
  12695. * @type boolean
  12696. * @default false
  12697. */
  12698. "bScrollOversize": false,
  12699.  
  12700. /**
  12701. * Determine if the vertical scrollbar is on the right or left of the
  12702. * scrolling container - needed for rtl language layout, although not
  12703. * all browsers move the scrollbar (Safari).
  12704. * @type boolean
  12705. * @default false
  12706. */
  12707. "bScrollbarLeft": false
  12708. },
  12709.  
  12710.  
  12711. "ajax": null,
  12712.  
  12713.  
  12714. /**
  12715. * Array referencing the nodes which are used for the features. The
  12716. * parameters of this object match what is allowed by sDom - i.e.
  12717. * <ul>
  12718. * <li>'l' - Length changing</li>
  12719. * <li>'f' - Filtering input</li>
  12720. * <li>'t' - The table!</li>
  12721. * <li>'i' - Information</li>
  12722. * <li>'p' - Pagination</li>
  12723. * <li>'r' - pRocessing</li>
  12724. * </ul>
  12725. * @type array
  12726. * @default []
  12727. */
  12728. "aanFeatures": [],
  12729.  
  12730. /**
  12731. * Store data information - see {@link DataTable.models.oRow} for detailed
  12732. * information.
  12733. * @type array
  12734. * @default []
  12735. */
  12736. "aoData": [],
  12737.  
  12738. /**
  12739. * Array of indexes which are in the current display (after filtering etc)
  12740. * @type array
  12741. * @default []
  12742. */
  12743. "aiDisplay": [],
  12744.  
  12745. /**
  12746. * Array of indexes for display - no filtering
  12747. * @type array
  12748. * @default []
  12749. */
  12750. "aiDisplayMaster": [],
  12751.  
  12752. /**
  12753. * Store information about each column that is in use
  12754. * @type array
  12755. * @default []
  12756. */
  12757. "aoColumns": [],
  12758.  
  12759. /**
  12760. * Store information about the table's header
  12761. * @type array
  12762. * @default []
  12763. */
  12764. "aoHeader": [],
  12765.  
  12766. /**
  12767. * Store information about the table's footer
  12768. * @type array
  12769. * @default []
  12770. */
  12771. "aoFooter": [],
  12772.  
  12773. /**
  12774. * Store the applied global search information in case we want to force a
  12775. * research or compare the old search to a new one.
  12776. * Note that this parameter will be set by the initialisation routine. To
  12777. * set a default use {@link DataTable.defaults}.
  12778. * @namespace
  12779. * @extends DataTable.models.oSearch
  12780. */
  12781. "oPreviousSearch": {},
  12782.  
  12783. /**
  12784. * Store the applied search for each column - see
  12785. * {@link DataTable.models.oSearch} for the format that is used for the
  12786. * filtering information for each column.
  12787. * @type array
  12788. * @default []
  12789. */
  12790. "aoPreSearchCols": [],
  12791.  
  12792. /**
  12793. * Sorting that is applied to the table. Note that the inner arrays are
  12794. * used in the following manner:
  12795. * <ul>
  12796. * <li>Index 0 - column number</li>
  12797. * <li>Index 1 - current sorting direction</li>
  12798. * </ul>
  12799. * Note that this parameter will be set by the initialisation routine. To
  12800. * set a default use {@link DataTable.defaults}.
  12801. * @type array
  12802. * @todo These inner arrays should really be objects
  12803. */
  12804. "aaSorting": null,
  12805.  
  12806. /**
  12807. * Sorting that is always applied to the table (i.e. prefixed in front of
  12808. * aaSorting).
  12809. * Note that this parameter will be set by the initialisation routine. To
  12810. * set a default use {@link DataTable.defaults}.
  12811. * @type array
  12812. * @default []
  12813. */
  12814. "aaSortingFixed": [],
  12815.  
  12816. /**
  12817. * Classes to use for the striping of a table.
  12818. * Note that this parameter will be set by the initialisation routine. To
  12819. * set a default use {@link DataTable.defaults}.
  12820. * @type array
  12821. * @default []
  12822. */
  12823. "asStripeClasses": null,
  12824.  
  12825. /**
  12826. * If restoring a table - we should restore its striping classes as well
  12827. * @type array
  12828. * @default []
  12829. */
  12830. "asDestroyStripes": [],
  12831.  
  12832. /**
  12833. * If restoring a table - we should restore its width
  12834. * @type int
  12835. * @default 0
  12836. */
  12837. "sDestroyWidth": 0,
  12838.  
  12839. /**
  12840. * Callback functions array for every time a row is inserted (i.e. on a draw).
  12841. * @type array
  12842. * @default []
  12843. */
  12844. "aoRowCallback": [],
  12845.  
  12846. /**
  12847. * Callback functions for the header on each draw.
  12848. * @type array
  12849. * @default []
  12850. */
  12851. "aoHeaderCallback": [],
  12852.  
  12853. /**
  12854. * Callback function for the footer on each draw.
  12855. * @type array
  12856. * @default []
  12857. */
  12858. "aoFooterCallback": [],
  12859.  
  12860. /**
  12861. * Array of callback functions for draw callback functions
  12862. * @type array
  12863. * @default []
  12864. */
  12865. "aoDrawCallback": [],
  12866.  
  12867. /**
  12868. * Array of callback functions for row created function
  12869. * @type array
  12870. * @default []
  12871. */
  12872. "aoRowCreatedCallback": [],
  12873.  
  12874. /**
  12875. * Callback functions for just before the table is redrawn. A return of
  12876. * false will be used to cancel the draw.
  12877. * @type array
  12878. * @default []
  12879. */
  12880. "aoPreDrawCallback": [],
  12881.  
  12882. /**
  12883. * Callback functions for when the table has been initialised.
  12884. * @type array
  12885. * @default []
  12886. */
  12887. "aoInitComplete": [],
  12888.  
  12889.  
  12890. /**
  12891. * Callbacks for modifying the settings to be stored for state saving, prior to
  12892. * saving state.
  12893. * @type array
  12894. * @default []
  12895. */
  12896. "aoStateSaveParams": [],
  12897.  
  12898. /**
  12899. * Callbacks for modifying the settings that have been stored for state saving
  12900. * prior to using the stored values to restore the state.
  12901. * @type array
  12902. * @default []
  12903. */
  12904. "aoStateLoadParams": [],
  12905.  
  12906. /**
  12907. * Callbacks for operating on the settings object once the saved state has been
  12908. * loaded
  12909. * @type array
  12910. * @default []
  12911. */
  12912. "aoStateLoaded": [],
  12913.  
  12914. /**
  12915. * Cache the table ID for quick access
  12916. * @type string
  12917. * @default <i>Empty string</i>
  12918. */
  12919. "sTableId": "",
  12920.  
  12921. /**
  12922. * The TABLE node for the main table
  12923. * @type node
  12924. * @default null
  12925. */
  12926. "nTable": null,
  12927.  
  12928. /**
  12929. * Permanent ref to the thead element
  12930. * @type node
  12931. * @default null
  12932. */
  12933. "nTHead": null,
  12934.  
  12935. /**
  12936. * Permanent ref to the tfoot element - if it exists
  12937. * @type node
  12938. * @default null
  12939. */
  12940. "nTFoot": null,
  12941.  
  12942. /**
  12943. * Permanent ref to the tbody element
  12944. * @type node
  12945. * @default null
  12946. */
  12947. "nTBody": null,
  12948.  
  12949. /**
  12950. * Cache the wrapper node (contains all DataTables controlled elements)
  12951. * @type node
  12952. * @default null
  12953. */
  12954. "nTableWrapper": null,
  12955.  
  12956. /**
  12957. * Indicate if when using server-side processing the loading of data
  12958. * should be deferred until the second draw.
  12959. * Note that this parameter will be set by the initialisation routine. To
  12960. * set a default use {@link DataTable.defaults}.
  12961. * @type boolean
  12962. * @default false
  12963. */
  12964. "bDeferLoading": false,
  12965.  
  12966. /**
  12967. * Indicate if all required information has been read in
  12968. * @type boolean
  12969. * @default false
  12970. */
  12971. "bInitialised": false,
  12972.  
  12973. /**
  12974. * Information about open rows. Each object in the array has the parameters
  12975. * 'nTr' and 'nParent'
  12976. * @type array
  12977. * @default []
  12978. */
  12979. "aoOpenRows": [],
  12980.  
  12981. /**
  12982. * Dictate the positioning of DataTables' control elements - see
  12983. * {@link DataTable.model.oInit.sDom}.
  12984. * Note that this parameter will be set by the initialisation routine. To
  12985. * set a default use {@link DataTable.defaults}.
  12986. * @type string
  12987. * @default null
  12988. */
  12989. "sDom": null,
  12990.  
  12991. /**
  12992. * Search delay (in mS)
  12993. * @type integer
  12994. * @default null
  12995. */
  12996. "searchDelay": null,
  12997.  
  12998. /**
  12999. * Which type of pagination should be used.
  13000. * Note that this parameter will be set by the initialisation routine. To
  13001. * set a default use {@link DataTable.defaults}.
  13002. * @type string
  13003. * @default two_button
  13004. */
  13005. "sPaginationType": "two_button",
  13006.  
  13007. /**
  13008. * The state duration (for `stateSave`) in seconds.
  13009. * Note that this parameter will be set by the initialisation routine. To
  13010. * set a default use {@link DataTable.defaults}.
  13011. * @type int
  13012. * @default 0
  13013. */
  13014. "iStateDuration": 0,
  13015.  
  13016. /**
  13017. * Array of callback functions for state saving. Each array element is an
  13018. * object with the following parameters:
  13019. * <ul>
  13020. * <li>function:fn - function to call. Takes two parameters, oSettings
  13021. * and the JSON string to save that has been thus far created. Returns
  13022. * a JSON string to be inserted into a json object
  13023. * (i.e. '"param": [ 0, 1, 2]')</li>
  13024. * <li>string:sName - name of callback</li>
  13025. * </ul>
  13026. * @type array
  13027. * @default []
  13028. */
  13029. "aoStateSave": [],
  13030.  
  13031. /**
  13032. * Array of callback functions for state loading. Each array element is an
  13033. * object with the following parameters:
  13034. * <ul>
  13035. * <li>function:fn - function to call. Takes two parameters, oSettings
  13036. * and the object stored. May return false to cancel state loading</li>
  13037. * <li>string:sName - name of callback</li>
  13038. * </ul>
  13039. * @type array
  13040. * @default []
  13041. */
  13042. "aoStateLoad": [],
  13043.  
  13044. /**
  13045. * State that was saved. Useful for back reference
  13046. * @type object
  13047. * @default null
  13048. */
  13049. "oSavedState": null,
  13050.  
  13051. /**
  13052. * State that was loaded. Useful for back reference
  13053. * @type object
  13054. * @default null
  13055. */
  13056. "oLoadedState": null,
  13057.  
  13058. /**
  13059. * Source url for AJAX data for the table.
  13060. * Note that this parameter will be set by the initialisation routine. To
  13061. * set a default use {@link DataTable.defaults}.
  13062. * @type string
  13063. * @default null
  13064. */
  13065. "sAjaxSource": null,
  13066.  
  13067. /**
  13068. * Property from a given object from which to read the table data from. This
  13069. * can be an empty string (when not server-side processing), in which case
  13070. * it is assumed an an array is given directly.
  13071. * Note that this parameter will be set by the initialisation routine. To
  13072. * set a default use {@link DataTable.defaults}.
  13073. * @type string
  13074. */
  13075. "sAjaxDataProp": null,
  13076.  
  13077. /**
  13078. * Note if draw should be blocked while getting data
  13079. * @type boolean
  13080. * @default true
  13081. */
  13082. "bAjaxDataGet": true,
  13083.  
  13084. /**
  13085. * The last jQuery XHR object that was used for server-side data gathering.
  13086. * This can be used for working with the XHR information in one of the
  13087. * callbacks
  13088. * @type object
  13089. * @default null
  13090. */
  13091. "jqXHR": null,
  13092.  
  13093. /**
  13094. * JSON returned from the server in the last Ajax request
  13095. * @type object
  13096. * @default undefined
  13097. */
  13098. "json": undefined,
  13099.  
  13100. /**
  13101. * Data submitted as part of the last Ajax request
  13102. * @type object
  13103. * @default undefined
  13104. */
  13105. "oAjaxData": undefined,
  13106.  
  13107. /**
  13108. * Function to get the server-side data.
  13109. * Note that this parameter will be set by the initialisation routine. To
  13110. * set a default use {@link DataTable.defaults}.
  13111. * @type function
  13112. */
  13113. "fnServerData": null,
  13114.  
  13115. /**
  13116. * Functions which are called prior to sending an Ajax request so extra
  13117. * parameters can easily be sent to the server
  13118. * @type array
  13119. * @default []
  13120. */
  13121. "aoServerParams": [],
  13122.  
  13123. /**
  13124. * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
  13125. * required).
  13126. * Note that this parameter will be set by the initialisation routine. To
  13127. * set a default use {@link DataTable.defaults}.
  13128. * @type string
  13129. */
  13130. "sServerMethod": null,
  13131.  
  13132. /**
  13133. * Format numbers for display.
  13134. * Note that this parameter will be set by the initialisation routine. To
  13135. * set a default use {@link DataTable.defaults}.
  13136. * @type function
  13137. */
  13138. "fnFormatNumber": null,
  13139.  
  13140. /**
  13141. * List of options that can be used for the user selectable length menu.
  13142. * Note that this parameter will be set by the initialisation routine. To
  13143. * set a default use {@link DataTable.defaults}.
  13144. * @type array
  13145. * @default []
  13146. */
  13147. "aLengthMenu": null,
  13148.  
  13149. /**
  13150. * Counter for the draws that the table does. Also used as a tracker for
  13151. * server-side processing
  13152. * @type int
  13153. * @default 0
  13154. */
  13155. "iDraw": 0,
  13156.  
  13157. /**
  13158. * Indicate if a redraw is being done - useful for Ajax
  13159. * @type boolean
  13160. * @default false
  13161. */
  13162. "bDrawing": false,
  13163.  
  13164. /**
  13165. * Draw index (iDraw) of the last error when parsing the returned data
  13166. * @type int
  13167. * @default -1
  13168. */
  13169. "iDrawError": -1,
  13170.  
  13171. /**
  13172. * Paging display length
  13173. * @type int
  13174. * @default 10
  13175. */
  13176. "_iDisplayLength": 10,
  13177.  
  13178. /**
  13179. * Paging start point - aiDisplay index
  13180. * @type int
  13181. * @default 0
  13182. */
  13183. "_iDisplayStart": 0,
  13184.  
  13185. /**
  13186. * Server-side processing - number of records in the result set
  13187. * (i.e. before filtering), Use fnRecordsTotal rather than
  13188. * this property to get the value of the number of records, regardless of
  13189. * the server-side processing setting.
  13190. * @type int
  13191. * @default 0
  13192. * @private
  13193. */
  13194. "_iRecordsTotal": 0,
  13195.  
  13196. /**
  13197. * Server-side processing - number of records in the current display set
  13198. * (i.e. after filtering). Use fnRecordsDisplay rather than
  13199. * this property to get the value of the number of records, regardless of
  13200. * the server-side processing setting.
  13201. * @type boolean
  13202. * @default 0
  13203. * @private
  13204. */
  13205. "_iRecordsDisplay": 0,
  13206.  
  13207. /**
  13208. * Flag to indicate if jQuery UI marking and classes should be used.
  13209. * Note that this parameter will be set by the initialisation routine. To
  13210. * set a default use {@link DataTable.defaults}.
  13211. * @type boolean
  13212. */
  13213. "bJUI": null,
  13214.  
  13215. /**
  13216. * The classes to use for the table
  13217. * @type object
  13218. * @default {}
  13219. */
  13220. "oClasses": {},
  13221.  
  13222. /**
  13223. * Flag attached to the settings object so you can check in the draw
  13224. * callback if filtering has been done in the draw. Deprecated in favour of
  13225. * events.
  13226. * @type boolean
  13227. * @default false
  13228. * @deprecated
  13229. */
  13230. "bFiltered": false,
  13231.  
  13232. /**
  13233. * Flag attached to the settings object so you can check in the draw
  13234. * callback if sorting has been done in the draw. Deprecated in favour of
  13235. * events.
  13236. * @type boolean
  13237. * @default false
  13238. * @deprecated
  13239. */
  13240. "bSorted": false,
  13241.  
  13242. /**
  13243. * Indicate that if multiple rows are in the header and there is more than
  13244. * one unique cell per column, if the top one (true) or bottom one (false)
  13245. * should be used for sorting / title by DataTables.
  13246. * Note that this parameter will be set by the initialisation routine. To
  13247. * set a default use {@link DataTable.defaults}.
  13248. * @type boolean
  13249. */
  13250. "bSortCellsTop": null,
  13251.  
  13252. /**
  13253. * Initialisation object that is used for the table
  13254. * @type object
  13255. * @default null
  13256. */
  13257. "oInit": null,
  13258.  
  13259. /**
  13260. * Destroy callback functions - for plug-ins to attach themselves to the
  13261. * destroy so they can clean up markup and events.
  13262. * @type array
  13263. * @default []
  13264. */
  13265. "aoDestroyCallback": [],
  13266.  
  13267.  
  13268. /**
  13269. * Get the number of records in the current record set, before filtering
  13270. * @type function
  13271. */
  13272. "fnRecordsTotal": function ()
  13273. {
  13274. return _fnDataSource( this ) == 'ssp' ?
  13275. this._iRecordsTotal * 1 :
  13276. this.aiDisplayMaster.length;
  13277. },
  13278.  
  13279. /**
  13280. * Get the number of records in the current record set, after filtering
  13281. * @type function
  13282. */
  13283. "fnRecordsDisplay": function ()
  13284. {
  13285. return _fnDataSource( this ) == 'ssp' ?
  13286. this._iRecordsDisplay * 1 :
  13287. this.aiDisplay.length;
  13288. },
  13289.  
  13290. /**
  13291. * Get the display end point - aiDisplay index
  13292. * @type function
  13293. */
  13294. "fnDisplayEnd": function ()
  13295. {
  13296. var
  13297. len = this._iDisplayLength,
  13298. start = this._iDisplayStart,
  13299. calc = start + len,
  13300. records = this.aiDisplay.length,
  13301. features = this.oFeatures,
  13302. paginate = features.bPaginate;
  13303.  
  13304. if ( features.bServerSide ) {
  13305. return paginate === false || len === -1 ?
  13306. start + records :
  13307. Math.min( start+len, this._iRecordsDisplay );
  13308. }
  13309. else {
  13310. return ! paginate || calc>records || len===-1 ?
  13311. records :
  13312. calc;
  13313. }
  13314. },
  13315.  
  13316. /**
  13317. * The DataTables object for this table
  13318. * @type object
  13319. * @default null
  13320. */
  13321. "oInstance": null,
  13322.  
  13323. /**
  13324. * Unique identifier for each instance of the DataTables object. If there
  13325. * is an ID on the table node, then it takes that value, otherwise an
  13326. * incrementing internal counter is used.
  13327. * @type string
  13328. * @default null
  13329. */
  13330. "sInstance": null,
  13331.  
  13332. /**
  13333. * tabindex attribute value that is added to DataTables control elements, allowing
  13334. * keyboard navigation of the table and its controls.
  13335. */
  13336. "iTabIndex": 0,
  13337.  
  13338. /**
  13339. * DIV container for the footer scrolling table if scrolling
  13340. */
  13341. "nScrollHead": null,
  13342.  
  13343. /**
  13344. * DIV container for the footer scrolling table if scrolling
  13345. */
  13346. "nScrollFoot": null,
  13347.  
  13348. /**
  13349. * Last applied sort
  13350. * @type array
  13351. * @default []
  13352. */
  13353. "aLastSort": [],
  13354.  
  13355. /**
  13356. * Stored plug-in instances
  13357. * @type object
  13358. * @default {}
  13359. */
  13360. "oPlugins": {}
  13361. };
  13362.  
  13363. /**
  13364. * Extension object for DataTables that is used to provide all extension
  13365. * options.
  13366. *
  13367. * Note that the `DataTable.ext` object is available through
  13368. * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
  13369. * also aliased to `jQuery.fn.dataTableExt` for historic reasons.
  13370. * @namespace
  13371. * @extends DataTable.models.ext
  13372. */
  13373.  
  13374.  
  13375. /**
  13376. * DataTables extensions
  13377. *
  13378. * This namespace acts as a collection area for plug-ins that can be used to
  13379. * extend DataTables capabilities. Indeed many of the build in methods
  13380. * use this method to provide their own capabilities (sorting methods for
  13381. * example).
  13382. *
  13383. * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
  13384. * reasons
  13385. *
  13386. * @namespace
  13387. */
  13388. DataTable.ext = _ext = {
  13389. /**
  13390. * Element class names
  13391. *
  13392. * @type object
  13393. * @default {}
  13394. */
  13395. classes: {},
  13396.  
  13397.  
  13398. /**
  13399. * Error reporting.
  13400. *
  13401. * How should DataTables report an error. Can take the value 'alert' or
  13402. * 'throw'
  13403. *
  13404. * @type string
  13405. * @default alert
  13406. */
  13407. errMode: "alert",
  13408.  
  13409.  
  13410. /**
  13411. * Feature plug-ins.
  13412. *
  13413. * This is an array of objects which describe the feature plug-ins that are
  13414. * available to DataTables. These feature plug-ins are then available for
  13415. * use through the `dom` initialisation option.
  13416. *
  13417. * Each feature plug-in is described by an object which must have the
  13418. * following properties:
  13419. *
  13420. * * `fnInit` - function that is used to initialise the plug-in,
  13421. * * `cFeature` - a character so the feature can be enabled by the `dom`
  13422. * instillation option. This is case sensitive.
  13423. *
  13424. * The `fnInit` function has the following input parameters:
  13425. *
  13426. * 1. `{object}` DataTables settings object: see
  13427. * {@link DataTable.models.oSettings}
  13428. *
  13429. * And the following return is expected:
  13430. *
  13431. * * {node|null} The element which contains your feature. Note that the
  13432. * return may also be void if your plug-in does not require to inject any
  13433. * DOM elements into DataTables control (`dom`) - for example this might
  13434. * be useful when developing a plug-in which allows table control via
  13435. * keyboard entry
  13436. *
  13437. * @type array
  13438. *
  13439. * @example
  13440. * $.fn.dataTable.ext.features.push( {
  13441. * "fnInit": function( oSettings ) {
  13442. * return new TableTools( { "oDTSettings": oSettings } );
  13443. * },
  13444. * "cFeature": "T"
  13445. * } );
  13446. */
  13447. feature: [],
  13448.  
  13449.  
  13450. /**
  13451. * Row searching.
  13452. *
  13453. * This method of searching is complimentary to the default type based
  13454. * searching, and a lot more comprehensive as it allows you complete control
  13455. * over the searching logic. Each element in this array is a function
  13456. * (parameters described below) that is called for every row in the table,
  13457. * and your logic decides if it should be included in the searching data set
  13458. * or not.
  13459. *
  13460. * Searching functions have the following input parameters:
  13461. *
  13462. * 1. `{object}` DataTables settings object: see
  13463. * {@link DataTable.models.oSettings}
  13464. * 2. `{array|object}` Data for the row to be processed (same as the
  13465. * original format that was passed in as the data source, or an array
  13466. * from a DOM data source
  13467. * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
  13468. * can be useful to retrieve the `TR` element if you need DOM interaction.
  13469. *
  13470. * And the following return is expected:
  13471. *
  13472. * * {boolean} Include the row in the searched result set (true) or not
  13473. * (false)
  13474. *
  13475. * Note that as with the main search ability in DataTables, technically this
  13476. * is "filtering", since it is subtractive. However, for consistency in
  13477. * naming we call it searching here.
  13478. *
  13479. * @type array
  13480. * @default []
  13481. *
  13482. * @example
  13483. * // The following example shows custom search being applied to the
  13484. * // fourth column (i.e. the data[3] index) based on two input values
  13485. * // from the end-user, matching the data in a certain range.
  13486. * $.fn.dataTable.ext.search.push(
  13487. * function( settings, data, dataIndex ) {
  13488. * var min = document.getElementById('min').value * 1;
  13489. * var max = document.getElementById('max').value * 1;
  13490. * var version = data[3] == "-" ? 0 : data[3]*1;
  13491. *
  13492. * if ( min == "" && max == "" ) {
  13493. * return true;
  13494. * }
  13495. * else if ( min == "" && version < max ) {
  13496. * return true;
  13497. * }
  13498. * else if ( min < version && "" == max ) {
  13499. * return true;
  13500. * }
  13501. * else if ( min < version && version < max ) {
  13502. * return true;
  13503. * }
  13504. * return false;
  13505. * }
  13506. * );
  13507. */
  13508. search: [],
  13509.  
  13510.  
  13511. /**
  13512. * Internal functions, exposed for used in plug-ins.
  13513. *
  13514. * Please note that you should not need to use the internal methods for
  13515. * anything other than a plug-in (and even then, try to avoid if possible).
  13516. * The internal function may change between releases.
  13517. *
  13518. * @type object
  13519. * @default {}
  13520. */
  13521. internal: {},
  13522.  
  13523.  
  13524. /**
  13525. * Legacy configuration options. Enable and disable legacy options that
  13526. * are available in DataTables.
  13527. *
  13528. * @type object
  13529. */
  13530. legacy: {
  13531. /**
  13532. * Enable / disable DataTables 1.9 compatible server-side processing
  13533. * requests
  13534. *
  13535. * @type boolean
  13536. * @default null
  13537. */
  13538. ajax: null
  13539. },
  13540.  
  13541.  
  13542. /**
  13543. * Pagination plug-in methods.
  13544. *
  13545. * Each entry in this object is a function and defines which buttons should
  13546. * be shown by the pagination rendering method that is used for the table:
  13547. * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
  13548. * buttons are displayed in the document, while the functions here tell it
  13549. * what buttons to display. This is done by returning an array of button
  13550. * descriptions (what each button will do).
  13551. *
  13552. * Pagination types (the four built in options and any additional plug-in
  13553. * options defined here) can be used through the `paginationType`
  13554. * initialisation parameter.
  13555. *
  13556. * The functions defined take two parameters:
  13557. *
  13558. * 1. `{int} page` The current page index
  13559. * 2. `{int} pages` The number of pages in the table
  13560. *
  13561. * Each function is expected to return an array where each element of the
  13562. * array can be one of:
  13563. *
  13564. * * `first` - Jump to first page when activated
  13565. * * `last` - Jump to last page when activated
  13566. * * `previous` - Show previous page when activated
  13567. * * `next` - Show next page when activated
  13568. * * `{int}` - Show page of the index given
  13569. * * `{array}` - A nested array containing the above elements to add a
  13570. * containing 'DIV' element (might be useful for styling).
  13571. *
  13572. * Note that DataTables v1.9- used this object slightly differently whereby
  13573. * an object with two functions would be defined for each plug-in. That
  13574. * ability is still supported by DataTables 1.10+ to provide backwards
  13575. * compatibility, but this option of use is now decremented and no longer
  13576. * documented in DataTables 1.10+.
  13577. *
  13578. * @type object
  13579. * @default {}
  13580. *
  13581. * @example
  13582. * // Show previous, next and current page buttons only
  13583. * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
  13584. * return [ 'previous', page, 'next' ];
  13585. * };
  13586. */
  13587. pager: {},
  13588.  
  13589.  
  13590. renderer: {
  13591. pageButton: {},
  13592. header: {}
  13593. },
  13594.  
  13595.  
  13596. /**
  13597. * Ordering plug-ins - custom data source
  13598. *
  13599. * The extension options for ordering of data available here is complimentary
  13600. * to the default type based ordering that DataTables typically uses. It
  13601. * allows much greater control over the the data that is being used to
  13602. * order a column, but is necessarily therefore more complex.
  13603. *
  13604. * This type of ordering is useful if you want to do ordering based on data
  13605. * live from the DOM (for example the contents of an 'input' element) rather
  13606. * than just the static string that DataTables knows of.
  13607. *
  13608. * The way these plug-ins work is that you create an array of the values you
  13609. * wish to be ordering for the column in question and then return that
  13610. * array. The data in the array much be in the index order of the rows in
  13611. * the table (not the currently ordering order!). Which order data gathering
  13612. * function is run here depends on the `dt-init columns.orderDataType`
  13613. * parameter that is used for the column (if any).
  13614. *
  13615. * The functions defined take two parameters:
  13616. *
  13617. * 1. `{object}` DataTables settings object: see
  13618. * {@link DataTable.models.oSettings}
  13619. * 2. `{int}` Target column index
  13620. *
  13621. * Each function is expected to return an array:
  13622. *
  13623. * * `{array}` Data for the column to be ordering upon
  13624. *
  13625. * @type array
  13626. *
  13627. * @example
  13628. * // Ordering using `input` node values
  13629. * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )
  13630. * {
  13631. * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
  13632. * return $('input', td).val();
  13633. * } );
  13634. * }
  13635. */
  13636. order: {},
  13637.  
  13638.  
  13639. /**
  13640. * Type based plug-ins.
  13641. *
  13642. * Each column in DataTables has a type assigned to it, either by automatic
  13643. * detection or by direct assignment using the `type` option for the column.
  13644. * The type of a column will effect how it is ordering and search (plug-ins
  13645. * can also make use of the column type if required).
  13646. *
  13647. * @namespace
  13648. */
  13649. type: {
  13650. /**
  13651. * Type detection functions.
  13652. *
  13653. * The functions defined in this object are used to automatically detect
  13654. * a column's type, making initialisation of DataTables super easy, even
  13655. * when complex data is in the table.
  13656. *
  13657. * The functions defined take two parameters:
  13658. *
  13659. * 1. `{*}` Data from the column cell to be analysed
  13660. * 2. `{settings}` DataTables settings object. This can be used to
  13661. * perform context specific type detection - for example detection
  13662. * based on language settings such as using a comma for a decimal
  13663. * place. Generally speaking the options from the settings will not
  13664. * be required
  13665. *
  13666. * Each function is expected to return:
  13667. *
  13668. * * `{string|null}` Data type detected, or null if unknown (and thus
  13669. * pass it on to the other type detection functions.
  13670. *
  13671. * @type array
  13672. *
  13673. * @example
  13674. * // Currency type detection plug-in:
  13675. * $.fn.dataTable.ext.type.detect.push(
  13676. * function ( data, settings ) {
  13677. * // Check the numeric part
  13678. * if ( ! $.isNumeric( data.substring(1) ) ) {
  13679. * return null;
  13680. * }
  13681. *
  13682. * // Check prefixed by currency
  13683. * if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
  13684. * return 'currency';
  13685. * }
  13686. * return null;
  13687. * }
  13688. * );
  13689. */
  13690. detect: [],
  13691.  
  13692.  
  13693. /**
  13694. * Type based search formatting.
  13695. *
  13696. * The type based searching functions can be used to pre-format the
  13697. * data to be search on. For example, it can be used to strip HTML
  13698. * tags or to de-format telephone numbers for numeric only searching.
  13699. *
  13700. * Note that is a search is not defined for a column of a given type,
  13701. * no search formatting will be performed.
  13702. *
  13703. * Pre-processing of searching data plug-ins - When you assign the sType
  13704. * for a column (or have it automatically detected for you by DataTables
  13705. * or a type detection plug-in), you will typically be using this for
  13706. * custom sorting, but it can also be used to provide custom searching
  13707. * by allowing you to pre-processing the data and returning the data in
  13708. * the format that should be searched upon. This is done by adding
  13709. * functions this object with a parameter name which matches the sType
  13710. * for that target column. This is the corollary of <i>afnSortData</i>
  13711. * for searching data.
  13712. *
  13713. * The functions defined take a single parameter:
  13714. *
  13715. * 1. `{*}` Data from the column cell to be prepared for searching
  13716. *
  13717. * Each function is expected to return:
  13718. *
  13719. * * `{string|null}` Formatted string that will be used for the searching.
  13720. *
  13721. * @type object
  13722. * @default {}
  13723. *
  13724. * @example
  13725. * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
  13726. * return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
  13727. * }
  13728. */
  13729. search: {},
  13730.  
  13731.  
  13732. /**
  13733. * Type based ordering.
  13734. *
  13735. * The column type tells DataTables what ordering to apply to the table
  13736. * when a column is sorted upon. The order for each type that is defined,
  13737. * is defined by the functions available in this object.
  13738. *
  13739. * Each ordering option can be described by three properties added to
  13740. * this object:
  13741. *
  13742. * * `{type}-pre` - Pre-formatting function
  13743. * * `{type}-asc` - Ascending order function
  13744. * * `{type}-desc` - Descending order function
  13745. *
  13746. * All three can be used together, only `{type}-pre` or only
  13747. * `{type}-asc` and `{type}-desc` together. It is generally recommended
  13748. * that only `{type}-pre` is used, as this provides the optimal
  13749. * implementation in terms of speed, although the others are provided
  13750. * for compatibility with existing Javascript sort functions.
  13751. *
  13752. * `{type}-pre`: Functions defined take a single parameter:
  13753. *
  13754. * 1. `{*}` Data from the column cell to be prepared for ordering
  13755. *
  13756. * And return:
  13757. *
  13758. * * `{*}` Data to be sorted upon
  13759. *
  13760. * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
  13761. * functions, taking two parameters:
  13762. *
  13763. * 1. `{*}` Data to compare to the second parameter
  13764. * 2. `{*}` Data to compare to the first parameter
  13765. *
  13766. * And returning:
  13767. *
  13768. * * `{*}` Ordering match: <0 if first parameter should be sorted lower
  13769. * than the second parameter, ===0 if the two parameters are equal and
  13770. * >0 if the first parameter should be sorted height than the second
  13771. * parameter.
  13772. *
  13773. * @type object
  13774. * @default {}
  13775. *
  13776. * @example
  13777. * // Numeric ordering of formatted numbers with a pre-formatter
  13778. * $.extend( $.fn.dataTable.ext.type.order, {
  13779. * "string-pre": function(x) {
  13780. * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
  13781. * return parseFloat( a );
  13782. * }
  13783. * } );
  13784. *
  13785. * @example
  13786. * // Case-sensitive string ordering, with no pre-formatting method
  13787. * $.extend( $.fn.dataTable.ext.order, {
  13788. * "string-case-asc": function(x,y) {
  13789. * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
  13790. * },
  13791. * "string-case-desc": function(x,y) {
  13792. * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
  13793. * }
  13794. * } );
  13795. */
  13796. order: {}
  13797. },
  13798.  
  13799. /**
  13800. * Unique DataTables instance counter
  13801. *
  13802. * @type int
  13803. * @private
  13804. */
  13805. _unique: 0,
  13806.  
  13807.  
  13808. //
  13809. // Depreciated
  13810. // The following properties are retained for backwards compatiblity only.
  13811. // The should not be used in new projects and will be removed in a future
  13812. // version
  13813. //
  13814.  
  13815. /**
  13816. * Version check function.
  13817. * @type function
  13818. * @depreciated Since 1.10
  13819. */
  13820. fnVersionCheck: DataTable.fnVersionCheck,
  13821.  
  13822.  
  13823. /**
  13824. * Index for what 'this' index API functions should use
  13825. * @type int
  13826. * @deprecated Since v1.10
  13827. */
  13828. iApiIndex: 0,
  13829.  
  13830.  
  13831. /**
  13832. * jQuery UI class container
  13833. * @type object
  13834. * @deprecated Since v1.10
  13835. */
  13836. oJUIClasses: {},
  13837.  
  13838.  
  13839. /**
  13840. * Software version
  13841. * @type string
  13842. * @deprecated Since v1.10
  13843. */
  13844. sVersion: DataTable.version
  13845. };
  13846.  
  13847.  
  13848. //
  13849. // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
  13850. //
  13851. $.extend( _ext, {
  13852. afnFiltering: _ext.search,
  13853. aTypes: _ext.type.detect,
  13854. ofnSearch: _ext.type.search,
  13855. oSort: _ext.type.order,
  13856. afnSortData: _ext.order,
  13857. aoFeatures: _ext.feature,
  13858. oApi: _ext.internal,
  13859. oStdClasses: _ext.classes,
  13860. oPagination: _ext.pager
  13861. } );
  13862.  
  13863.  
  13864. $.extend( DataTable.ext.classes, {
  13865. "sTable": "dataTable",
  13866. "sNoFooter": "no-footer",
  13867.  
  13868. /* Paging buttons */
  13869. "sPageButton": "paginate_button",
  13870. "sPageButtonActive": "current",
  13871. "sPageButtonDisabled": "disabled",
  13872.  
  13873. /* Striping classes */
  13874. "sStripeOdd": "odd",
  13875. "sStripeEven": "even",
  13876.  
  13877. /* Empty row */
  13878. "sRowEmpty": "dataTables_empty",
  13879.  
  13880. /* Features */
  13881. "sWrapper": "dataTables_wrapper",
  13882. "sFilter": "dataTables_filter",
  13883. "sInfo": "dataTables_info",
  13884. "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
  13885. "sLength": "dataTables_length",
  13886. "sProcessing": "dataTables_processing",
  13887.  
  13888. /* Sorting */
  13889. "sSortAsc": "sorting_asc",
  13890. "sSortDesc": "sorting_desc",
  13891. "sSortable": "sorting", /* Sortable in both directions */
  13892. "sSortableAsc": "sorting_asc_disabled",
  13893. "sSortableDesc": "sorting_desc_disabled",
  13894. "sSortableNone": "sorting_disabled",
  13895. "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
  13896.  
  13897. /* Filtering */
  13898. "sFilterInput": "",
  13899.  
  13900. /* Page length */
  13901. "sLengthSelect": "",
  13902.  
  13903. /* Scrolling */
  13904. "sScrollWrapper": "dataTables_scroll",
  13905. "sScrollHead": "dataTables_scrollHead",
  13906. "sScrollHeadInner": "dataTables_scrollHeadInner",
  13907. "sScrollBody": "dataTables_scrollBody",
  13908. "sScrollFoot": "dataTables_scrollFoot",
  13909. "sScrollFootInner": "dataTables_scrollFootInner",
  13910.  
  13911. /* Misc */
  13912. "sHeaderTH": "",
  13913. "sFooterTH": "",
  13914.  
  13915. // Deprecated
  13916. "sSortJUIAsc": "",
  13917. "sSortJUIDesc": "",
  13918. "sSortJUI": "",
  13919. "sSortJUIAscAllowed": "",
  13920. "sSortJUIDescAllowed": "",
  13921. "sSortJUIWrapper": "",
  13922. "sSortIcon": "",
  13923. "sJUIHeader": "",
  13924. "sJUIFooter": ""
  13925. } );
  13926.  
  13927.  
  13928. (function() {
  13929.  
  13930. // Reused strings for better compression. Closure compiler appears to have a
  13931. // weird edge case where it is trying to expand strings rather than use the
  13932. // variable version. This results in about 200 bytes being added, for very
  13933. // little preference benefit since it this run on script load only.
  13934. var _empty = '';
  13935. _empty = '';
  13936.  
  13937. var _stateDefault = _empty + 'ui-state-default';
  13938. var _sortIcon = _empty + 'css_right ui-icon ui-icon-';
  13939. var _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix';
  13940.  
  13941. $.extend( DataTable.ext.oJUIClasses, DataTable.ext.classes, {
  13942. /* Full numbers paging buttons */
  13943. "sPageButton": "fg-button ui-button "+_stateDefault,
  13944. "sPageButtonActive": "ui-state-disabled",
  13945. "sPageButtonDisabled": "ui-state-disabled",
  13946.  
  13947. /* Features */
  13948. "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
  13949. "ui-buttonset-multi paging_", /* Note that the type is postfixed */
  13950.  
  13951. /* Sorting */
  13952. "sSortAsc": _stateDefault+" sorting_asc",
  13953. "sSortDesc": _stateDefault+" sorting_desc",
  13954. "sSortable": _stateDefault+" sorting",
  13955. "sSortableAsc": _stateDefault+" sorting_asc_disabled",
  13956. "sSortableDesc": _stateDefault+" sorting_desc_disabled",
  13957. "sSortableNone": _stateDefault+" sorting_disabled",
  13958. "sSortJUIAsc": _sortIcon+"triangle-1-n",
  13959. "sSortJUIDesc": _sortIcon+"triangle-1-s",
  13960. "sSortJUI": _sortIcon+"carat-2-n-s",
  13961. "sSortJUIAscAllowed": _sortIcon+"carat-1-n",
  13962. "sSortJUIDescAllowed": _sortIcon+"carat-1-s",
  13963. "sSortJUIWrapper": "DataTables_sort_wrapper",
  13964. "sSortIcon": "DataTables_sort_icon",
  13965.  
  13966. /* Scrolling */
  13967. "sScrollHead": "dataTables_scrollHead "+_stateDefault,
  13968. "sScrollFoot": "dataTables_scrollFoot "+_stateDefault,
  13969.  
  13970. /* Misc */
  13971. "sHeaderTH": _stateDefault,
  13972. "sFooterTH": _stateDefault,
  13973. "sJUIHeader": _headerFooter+" ui-corner-tl ui-corner-tr",
  13974. "sJUIFooter": _headerFooter+" ui-corner-bl ui-corner-br"
  13975. } );
  13976.  
  13977. }());
  13978.  
  13979.  
  13980.  
  13981. var extPagination = DataTable.ext.pager;
  13982.  
  13983. function _numbers ( page, pages ) {
  13984. var
  13985. numbers = [],
  13986. buttons = extPagination.numbers_length,
  13987. half = Math.floor( buttons / 2 ),
  13988. i = 1;
  13989.  
  13990. if ( pages <= buttons ) {
  13991. numbers = _range( 0, pages );
  13992. }
  13993. else if ( page <= half ) {
  13994. numbers = _range( 0, buttons-2 );
  13995. numbers.push( 'ellipsis' );
  13996. numbers.push( pages-1 );
  13997. }
  13998. else if ( page >= pages - 1 - half ) {
  13999. numbers = _range( pages-(buttons-2), pages );
  14000. numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
  14001. numbers.splice( 0, 0, 0 );
  14002. }
  14003. else {
  14004. numbers = _range( page-1, page+2 );
  14005. numbers.push( 'ellipsis' );
  14006. numbers.push( pages-1 );
  14007. numbers.splice( 0, 0, 'ellipsis' );
  14008. numbers.splice( 0, 0, 0 );
  14009. }
  14010.  
  14011. numbers.DT_el = 'span';
  14012. return numbers;
  14013. }
  14014.  
  14015.  
  14016. $.extend( extPagination, {
  14017. simple: function ( page, pages ) {
  14018. return [ 'previous', 'next' ];
  14019. },
  14020.  
  14021. full: function ( page, pages ) {
  14022. return [ 'first', 'previous', 'next', 'last' ];
  14023. },
  14024.  
  14025. simple_numbers: function ( page, pages ) {
  14026. return [ 'previous', _numbers(page, pages), 'next' ];
  14027. },
  14028.  
  14029. full_numbers: function ( page, pages ) {
  14030. return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
  14031. },
  14032.  
  14033. // For testing and plug-ins to use
  14034. _numbers: _numbers,
  14035. numbers_length: 7
  14036. } );
  14037.  
  14038.  
  14039. $.extend( true, DataTable.ext.renderer, {
  14040. pageButton: {
  14041. _: function ( settings, host, idx, buttons, page, pages ) {
  14042. var classes = settings.oClasses;
  14043. var lang = settings.oLanguage.oPaginate;
  14044. var btnDisplay, btnClass, counter=0;
  14045.  
  14046. var attach = function( container, buttons ) {
  14047. var i, ien, node, button;
  14048. var clickHandler = function ( e ) {
  14049. _fnPageChange( settings, e.data.action, true );
  14050. };
  14051.  
  14052. for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
  14053. button = buttons[i];
  14054.  
  14055. if ( $.isArray( button ) ) {
  14056. var inner = $( '<'+(button.DT_el || 'div')+'/>' )
  14057. .appendTo( container );
  14058. attach( inner, button );
  14059. }
  14060. else {
  14061. btnDisplay = '';
  14062. btnClass = '';
  14063.  
  14064. switch ( button ) {
  14065. case 'ellipsis':
  14066. container.append('<span>&hellip;</span>');
  14067. break;
  14068.  
  14069. case 'first':
  14070. btnDisplay = lang.sFirst;
  14071. btnClass = button + (page > 0 ?
  14072. '' : ' '+classes.sPageButtonDisabled);
  14073. break;
  14074.  
  14075. case 'previous':
  14076. btnDisplay = lang.sPrevious;
  14077. btnClass = button + (page > 0 ?
  14078. '' : ' '+classes.sPageButtonDisabled);
  14079. break;
  14080.  
  14081. case 'next':
  14082. btnDisplay = lang.sNext;
  14083. btnClass = button + (page < pages-1 ?
  14084. '' : ' '+classes.sPageButtonDisabled);
  14085. break;
  14086.  
  14087. case 'last':
  14088. btnDisplay = lang.sLast;
  14089. btnClass = button + (page < pages-1 ?
  14090. '' : ' '+classes.sPageButtonDisabled);
  14091. break;
  14092.  
  14093. default:
  14094. btnDisplay = button + 1;
  14095. btnClass = page === button ?
  14096. classes.sPageButtonActive : '';
  14097. break;
  14098. }
  14099.  
  14100. if ( btnDisplay ) {
  14101. node = $('<a>', {
  14102. 'class': classes.sPageButton+' '+btnClass,
  14103. 'aria-controls': settings.sTableId,
  14104. 'data-dt-idx': counter,
  14105. 'tabindex': settings.iTabIndex,
  14106. 'id': idx === 0 && typeof button === 'string' ?
  14107. settings.sTableId +'_'+ button :
  14108. null
  14109. } )
  14110. .html( btnDisplay )
  14111. .appendTo( container );
  14112.  
  14113. _fnBindAction(
  14114. node, {action: button}, clickHandler
  14115. );
  14116.  
  14117. counter++;
  14118. }
  14119. }
  14120. }
  14121. };
  14122.  
  14123. // IE9 throws an 'unknown error' if document.activeElement is used
  14124. // inside an iframe or frame. Try / catch the error. Not good for
  14125. // accessibility, but neither are frames.
  14126. try {
  14127. // Because this approach is destroying and recreating the paging
  14128. // elements, focus is lost on the select button which is bad for
  14129. // accessibility. So we want to restore focus once the draw has
  14130. // completed
  14131. var activeEl = $(document.activeElement).data('dt-idx');
  14132.  
  14133. attach( $(host).empty(), buttons );
  14134.  
  14135. if ( activeEl !== null ) {
  14136. $(host).find( '[data-dt-idx='+activeEl+']' ).focus();
  14137. }
  14138. }
  14139. catch (e) {}
  14140. }
  14141. }
  14142. } );
  14143.  
  14144.  
  14145.  
  14146. // Built in type detection. See model.ext.aTypes for information about
  14147. // what is required from this methods.
  14148. $.extend( DataTable.ext.type.detect, [
  14149. // Plain numbers - first since V8 detects some plain numbers as dates
  14150. // e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
  14151. function ( d, settings )
  14152. {
  14153. var decimal = settings.oLanguage.sDecimal;
  14154. return _isNumber( d, decimal ) ? 'num'+decimal : null;
  14155. },
  14156.  
  14157. // Dates (only those recognised by the browser's Date.parse)
  14158. function ( d, settings )
  14159. {
  14160. // V8 will remove any unknown characters at the start and end of the
  14161. // expression, leading to false matches such as `$245.12` or `10%` being
  14162. // a valid date. See forum thread 18941 for detail.
  14163. if ( d && !(d instanceof Date) && ( ! _re_date_start.test(d) || ! _re_date_end.test(d) ) ) {
  14164. return null;
  14165. }
  14166. var parsed = Date.parse(d);
  14167. return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
  14168. },
  14169.  
  14170. // Formatted numbers
  14171. function ( d, settings )
  14172. {
  14173. var decimal = settings.oLanguage.sDecimal;
  14174. return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;
  14175. },
  14176.  
  14177. // HTML numeric
  14178. function ( d, settings )
  14179. {
  14180. var decimal = settings.oLanguage.sDecimal;
  14181. return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;
  14182. },
  14183.  
  14184. // HTML numeric, formatted
  14185. function ( d, settings )
  14186. {
  14187. var decimal = settings.oLanguage.sDecimal;
  14188. return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;
  14189. },
  14190.  
  14191. // HTML (this is strict checking - there must be html)
  14192. function ( d, settings )
  14193. {
  14194. return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
  14195. 'html' : null;
  14196. }
  14197. ] );
  14198.  
  14199.  
  14200.  
  14201. // Filter formatting functions. See model.ext.ofnSearch for information about
  14202. // what is required from these methods.
  14203. //
  14204. // Note that additional search methods are added for the html numbers and
  14205. // html formatted numbers by `_addNumericSort()` when we know what the decimal
  14206. // place is
  14207.  
  14208.  
  14209. $.extend( DataTable.ext.type.search, {
  14210. html: function ( data ) {
  14211. return _empty(data) ?
  14212. data :
  14213. typeof data === 'string' ?
  14214. data
  14215. .replace( _re_new_lines, " " )
  14216. .replace( _re_html, "" ) :
  14217. '';
  14218. },
  14219.  
  14220. string: function ( data ) {
  14221. return _empty(data) ?
  14222. data :
  14223. typeof data === 'string' ?
  14224. data.replace( _re_new_lines, " " ) :
  14225. data;
  14226. }
  14227. } );
  14228.  
  14229.  
  14230.  
  14231. var __numericReplace = function ( d, decimalPlace, re1, re2 ) {
  14232. if ( d !== 0 && (!d || d === '-') ) {
  14233. return -Infinity;
  14234. }
  14235.  
  14236. // If a decimal place other than `.` is used, it needs to be given to the
  14237. // function so we can detect it and replace with a `.` which is the only
  14238. // decimal place Javascript recognises - it is not locale aware.
  14239. if ( decimalPlace ) {
  14240. d = _numToDecimal( d, decimalPlace );
  14241. }
  14242.  
  14243. if ( d.replace ) {
  14244. if ( re1 ) {
  14245. d = d.replace( re1, '' );
  14246. }
  14247.  
  14248. if ( re2 ) {
  14249. d = d.replace( re2, '' );
  14250. }
  14251. }
  14252.  
  14253. return d * 1;
  14254. };
  14255.  
  14256.  
  14257. // Add the numeric 'deformatting' functions for sorting and search. This is done
  14258. // in a function to provide an easy ability for the language options to add
  14259. // additional methods if a non-period decimal place is used.
  14260. function _addNumericSort ( decimalPlace ) {
  14261. $.each(
  14262. {
  14263. // Plain numbers
  14264. "num": function ( d ) {
  14265. return __numericReplace( d, decimalPlace );
  14266. },
  14267.  
  14268. // Formatted numbers
  14269. "num-fmt": function ( d ) {
  14270. return __numericReplace( d, decimalPlace, _re_formatted_numeric );
  14271. },
  14272.  
  14273. // HTML numeric
  14274. "html-num": function ( d ) {
  14275. return __numericReplace( d, decimalPlace, _re_html );
  14276. },
  14277.  
  14278. // HTML numeric, formatted
  14279. "html-num-fmt": function ( d ) {
  14280. return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );
  14281. }
  14282. },
  14283. function ( key, fn ) {
  14284. // Add the ordering method
  14285. _ext.type.order[ key+decimalPlace+'-pre' ] = fn;
  14286.  
  14287. // For HTML types add a search formatter that will strip the HTML
  14288. if ( key.match(/^html\-/) ) {
  14289. _ext.type.search[ key+decimalPlace ] = _ext.type.search.html;
  14290. }
  14291. }
  14292. );
  14293. }
  14294.  
  14295.  
  14296. // Default sort methods
  14297. $.extend( _ext.type.order, {
  14298. // Dates
  14299. "date-pre": function ( d ) {
  14300. return Date.parse( d ) || 0;
  14301. },
  14302.  
  14303. // html
  14304. "html-pre": function ( a ) {
  14305. return _empty(a) ?
  14306. '' :
  14307. a.replace ?
  14308. a.replace( /<.*?>/g, "" ).toLowerCase() :
  14309. a+'';
  14310. },
  14311.  
  14312. // string
  14313. "string-pre": function ( a ) {
  14314. // This is a little complex, but faster than always calling toString,
  14315. // http://jsperf.com/tostring-v-check
  14316. return _empty(a) ?
  14317. '' :
  14318. typeof a === 'string' ?
  14319. a.toLowerCase() :
  14320. ! a.toString ?
  14321. '' :
  14322. a.toString();
  14323. },
  14324.  
  14325. // string-asc and -desc are retained only for compatibility with the old
  14326. // sort methods
  14327. "string-asc": function ( x, y ) {
  14328. return ((x < y) ? -1 : ((x > y) ? 1 : 0));
  14329. },
  14330.  
  14331. "string-desc": function ( x, y ) {
  14332. return ((x < y) ? 1 : ((x > y) ? -1 : 0));
  14333. }
  14334. } );
  14335.  
  14336.  
  14337. // Numeric sorting types - order doesn't matter here
  14338. _addNumericSort( '' );
  14339.  
  14340.  
  14341. $.extend( true, DataTable.ext.renderer, {
  14342. header: {
  14343. _: function ( settings, cell, column, classes ) {
  14344. // No additional mark-up required
  14345. // Attach a sort listener to update on sort - note that using the
  14346. // `DT` namespace will allow the event to be removed automatically
  14347. // on destroy, while the `dt` namespaced event is the one we are
  14348. // listening for
  14349. $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
  14350. if ( settings !== ctx ) { // need to check this this is the host
  14351. return; // table, not a nested one
  14352. }
  14353.  
  14354. var colIdx = column.idx;
  14355.  
  14356. cell
  14357. .removeClass(
  14358. column.sSortingClass +' '+
  14359. classes.sSortAsc +' '+
  14360. classes.sSortDesc
  14361. )
  14362. .addClass( columns[ colIdx ] == 'asc' ?
  14363. classes.sSortAsc : columns[ colIdx ] == 'desc' ?
  14364. classes.sSortDesc :
  14365. column.sSortingClass
  14366. );
  14367. } );
  14368. },
  14369.  
  14370. jqueryui: function ( settings, cell, column, classes ) {
  14371. $('<div/>')
  14372. .addClass( classes.sSortJUIWrapper )
  14373. .append( cell.contents() )
  14374. .append( $('<span/>')
  14375. .addClass( classes.sSortIcon+' '+column.sSortingClassJUI )
  14376. )
  14377. .appendTo( cell );
  14378.  
  14379. // Attach a sort listener to update on sort
  14380. $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
  14381. if ( settings !== ctx ) {
  14382. return;
  14383. }
  14384.  
  14385. var colIdx = column.idx;
  14386.  
  14387. cell
  14388. .removeClass( classes.sSortAsc +" "+classes.sSortDesc )
  14389. .addClass( columns[ colIdx ] == 'asc' ?
  14390. classes.sSortAsc : columns[ colIdx ] == 'desc' ?
  14391. classes.sSortDesc :
  14392. column.sSortingClass
  14393. );
  14394.  
  14395. cell
  14396. .find( 'span.'+classes.sSortIcon )
  14397. .removeClass(
  14398. classes.sSortJUIAsc +" "+
  14399. classes.sSortJUIDesc +" "+
  14400. classes.sSortJUI +" "+
  14401. classes.sSortJUIAscAllowed +" "+
  14402. classes.sSortJUIDescAllowed
  14403. )
  14404. .addClass( columns[ colIdx ] == 'asc' ?
  14405. classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
  14406. classes.sSortJUIDesc :
  14407. column.sSortingClassJUI
  14408. );
  14409. } );
  14410. }
  14411. }
  14412. } );
  14413.  
  14414. /*
  14415. * Public helper functions. These aren't used internally by DataTables, or
  14416. * called by any of the options passed into DataTables, but they can be used
  14417. * externally by developers working with DataTables. They are helper functions
  14418. * to make working with DataTables a little bit easier.
  14419. */
  14420.  
  14421. /**
  14422. * Helpers for `columns.render`.
  14423. *
  14424. * The options defined here can be used with the `columns.render` initialisation
  14425. * option to provide a display renderer. The following functions are defined:
  14426. *
  14427. * * `number` - Will format numeric data (defined by `columns.data`) for
  14428. * display, retaining the original unformatted data for sorting and filtering.
  14429. * It takes 4 parameters:
  14430. * * `string` - Thousands grouping separator
  14431. * * `string` - Decimal point indicator
  14432. * * `integer` - Number of decimal points to show
  14433. * * `string` (optional) - Prefix.
  14434. *
  14435. * @example
  14436. * // Column definition using the number renderer
  14437. * {
  14438. * data: "salary",
  14439. * render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
  14440. * }
  14441. *
  14442. * @namespace
  14443. */
  14444. DataTable.render = {
  14445. number: function ( thousands, decimal, precision, prefix ) {
  14446. return {
  14447. display: function ( d ) {
  14448. var negative = d < 0 ? '-' : '';
  14449. d = Math.abs( parseFloat( d ) );
  14450.  
  14451. var intPart = parseInt( d, 10 );
  14452. var floatPart = precision ?
  14453. decimal+(d - intPart).toFixed( precision ).substring( 2 ):
  14454. '';
  14455.  
  14456. return negative + (prefix||'') +
  14457. intPart.toString().replace(
  14458. /\B(?=(\d{3})+(?!\d))/g, thousands
  14459. ) +
  14460. floatPart;
  14461. }
  14462. };
  14463. }
  14464. };
  14465.  
  14466.  
  14467. /*
  14468. * This is really a good bit rubbish this method of exposing the internal methods
  14469. * publicly... - To be fixed in 2.0 using methods on the prototype
  14470. */
  14471.  
  14472.  
  14473. /**
  14474. * Create a wrapper function for exporting an internal functions to an external API.
  14475. * @param {string} fn API function name
  14476. * @returns {function} wrapped function
  14477. * @memberof DataTable#internal
  14478. */
  14479. function _fnExternApiFunc (fn)
  14480. {
  14481. return function() {
  14482. var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(
  14483. Array.prototype.slice.call(arguments)
  14484. );
  14485. return DataTable.ext.internal[fn].apply( this, args );
  14486. };
  14487. }
  14488.  
  14489.  
  14490. /**
  14491. * Reference to internal functions for use by plug-in developers. Note that
  14492. * these methods are references to internal functions and are considered to be
  14493. * private. If you use these methods, be aware that they are liable to change
  14494. * between versions.
  14495. * @namespace
  14496. */
  14497. $.extend( DataTable.ext.internal, {
  14498. _fnExternApiFunc: _fnExternApiFunc,
  14499. _fnBuildAjax: _fnBuildAjax,
  14500. _fnAjaxUpdate: _fnAjaxUpdate,
  14501. _fnAjaxParameters: _fnAjaxParameters,
  14502. _fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
  14503. _fnAjaxDataSrc: _fnAjaxDataSrc,
  14504. _fnAddColumn: _fnAddColumn,
  14505. _fnColumnOptions: _fnColumnOptions,
  14506. _fnAdjustColumnSizing: _fnAdjustColumnSizing,
  14507. _fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
  14508. _fnColumnIndexToVisible: _fnColumnIndexToVisible,
  14509. _fnVisbleColumns: _fnVisbleColumns,
  14510. _fnGetColumns: _fnGetColumns,
  14511. _fnColumnTypes: _fnColumnTypes,
  14512. _fnApplyColumnDefs: _fnApplyColumnDefs,
  14513. _fnHungarianMap: _fnHungarianMap,
  14514. _fnCamelToHungarian: _fnCamelToHungarian,
  14515. _fnLanguageCompat: _fnLanguageCompat,
  14516. _fnBrowserDetect: _fnBrowserDetect,
  14517. _fnAddData: _fnAddData,
  14518. _fnAddTr: _fnAddTr,
  14519. _fnNodeToDataIndex: _fnNodeToDataIndex,
  14520. _fnNodeToColumnIndex: _fnNodeToColumnIndex,
  14521. _fnGetCellData: _fnGetCellData,
  14522. _fnSetCellData: _fnSetCellData,
  14523. _fnSplitObjNotation: _fnSplitObjNotation,
  14524. _fnGetObjectDataFn: _fnGetObjectDataFn,
  14525. _fnSetObjectDataFn: _fnSetObjectDataFn,
  14526. _fnGetDataMaster: _fnGetDataMaster,
  14527. _fnClearTable: _fnClearTable,
  14528. _fnDeleteIndex: _fnDeleteIndex,
  14529. _fnInvalidate: _fnInvalidate,
  14530. _fnGetRowElements: _fnGetRowElements,
  14531. _fnCreateTr: _fnCreateTr,
  14532. _fnBuildHead: _fnBuildHead,
  14533. _fnDrawHead: _fnDrawHead,
  14534. _fnDraw: _fnDraw,
  14535. _fnReDraw: _fnReDraw,
  14536. _fnAddOptionsHtml: _fnAddOptionsHtml,
  14537. _fnDetectHeader: _fnDetectHeader,
  14538. _fnGetUniqueThs: _fnGetUniqueThs,
  14539. _fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
  14540. _fnFilterComplete: _fnFilterComplete,
  14541. _fnFilterCustom: _fnFilterCustom,
  14542. _fnFilterColumn: _fnFilterColumn,
  14543. _fnFilter: _fnFilter,
  14544. _fnFilterCreateSearch: _fnFilterCreateSearch,
  14545. _fnEscapeRegex: _fnEscapeRegex,
  14546. _fnFilterData: _fnFilterData,
  14547. _fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
  14548. _fnUpdateInfo: _fnUpdateInfo,
  14549. _fnInfoMacros: _fnInfoMacros,
  14550. _fnInitialise: _fnInitialise,
  14551. _fnInitComplete: _fnInitComplete,
  14552. _fnLengthChange: _fnLengthChange,
  14553. _fnFeatureHtmlLength: _fnFeatureHtmlLength,
  14554. _fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
  14555. _fnPageChange: _fnPageChange,
  14556. _fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
  14557. _fnProcessingDisplay: _fnProcessingDisplay,
  14558. _fnFeatureHtmlTable: _fnFeatureHtmlTable,
  14559. _fnScrollDraw: _fnScrollDraw,
  14560. _fnApplyToChildren: _fnApplyToChildren,
  14561. _fnCalculateColumnWidths: _fnCalculateColumnWidths,
  14562. _fnThrottle: _fnThrottle,
  14563. _fnConvertToWidth: _fnConvertToWidth,
  14564. _fnScrollingWidthAdjust: _fnScrollingWidthAdjust,
  14565. _fnGetWidestNode: _fnGetWidestNode,
  14566. _fnGetMaxLenString: _fnGetMaxLenString,
  14567. _fnStringToCss: _fnStringToCss,
  14568. _fnScrollBarWidth: _fnScrollBarWidth,
  14569. _fnSortFlatten: _fnSortFlatten,
  14570. _fnSort: _fnSort,
  14571. _fnSortAria: _fnSortAria,
  14572. _fnSortListener: _fnSortListener,
  14573. _fnSortAttachListener: _fnSortAttachListener,
  14574. _fnSortingClasses: _fnSortingClasses,
  14575. _fnSortData: _fnSortData,
  14576. _fnSaveState: _fnSaveState,
  14577. _fnLoadState: _fnLoadState,
  14578. _fnSettingsFromNode: _fnSettingsFromNode,
  14579. _fnLog: _fnLog,
  14580. _fnMap: _fnMap,
  14581. _fnBindAction: _fnBindAction,
  14582. _fnCallbackReg: _fnCallbackReg,
  14583. _fnCallbackFire: _fnCallbackFire,
  14584. _fnLengthOverflow: _fnLengthOverflow,
  14585. _fnRenderer: _fnRenderer,
  14586. _fnDataSource: _fnDataSource,
  14587. _fnRowAttributes: _fnRowAttributes,
  14588. _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
  14589. // in 1.10, so this dead-end function is
  14590. // added to prevent errors
  14591. } );
  14592.  
  14593.  
  14594. // jQuery access
  14595. $.fn.dataTable = DataTable;
  14596.  
  14597. // Legacy aliases
  14598. $.fn.dataTableSettings = DataTable.settings;
  14599. $.fn.dataTableExt = DataTable.ext;
  14600.  
  14601. // With a capital `D` we return a DataTables API instance rather than a
  14602. // jQuery object
  14603. $.fn.DataTable = function ( opts ) {
  14604. return $(this).dataTable( opts ).api();
  14605. };
  14606.  
  14607. // All properties that are available to $.fn.dataTable should also be
  14608. // available on $.fn.DataTable
  14609. $.each( DataTable, function ( prop, val ) {
  14610. $.fn.DataTable[ prop ] = val;
  14611. } );
  14612.  
  14613.  
  14614. // Information about events fired by DataTables - for documentation.
  14615. /**
  14616. * Draw event, fired whenever the table is redrawn on the page, at the same
  14617. * point as fnDrawCallback. This may be useful for binding events or
  14618. * performing calculations when the table is altered at all.
  14619. * @name DataTable#draw.dt
  14620. * @event
  14621. * @param {event} e jQuery event object
  14622. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  14623. */
  14624.  
  14625. /**
  14626. * Search event, fired when the searching applied to the table (using the
  14627. * built-in global search, or column filters) is altered.
  14628. * @name DataTable#search.dt
  14629. * @event
  14630. * @param {event} e jQuery event object
  14631. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  14632. */
  14633.  
  14634. /**
  14635. * Page change event, fired when the paging of the table is altered.
  14636. * @name DataTable#page.dt
  14637. * @event
  14638. * @param {event} e jQuery event object
  14639. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  14640. */
  14641.  
  14642. /**
  14643. * Order event, fired when the ordering applied to the table is altered.
  14644. * @name DataTable#order.dt
  14645. * @event
  14646. * @param {event} e jQuery event object
  14647. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  14648. */
  14649.  
  14650. /**
  14651. * DataTables initialisation complete event, fired when the table is fully
  14652. * drawn, including Ajax data loaded, if Ajax data is required.
  14653. * @name DataTable#init.dt
  14654. * @event
  14655. * @param {event} e jQuery event object
  14656. * @param {object} oSettings DataTables settings object
  14657. * @param {object} json The JSON object request from the server - only
  14658. * present if client-side Ajax sourced data is used</li></ol>
  14659. */
  14660.  
  14661. /**
  14662. * State save event, fired when the table has changed state a new state save
  14663. * is required. This event allows modification of the state saving object
  14664. * prior to actually doing the save, including addition or other state
  14665. * properties (for plug-ins) or modification of a DataTables core property.
  14666. * @name DataTable#stateSaveParams.dt
  14667. * @event
  14668. * @param {event} e jQuery event object
  14669. * @param {object} oSettings DataTables settings object
  14670. * @param {object} json The state information to be saved
  14671. */
  14672.  
  14673. /**
  14674. * State load event, fired when the table is loading state from the stored
  14675. * data, but prior to the settings object being modified by the saved state
  14676. * - allowing modification of the saved state is required or loading of
  14677. * state for a plug-in.
  14678. * @name DataTable#stateLoadParams.dt
  14679. * @event
  14680. * @param {event} e jQuery event object
  14681. * @param {object} oSettings DataTables settings object
  14682. * @param {object} json The saved state information
  14683. */
  14684.  
  14685. /**
  14686. * State loaded event, fired when state has been loaded from stored data and
  14687. * the settings object has been modified by the loaded data.
  14688. * @name DataTable#stateLoaded.dt
  14689. * @event
  14690. * @param {event} e jQuery event object
  14691. * @param {object} oSettings DataTables settings object
  14692. * @param {object} json The saved state information
  14693. */
  14694.  
  14695. /**
  14696. * Processing event, fired when DataTables is doing some kind of processing
  14697. * (be it, order, searcg or anything else). It can be used to indicate to
  14698. * the end user that there is something happening, or that something has
  14699. * finished.
  14700. * @name DataTable#processing.dt
  14701. * @event
  14702. * @param {event} e jQuery event object
  14703. * @param {object} oSettings DataTables settings object
  14704. * @param {boolean} bShow Flag for if DataTables is doing processing or not
  14705. */
  14706.  
  14707. /**
  14708. * Ajax (XHR) event, fired whenever an Ajax request is completed from a
  14709. * request to made to the server for new data. This event is called before
  14710. * DataTables processed the returned data, so it can also be used to pre-
  14711. * process the data returned from the server, if needed.
  14712. *
  14713. * Note that this trigger is called in `fnServerData`, if you override
  14714. * `fnServerData` and which to use this event, you need to trigger it in you
  14715. * success function.
  14716. * @name DataTable#xhr.dt
  14717. * @event
  14718. * @param {event} e jQuery event object
  14719. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  14720. * @param {object} json JSON returned from the server
  14721. *
  14722. * @example
  14723. * // Use a custom property returned from the server in another DOM element
  14724. * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
  14725. * $('#status').html( json.status );
  14726. * } );
  14727. *
  14728. * @example
  14729. * // Pre-process the data returned from the server
  14730. * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
  14731. * for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
  14732. * json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
  14733. * }
  14734. * // Note no return - manipulate the data directly in the JSON object.
  14735. * } );
  14736. */
  14737.  
  14738. /**
  14739. * Destroy event, fired when the DataTable is destroyed by calling fnDestroy
  14740. * or passing the bDestroy:true parameter in the initialisation object. This
  14741. * can be used to remove bound events, added DOM nodes, etc.
  14742. * @name DataTable#destroy.dt
  14743. * @event
  14744. * @param {event} e jQuery event object
  14745. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  14746. */
  14747.  
  14748. /**
  14749. * Page length change event, fired when number of records to show on each
  14750. * page (the length) is changed.
  14751. * @name DataTable#length.dt
  14752. * @event
  14753. * @param {event} e jQuery event object
  14754. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  14755. * @param {integer} len New length
  14756. */
  14757.  
  14758. /**
  14759. * Column sizing has changed.
  14760. * @name DataTable#column-sizing.dt
  14761. * @event
  14762. * @param {event} e jQuery event object
  14763. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  14764. */
  14765.  
  14766. /**
  14767. * Column visibility has changed.
  14768. * @name DataTable#column-visibility.dt
  14769. * @event
  14770. * @param {event} e jQuery event object
  14771. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  14772. * @param {int} column Column index
  14773. * @param {bool} vis `false` if column now hidden, or `true` if visible
  14774. */
  14775.  
  14776. return $.fn.dataTable;
  14777. }));
  14778.  
  14779. }(window, document));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement