UNPKG

amazeui-datatables

Version:

jQuery DataTables 插件 Amaze UI 集成

1,514 lines (1,344 loc) 455 kB
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ (function (global){ /*! DataTables Amaze UI 2.x integration v0.0.6 dt@1.10.11 */ /** * DataTables integration for Amaze UI 2.x. This requires Amaze UI 2.x and * DataTables 1.10 or newer. */ 'use strict'; var $ = (typeof window !== "undefined" ? window['jQuery'] : typeof global !== "undefined" ? global['jQuery'] : null); // @see https://www.datatables.net/download/npm var DataTable = _dereq_('datatables')(); // language // https://github.com/DataTables/Plugins/blob/master/i18n/Chinese.lang DataTable.defaults.oLanguage = { sProcessing: "处理中...", sLengthMenu: "显示 _MENU_ 项结果", sZeroRecords: "没有匹配结果", sInfo: "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项", sInfoEmpty: "显示第 0 至 0 项结果,共 0 项", sInfoFiltered: "(由 _MAX_ 项结果过滤)", sInfoPostFix: "", sSearch: "搜索:", sUrl: "", sEmptyTable: "表中数据为空", sLoadingRecords: "载入中...", // old, obsolete, using sThousands instead sInfoThousands: ",", sThousands: ",", oPaginate: { sFirst: "首页", sPrevious: "上页", sNext: "下页", sLast: "末页" }, oAria: { sSortAscending: ": 以升序排列此列", sSortDescending: ": 以降序排列此列" } }; // Set the defaults for DataTables initialisation // https://datatables.net/reference/option/dom $.extend(true, DataTable.defaults, { dom: "<'am-g am-datatable-hd'<'am-u-sm-6'l><'am-u-sm-6'f>>" + "<'am-g'<'am-u-sm-12'tr>>" + "<'am-g am-datatable-footer'<'am-u-sm-5'i><'am-u-sm-7'p>>", renderer: 'amazeui' }); /* Default class modification */ $.extend(DataTable.ext.classes, { /* Features */ sWrapper: 'dataTables_wrapper am-datatable am-form-inline dt-amazeui', sFilter: 'dataTables_filter am-datatable-filter', sFilterInput: 'am-form-field am-input-sm', sInfo: 'dataTables_info am-datatable-info', sPaging: 'dataTables_paginate paging_', /* Note that the type is postfixed */ sLength: 'dataTables_length am-form-group am-datatable-length', sLengthSelect: 'am-form-select am-input-sm', sProcessing: "dataTables_processing", /* Sorting */ sSortAsc: "sorting_asc", sSortDesc: "sorting_desc", sSortable: "sorting", /* Sortable in both directions */ sSortableAsc: "sorting_asc_disabled", sSortableDesc: "sorting_desc_disabled", sSortableNone: "sorting_disabled", sSortColumn: "sorting_" /* Note that an int is postfixed for the sorting order */ }); /* Amaze UI paging button renderer */ DataTable.ext.renderer.pageButton.amazeui = function(settings, host, idx, buttons, page, pages) { var api = new DataTable.Api(settings); var classes = settings.oClasses; var lang = settings.oLanguage.oPaginate; var btnDisplay, btnClass, counter = 0; var attach = function(container, buttons) { var i, ien, node, button; var clickHandler = function(e) { e.preventDefault(); if (!$(e.currentTarget).hasClass('am-disabled')) { api.page(e.data.action).draw(false); } }; for (i = 0, ien = buttons.length; i < ien; i++) { button = buttons[i]; if ($.isArray(button)) { attach(container, button); } else { btnDisplay = ''; btnClass = ''; switch (button) { case 'ellipsis': btnDisplay = '&hellip;'; btnClass = 'am-disabled'; break; case 'first': btnDisplay = lang.sFirst; btnClass = button + (page > 0 ? '' : ' am-disabled'); break; case 'previous': btnDisplay = lang.sPrevious; btnClass = button + (page > 0 ? '' : ' am-disabled'); break; case 'next': btnDisplay = lang.sNext; btnClass = button + (page < pages - 1 ? '' : ' am-disabled'); break; case 'last': btnDisplay = lang.sLast; btnClass = button + (page < pages - 1 ? '' : ' am-disabled'); break; default: btnDisplay = button + 1; btnClass = page === button ? 'am-active' : ''; break; } if (btnDisplay) { node = $('<li>', { 'class': classes.sPageButton + ' ' + btnClass, 'id': idx === 0 && typeof button === 'string' ? settings.sTableId + '_' + button : null }) .append($('<a>', { 'href': '#', 'aria-controls': settings.sTableId, 'data-dt-idx': counter, 'tabindex': settings.iTabIndex }) .html(btnDisplay) ) .appendTo(container); settings.oApi._fnBindAction( node, {action: button}, clickHandler ); counter++; } } } }; // IE9 throws an 'unknown error' if document.activeElement is used // inside an iframe or frame. var activeEl; try { // Because this approach is destroying and recreating the paging // elements, focus is lost on the select button which is bad for // accessibility. So we want to restore focus once the draw has // completed activeEl = $(document.activeElement).data('dt-idx'); } catch (e) { } attach( $(host).empty(). html('<ul class="am-datatable-pager am-pagination am-pagination-right am-text-sm"/>'). children('ul'), buttons ); if (activeEl) { $(host).find('[data-dt-idx=' + activeEl + ']').focus(); } }; /* * TableTools Amaze UI compatibility * Required TableTools 2.1+ */ if (DataTable.TableTools) { // Set the classes that TableTools uses to something suitable for Bootstrap $.extend(true, DataTable.TableTools.classes, { container: "DTTT am-btn-group", buttons: { normal: "am-btn am-btn-default", disabled: "am-disabled" }, collection: { container: "DTTT_dropdown dropdown-menu", buttons: { normal: "", disabled: "am-disabled" } }, print: { info: "DTTT_print_info" }, select: { row: "am-active" } }); // Have the collection use a bootstrap compatible drop down $.extend(true, DataTable.TableTools.DEFAULTS.oTags, { collection: { container: "ul", button: "li", liner: "a" } }); } module.exports = DataTable; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"datatables":2}],2:[function(_dereq_,module,exports){ (function (global){ /*! DataTables 1.10.12 * ©2008-2015 SpryMedia Ltd - datatables.net/license */ /** * @summary DataTables * @description Paginate, search and order HTML tables * @version 1.10.12 * @file jquery.dataTables.js * @author SpryMedia Ltd (www.sprymedia.co.uk) * @contact www.sprymedia.co.uk/contact * @copyright Copyright 2008-2015 SpryMedia Ltd. * * This source file is free software, available under the following license: * MIT license - http://datatables.net/license * * This source file is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. * * For details please refer to: http://www.datatables.net */ /*jslint evil: true, undef: true, browser: true */ /*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,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/ (function( factory ) { "use strict"; if ( typeof define === 'function' && define.amd ) { // AMD define( ['jquery'], function ( $ ) { return factory( $, window, document ); } ); } else if ( typeof exports === 'object' ) { // CommonJS module.exports = function (root, $) { if ( ! root ) { // CommonJS environments without a window global must pass a // root. This will give an error otherwise root = window; } if ( ! $ ) { $ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window (typeof window !== "undefined" ? window['jQuery'] : typeof global !== "undefined" ? global['jQuery'] : null) : (typeof window !== "undefined" ? window['jQuery'] : typeof global !== "undefined" ? global['jQuery'] : null)( root ); } return factory( $, root, root.document ); }; } else { // Browser factory( jQuery, window, document ); } } (function( $, window, document, undefined ) { "use strict"; /** * DataTables is a plug-in for the jQuery Javascript library. It is a highly * flexible tool, based upon the foundations of progressive enhancement, * which will add advanced interaction controls to any HTML table. For a * full list of features please refer to * [DataTables.net](href="http://datatables.net). * * Note that the `DataTable` object is not a global variable but is aliased * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may * be accessed. * * @class * @param {object} [init={}] Configuration object for DataTables. Options * are defined by {@link DataTable.defaults} * @requires jQuery 1.7+ * * @example * // Basic initialisation * $(document).ready( function { * $('#example').dataTable(); * } ); * * @example * // Initialisation with configuration options - in this case, disable * // pagination and sorting. * $(document).ready( function { * $('#example').dataTable( { * "paginate": false, * "sort": false * } ); * } ); */ var DataTable = function ( options ) { /** * Perform a jQuery selector action on the table's TR elements (from the tbody) and * return the resulting jQuery object. * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on * @param {object} [oOpts] Optional parameters for modifying the rows to be included * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter * criterion ("applied") or all TR elements (i.e. no filter). * @param {string} [oOpts.order=current] Order of the TR elements in the processed array. * Can be either 'current', whereby the current sorting of the table is used, or * 'original' whereby the original order the data was read into the table is used. * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page * ("current") or not ("all"). If 'current' is given, then order is assumed to be * 'current' and filter is 'applied', regardless of what they might be given as. * @returns {object} jQuery object, filtered by the given selector. * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * * // Highlight every second row * oTable.$('tr:odd').css('backgroundColor', 'blue'); * } ); * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * * // Filter to rows with 'Webkit' in them, add a background colour and then * // remove the filter, thus highlighting the 'Webkit' rows only. * oTable.fnFilter('Webkit'); * oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue'); * oTable.fnFilter(''); * } ); */ this.$ = function ( sSelector, oOpts ) { return this.api(true).$( sSelector, oOpts ); }; /** * Almost identical to $ in operation, but in this case returns the data for the matched * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes * rather than any descendants, so the data can be obtained for the row/cell. If matching * rows are found, the data returned is the original data array/object that was used to * create the row (or a generated array if from a DOM source). * * This method is often useful in-combination with $ where both functions are given the * same parameters and the array indexes will match identically. * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on * @param {object} [oOpts] Optional parameters for modifying the rows to be included * @param {string} [oOpts.filter=none] Select elements that meet the current filter * criterion ("applied") or all elements (i.e. no filter). * @param {string} [oOpts.order=current] Order of the data in the processed array. * Can be either 'current', whereby the current sorting of the table is used, or * 'original' whereby the original order the data was read into the table is used. * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page * ("current") or not ("all"). If 'current' is given, then order is assumed to be * 'current' and filter is 'applied', regardless of what they might be given as. * @returns {array} Data for the matched elements. If any elements, as a result of the * selector, were not TR, TD or TH elements in the DataTable, they will have a null * entry in the array. * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * * // Get the data from the first row in the table * var data = oTable._('tr:first'); * * // Do something useful with the data * alert( "First cell is: "+data[0] ); * } ); * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * * // Filter to 'Webkit' and get all data for * oTable.fnFilter('Webkit'); * var data = oTable._('tr', {"search": "applied"}); * * // Do something with the data * alert( data.length+" rows matched the search" ); * } ); */ this._ = function ( sSelector, oOpts ) { return this.api(true).rows( sSelector, oOpts ).data(); }; /** * Create a DataTables Api instance, with the currently selected tables for * the Api's context. * @param {boolean} [traditional=false] Set the API instance's context to be * only the table referred to by the `DataTable.ext.iApiIndex` option, as was * used in the API presented by DataTables 1.9- (i.e. the traditional mode), * or if all tables captured in the jQuery object should be used. * @return {DataTables.Api} */ this.api = function ( traditional ) { return traditional ? new _Api( _fnSettingsFromNode( this[ _ext.iApiIndex ] ) ) : new _Api( this ); }; /** * Add a single new row or multiple rows of data to the table. Please note * that this is suitable for client-side processing only - if you are using * server-side processing (i.e. "bServerSide": true), then to add data, you * must add it to the data source, i.e. the server-side, through an Ajax call. * @param {array|object} data The data to be added to the table. This can be: * <ul> * <li>1D array of data - add a single row with the data provided</li> * <li>2D array of arrays - add multiple rows in a single call</li> * <li>object - data object when using <i>mData</i></li> * <li>array of objects - multiple data objects when using <i>mData</i></li> * </ul> * @param {bool} [redraw=true] redraw the table or not * @returns {array} An array of integers, representing the list of indexes in * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to * the table. * @dtopt API * @deprecated Since v1.10 * * @example * // Global var for counter * var giCount = 2; * * $(document).ready(function() { * $('#example').dataTable(); * } ); * * function fnClickAddRow() { * $('#example').dataTable().fnAddData( [ * giCount+".1", * giCount+".2", * giCount+".3", * giCount+".4" ] * ); * * giCount++; * } */ this.fnAddData = function( data, redraw ) { var api = this.api( true ); /* Check if we want to add multiple rows or not */ var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ? api.rows.add( data ) : api.row.add( data ); if ( redraw === undefined || redraw ) { api.draw(); } return rows.flatten().toArray(); }; /** * This function will make DataTables recalculate the column sizes, based on the data * contained in the table and the sizes applied to the columns (in the DOM, CSS or * through the sWidth parameter). This can be useful when the width of the table's * parent element changes (for example a window resize). * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable( { * "sScrollY": "200px", * "bPaginate": false * } ); * * $(window).bind('resize', function () { * oTable.fnAdjustColumnSizing(); * } ); * } ); */ this.fnAdjustColumnSizing = function ( bRedraw ) { var api = this.api( true ).columns.adjust(); var settings = api.settings()[0]; var scroll = settings.oScroll; if ( bRedraw === undefined || bRedraw ) { api.draw( false ); } else if ( scroll.sX !== "" || scroll.sY !== "" ) { /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */ _fnScrollDraw( settings ); } }; /** * Quickly and simply clear a table * @param {bool} [bRedraw=true] redraw the table or not * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...) * oTable.fnClearTable(); * } ); */ this.fnClearTable = function( bRedraw ) { var api = this.api( true ).clear(); if ( bRedraw === undefined || bRedraw ) { api.draw(); } }; /** * The exact opposite of 'opening' a row, this function will close any rows which * are currently 'open'. * @param {node} nTr the table row to 'close' * @returns {int} 0 on success, or 1 if failed (can't find the row) * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable; * * // 'open' an information row when a row is clicked on * $('#example tbody tr').click( function () { * if ( oTable.fnIsOpen(this) ) { * oTable.fnClose( this ); * } else { * oTable.fnOpen( this, "Temporary row opened", "info_row" ); * } * } ); * * oTable = $('#example').dataTable(); * } ); */ this.fnClose = function( nTr ) { this.api( true ).row( nTr ).child.hide(); }; /** * Remove a row for the table * @param {mixed} target The index of the row from aoData to be deleted, or * the TR element you want to delete * @param {function|null} [callBack] Callback function * @param {bool} [redraw=true] Redraw the table or not * @returns {array} The row that was deleted * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * * // Immediately remove the first row * oTable.fnDeleteRow( 0 ); * } ); */ this.fnDeleteRow = function( target, callback, redraw ) { var api = this.api( true ); var rows = api.rows( target ); var settings = rows.settings()[0]; var data = settings.aoData[ rows[0][0] ]; rows.remove(); if ( callback ) { callback.call( this, settings, data ); } if ( redraw === undefined || redraw ) { api.draw(); } return data; }; /** * Restore the table to it's original state in the DOM by removing all of DataTables * enhancements, alterations to the DOM structure of the table and event listeners. * @param {boolean} [remove=false] Completely remove the table from the DOM * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * // This example is fairly pointless in reality, but shows how fnDestroy can be used * var oTable = $('#example').dataTable(); * oTable.fnDestroy(); * } ); */ this.fnDestroy = function ( remove ) { this.api( true ).destroy( remove ); }; /** * Redraw the table * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw. * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * * // Re-draw the table - you wouldn't want to do it here, but it's an example :-) * oTable.fnDraw(); * } ); */ this.fnDraw = function( complete ) { // Note that this isn't an exact match to the old call to _fnDraw - it takes // into account the new data, but can hold position. this.api( true ).draw( complete ); }; /** * Filter the input based on data * @param {string} sInput String to filter the table on * @param {int|null} [iColumn] Column to limit filtering to * @param {bool} [bRegex=false] Treat as regular expression or not * @param {bool} [bSmart=true] Perform smart filtering or not * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es) * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false) * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * * // Sometime later - filter... * oTable.fnFilter( 'test string' ); * } ); */ this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive ) { var api = this.api( true ); if ( iColumn === null || iColumn === undefined ) { api.search( sInput, bRegex, bSmart, bCaseInsensitive ); } else { api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive ); } api.draw(); }; /** * Get the data for the whole table, an individual row or an individual cell based on the * provided parameters. * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as * a TR node then the data source for the whole row will be returned. If given as a * TD/TH cell node then iCol will be automatically calculated and the data for the * cell returned. If given as an integer, then this is treated as the aoData internal * data index for the row (see fnGetPosition) and the data for that row used. * @param {int} [col] Optional column index that you want the data of. * @returns {array|object|string} If mRow is undefined, then the data for all rows is * returned. If mRow is defined, just data for that row, and is iCol is * defined, only data for the designated cell is returned. * @dtopt API * @deprecated Since v1.10 * * @example * // Row data * $(document).ready(function() { * oTable = $('#example').dataTable(); * * oTable.$('tr').click( function () { * var data = oTable.fnGetData( this ); * // ... do something with the array / object of data for the row * } ); * } ); * * @example * // Individual cell data * $(document).ready(function() { * oTable = $('#example').dataTable(); * * oTable.$('td').click( function () { * var sData = oTable.fnGetData( this ); * alert( 'The cell clicked on had the value of '+sData ); * } ); * } ); */ this.fnGetData = function( src, col ) { var api = this.api( true ); if ( src !== undefined ) { var type = src.nodeName ? src.nodeName.toLowerCase() : ''; return col !== undefined || type == 'td' || type == 'th' ? api.cell( src, col ).data() : api.row( src ).data() || null; } return api.data().toArray(); }; /** * Get an array of the TR nodes that are used in the table's body. Note that you will * typically want to use the '$' API method in preference to this as it is more * flexible. * @param {int} [iRow] Optional row index for the TR element you want * @returns {array|node} If iRow is undefined, returns an array of all TR elements * in the table's body, or iRow is defined, just the TR element requested. * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * * // Get the nodes from the table * var nNodes = oTable.fnGetNodes( ); * } ); */ this.fnGetNodes = function( iRow ) { var api = this.api( true ); return iRow !== undefined ? api.row( iRow ).node() : api.rows().nodes().flatten().toArray(); }; /** * Get the array indexes of a particular cell from it's DOM element * and column index including hidden columns * @param {node} node this can either be a TR, TD or TH in the table's body * @returns {int} If nNode is given as a TR, then a single index is returned, or * if given as a cell, an array of [row index, column index (visible), * column index (all)] is given. * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * $('#example tbody td').click( function () { * // Get the position of the current data from the node * var aPos = oTable.fnGetPosition( this ); * * // Get the data array for this row * var aData = oTable.fnGetData( aPos[0] ); * * // Update the data array and return the value * aData[ aPos[1] ] = 'clicked'; * this.innerHTML = 'clicked'; * } ); * * // Init DataTables * oTable = $('#example').dataTable(); * } ); */ this.fnGetPosition = function( node ) { var api = this.api( true ); var nodeName = node.nodeName.toUpperCase(); if ( nodeName == 'TR' ) { return api.row( node ).index(); } else if ( nodeName == 'TD' || nodeName == 'TH' ) { var cell = api.cell( node ).index(); return [ cell.row, cell.columnVisible, cell.column ]; } return null; }; /** * Check to see if a row is 'open' or not. * @param {node} nTr the table row to check * @returns {boolean} true if the row is currently open, false otherwise * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable; * * // 'open' an information row when a row is clicked on * $('#example tbody tr').click( function () { * if ( oTable.fnIsOpen(this) ) { * oTable.fnClose( this ); * } else { * oTable.fnOpen( this, "Temporary row opened", "info_row" ); * } * } ); * * oTable = $('#example').dataTable(); * } ); */ this.fnIsOpen = function( nTr ) { return this.api( true ).row( nTr ).child.isShown(); }; /** * This function will place a new row directly after a row which is currently * on display on the page, with the HTML contents that is passed into the * function. This can be used, for example, to ask for confirmation that a * particular record should be deleted. * @param {node} nTr The table row to 'open' * @param {string|node|jQuery} mHtml The HTML to put into the row * @param {string} sClass Class to give the new TD cell * @returns {node} The row opened. Note that if the table row passed in as the * first parameter, is not found in the table, this method will silently * return. * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable; * * // 'open' an information row when a row is clicked on * $('#example tbody tr').click( function () { * if ( oTable.fnIsOpen(this) ) { * oTable.fnClose( this ); * } else { * oTable.fnOpen( this, "Temporary row opened", "info_row" ); * } * } ); * * oTable = $('#example').dataTable(); * } ); */ this.fnOpen = function( nTr, mHtml, sClass ) { return this.api( true ) .row( nTr ) .child( mHtml, sClass ) .show() .child()[0]; }; /** * Change the pagination - provides the internal logic for pagination in a simple API * function. With this function you can have a DataTables table go to the next, * previous, first or last pages. * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last" * or page number to jump to (integer), note that page 0 is the first page. * @param {bool} [bRedraw=true] Redraw the table or not * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * oTable.fnPageChange( 'next' ); * } ); */ this.fnPageChange = function ( mAction, bRedraw ) { var api = this.api( true ).page( mAction ); if ( bRedraw === undefined || bRedraw ) { api.draw(false); } }; /** * Show a particular column * @param {int} iCol The column whose display should be changed * @param {bool} bShow Show (true) or hide (false) the column * @param {bool} [bRedraw=true] Redraw the table or not * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * * // Hide the second column after initialisation * oTable.fnSetColumnVis( 1, false ); * } ); */ this.fnSetColumnVis = function ( iCol, bShow, bRedraw ) { var api = this.api( true ).column( iCol ).visible( bShow ); if ( bRedraw === undefined || bRedraw ) { api.columns.adjust().draw(); } }; /** * Get the settings for a particular table for external manipulation * @returns {object} DataTables settings object. See * {@link DataTable.models.oSettings} * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * var oSettings = oTable.fnSettings(); * * // Show an example parameter from the settings * alert( oSettings._iDisplayStart ); * } ); */ this.fnSettings = function() { return _fnSettingsFromNode( this[_ext.iApiIndex] ); }; /** * Sort the table by a particular column * @param {int} iCol the data index to sort on. Note that this will not match the * 'display index' if you have hidden data entries * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * * // Sort immediately with columns 0 and 1 * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] ); * } ); */ this.fnSort = function( aaSort ) { this.api( true ).order( aaSort ).draw(); }; /** * Attach a sort listener to an element for a given column * @param {node} nNode the element to attach the sort listener to * @param {int} iColumn the column that a click on this node will sort on * @param {function} [fnCallback] callback function when sort is run * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * * // Sort on column 1, when 'sorter' is clicked on * oTable.fnSortListener( document.getElementById('sorter'), 1 ); * } ); */ this.fnSortListener = function( nNode, iColumn, fnCallback ) { this.api( true ).order.listener( nNode, iColumn, fnCallback ); }; /** * Update a table cell or row - this method will accept either a single value to * update the cell with, an array of values with one element for each column or * an object in the same format as the original data source. The function is * self-referencing in order to make the multi column updates easier. * @param {object|array|string} mData Data to update the cell/row with * @param {node|int} mRow TR element you want to update or the aoData index * @param {int} [iColumn] The column to update, give as null or undefined to * update a whole row. * @param {bool} [bRedraw=true] Redraw the table or not * @param {bool} [bAction=true] Perform pre-draw actions or not * @returns {int} 0 on success, 1 on error * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row * } ); */ this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction ) { var api = this.api( true ); if ( iColumn === undefined || iColumn === null ) { api.row( mRow ).data( mData ); } else { api.cell( mRow, iColumn ).data( mData ); } if ( bAction === undefined || bAction ) { api.columns.adjust(); } if ( bRedraw === undefined || bRedraw ) { api.draw(); } return 0; }; /** * Provide a common method for plug-ins to check the version of DataTables being used, in order * to ensure compatibility. * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the * formats "X" and "X.Y" are also acceptable. * @returns {boolean} true if this version of DataTables is greater or equal to the required * version, or false if this version of DataTales is not suitable * @method * @dtopt API * @deprecated Since v1.10 * * @example * $(document).ready(function() { * var oTable = $('#example').dataTable(); * alert( oTable.fnVersionCheck( '1.9.0' ) ); * } ); */ this.fnVersionCheck = _ext.fnVersionCheck; var _that = this; var emptyInit = options === undefined; var len = this.length; if ( emptyInit ) { options = {}; } this.oApi = this.internal = _ext.internal; // Extend with old style plug-in API methods for ( var fn in DataTable.ext.internal ) { if ( fn ) { this[fn] = _fnExternApiFunc(fn); } } this.each(function() { // For each initialisation we want to give it a clean initialisation // object that can be bashed around var o = {}; var oInit = len > 1 ? // optimisation for single table case _fnExtend( o, options, true ) : options; /*global oInit,_that,emptyInit*/ var i=0, iLen, j, jLen, k, kLen; var sId = this.getAttribute( 'id' ); var bInitHandedOff = false; var defaults = DataTable.defaults; var $this = $(this); /* Sanity check */ if ( this.nodeName.toLowerCase() != 'table' ) { _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 ); return; } /* Backwards compatibility for the defaults */ _fnCompatOpts( defaults ); _fnCompatCols( defaults.column ); /* Convert the camel-case defaults to Hungarian */ _fnCamelToHungarian( defaults, defaults, true ); _fnCamelToHungarian( defaults.column, defaults.column, true ); /* Setting up the initialisation object */ _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) ); /* Check to see if we are re-initialising a table */ var allSettings = DataTable.settings; for ( i=0, iLen=allSettings.length ; i<iLen ; i++ ) { var s = allSettings[i]; /* Base check on table node */ if ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) ) { var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve; var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy; if ( emptyInit || bRetrieve ) { return s.oInstance; } else if ( bDestroy ) { s.oInstance.fnDestroy(); break; } else { _fnLog( s, 0, 'Cannot reinitialise DataTable', 3 ); return; } } /* If the element we are initialising has the same ID as a table which was previously * initialised, but the table nodes don't match (from before) then we destroy the old * instance by simply deleting it. This is under the assumption that the table has been * destroyed by other methods. Anyone using non-id selectors will need to do this manually */ if ( s.sTableId == this.id ) { allSettings.splice( i, 1 ); break; } } /* Ensure the table has an ID - required for accessibility */ if ( sId === null || sId === "" ) { sId = "DataTables_Table_"+(DataTable.ext._unique++); this.id = sId; } /* Create the settings object for this table and set some of the default parameters */ var oSettings = $.extend( true, {}, DataTable.models.oSettings, { "sDestroyWidth": $this[0].style.width, "sInstance": sId, "sTableId": sId } ); oSettings.nTable = this; oSettings.oApi = _that.internal; oSettings.oInit = oInit; allSettings.push( oSettings ); // Need to add the instance after the instance after the settings object has been added // to the settings array, so we can self reference the table instance if more than one oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable(); // Backwards compatibility, before we apply all the defaults _fnCompatOpts( oInit ); if ( oInit.oLanguage ) { _fnLanguageCompat( oInit.oLanguage ); } // If the length menu is given, but the init display length is not, use the length menu if ( oInit.aLengthMenu && ! oInit.iDisplayLength ) { oInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ? oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0]; } // Apply the defaults and init options to make a single init object will all // options defined from defaults and instance options. oInit = _fnExtend( $.extend( true, {}, defaults ), oInit ); // Map the initialisation options onto the settings object _fnMap( oSettings.oFeatures, oInit, [ "bPaginate", "bLengthChange", "bFilter", "bSort", "bSortMulti", "bInfo", "bProcessing", "bAutoWidth", "bSortClasses", "bServerSide", "bDeferRender" ] ); _fnMap( oSettings, oInit, [ "asStripeClasses", "ajax", "fnServerData", "fnFormatNumber", "sServerMethod", "aaSorting", "aaSortingFixed", "aLengthMenu", "sPaginationType", "sAjaxSource", "sAjaxDataProp", "iStateDuration", "sDom", "bSortCellsTop", "iTabIndex", "fnStateLoadCallback", "fnStateSaveCallback", "renderer", "searchDelay", "rowId", [ "iCookieDuration", "iStateDuration" ], // backwards compat [ "oSearch", "oPreviousSearch" ], [ "aoSearchCols", "aoPreSearchCols" ], [ "iDisplayLength", "_iDisplayLength" ], [ "bJQueryUI", "bJUI" ] ] ); _fnMap( oSettings.oScroll, oInit, [ [ "sScrollX", "sX" ], [ "sScrollXInner", "sXInner" ], [ "sScrollY", "sY" ], [ "bScrollCollapse", "bCollapse" ] ] ); _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" ); /* Callback functions which are array driven */ _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' ); _fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' ); _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' ); _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' ); _fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' ); _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' ); _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' ); _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' ); _fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' ); _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' ); _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' ); oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId ); /* Browser support detection */ _fnBrowserDetect( oSettings ); var oClasses = oSettings.oClasses; // @todo Remove in 1.11 if ( oInit.bJQueryUI ) { /* Use the JUI classes object for display. You could clone the oStdClasses object if * you want to have multiple tables with multiple independent classes */ $.extend( oClasses, DataTable.ext.oJUIClasses, oInit.oClasses ); if ( oInit.sDom === defaults.sDom && defaults.sDom === "lfrtip" ) { /* Set the DOM to use a layout suitable for jQuery UI's theming */ oSettings.sDom = '<"H"lfr>t<"F"ip>'; } if ( ! oSettings.renderer ) { oSettings.renderer = 'jqueryui'; } else if ( $.isPlainObject( oSettings.renderer ) && ! oSettings.renderer.header ) { oSettings.renderer.header = 'jqueryui'; } } else { $.extend( oClasses, DataTable.ext.classes, oInit.oClasses ); } $this.addClass( oClasses.sTable ); if ( oSettings.iInitDisplayStart === undefined ) { /* Display start point, taking into account the save saving */ oSettings.iInitDisplayStart = oInit.iDisplayStart; oSettings._iDisplayStart = oInit.iDisplayStart; } if ( oInit.iDeferLoading !== null ) { oSettings.bDeferLoading = true; var tmp = $.isArray( oInit.iDeferLoading ); oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading; oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading; } /* Language definitions */ var oLanguage = oSettings.oLanguage; $.extend( true, oLanguage, oInit.oLanguage ); if ( oLanguage.sUrl !== "" ) { /* Get the language definitions from a file - because this Ajax call makes the language * get async to the remainder of this function we use bInitHandedOff to indicate that * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor */ $.ajax( { dataType: 'json', url: oLanguage.sUrl, success: function ( json ) { _fnLanguageCompat( json ); _fnCamelToHungarian( defaults.oLanguage, json ); $.extend( true, oLanguage, json ); _fnInitialise( oSettings ); }, error: function () { // Error occurred loading language file, continue on as best we can _fnInitialise( oSettings ); } } ); bInitHandedOff = true; } /* * Stripes */ if ( oInit.asStripeClasses === null ) { oSettings.asStripeClasses =[ oClasses.sStripeOdd, oClasses.sStripeEven ]; } /* Remove row stripe classes if they are already on the table row */ var stripeClasses = oSettings.asStripeClasses; var rowOne = $this.children('tbody').find('tr').eq(0); if ( $.inArray( true, $.map( stripeClasses, function(el, i) { return rowOne.hasClass(el); } ) ) !== -1 ) { $('tbody tr', this).removeClass( stripeClasses.join(' ') ); oSettings.asDestroyStripes = stripeClasses.slice(); } /* * Columns * See if we should load columns automatically or use defined ones */ var anThs = []; var aoColumnsInit; var nThead = this.getElementsByTagName('thead'); if ( nThead.length !== 0 ) { _fnDetectHeader( oSettings.aoHeader, nThead[0] ); anThs = _fnGetUniqueThs( oSettings ); } /* If not given a column array, generate one with nulls */ if ( oInit.aoColumns === null ) { aoColumnsInit = []; for ( i=0, iLen=anThs.length ; i<iLen ; i++ ) { aoColumnsInit.push( null ); } } else { aoColumnsInit = oInit.aoColumns; } /* Add the columns */ for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ ) { _fnAddColumn( oSettings, anThs ? anThs[i] : null ); } /* Apply the column definitions */ _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) { _fnColumnOptions( oSettings, iCol, oDef ); } ); /* HTML5 attribute detection - build an mData object automatically if the * attributes are found */ if ( rowOne.length ) { var a = function ( cell, name ) { return cell.getAttribute( 'data-'+name ) !== null ? name : null; }; $( rowOne[0] ).children('th, td').each( function (i, cell) { var col = oSettings.aoColumns[i]; if ( col.mData === i ) { var sort = a( cell, 'sort' ) || a( cell, 'order' ); var filter = a( cell, 'filter' ) || a( cell, 'search' ); if ( sort !== null || filter !== null ) { col.mData = { _: i+'.display', sort: sort !== null ? i+'.@data-'+sort : undefined, type: sort !== null ? i+'.@data-'+sort : undefined, filter: filter !== null ? i+'.@data-'+filter : undefined }; _fnColumnOptions( oSettings, i ); } } } ); } var features = oSettings.oFeatures; /* Must be done after everything which can be overridden by the state saving! */ if ( oInit.bStateSave ) { features.bStateSave = true; _fnLoadState( oSettings, oInit ); _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' ); } /* * Sorting * @todo For modularisation (1.11) this needs to do into a sort start up handler */ // If aaSorting is not defined, then we use the first indicator in asSorting // in case that has been altered, so the default sort reflects that option if ( oInit.aaSorting === undefined ) { var sorting = oSettings.aaSorting; for ( i=0, iLen=sorting.length ; i<iLen ; i++ ) { sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0]; } } /* Do a first pass on the sorting classes (allows any size changes to be taken into * account, and also will apply sorting disabled classes if disabled */ _fnSortingClasses( oSettings ); if ( features.bSort ) { _fnCallbackReg( oSettings, 'aoDrawCallback', function () { if ( oSettings.bSorted ) { var aSort = _fnSortFlatten( oSettings ); var sortedColumns = {}; $.each( aSort, function (i, val) { sortedColumns[ val.src ] = val.dir; } ); _fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] ); _fnSortAria( oSettings ); } } ); } _fnCallbackReg( oSettings, 'aoDrawCallback', function () { if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) { _fnSortingClasses( oSettings ); } }, 'sc' ); /* * Final init * Cache the header, body and footer as required, creating them if needed */ // Work around for Webkit bug 83867 - store the caption-side before removing from doc var capt