From 1a880b9f4636699cecfebba86e4211f9ba6a8f44 Mon Sep 17 00:00:00 2001 From: Allan Jardine Date: Wed, 19 Jun 2013 17:34:49 +0100 Subject: [PATCH] Dev: All the latest changes now built --- media/js/jquery.dataTables.js | 998 ++++++++++++++++------------------ 1 file changed, 476 insertions(+), 522 deletions(-) diff --git a/media/js/jquery.dataTables.js b/media/js/jquery.dataTables.js index cc3cae4e..4390fd3d 100644 --- a/media/js/jquery.dataTables.js +++ b/media/js/jquery.dataTables.js @@ -308,8 +308,16 @@ } /* Cache the data get and set functions for speed */ + var mDataSrc = oCol.mData; + var mData = _fnGetObjectDataFn( mDataSrc ); var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null; - var mData = _fnGetObjectDataFn( oCol.mData ); + + var attrTest = function( src ) { + return typeof src === 'string' && src.indexOf('@') !== -1; + }; + oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && ( + attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter) + ); oCol.fnGetData = function (oData, sSpecific) { var innerData = mData( oData, sSpecific ); @@ -320,7 +328,7 @@ } return innerData; }; - oCol.fnSetData = _fnSetObjectDataFn( oCol.mData ); + oCol.fnSetData = _fnSetObjectDataFn( mDataSrc ); /* Feature sorting overrides column specific when off */ if ( !oSettings.oFeatures.bSort ) @@ -630,12 +638,12 @@ * use this for reading data from a DOM sourced table, but it could be * used for an TR element. Note that if a TR is given, it is used (i.e. * it is not cloned). - * @param {object} oSettings dataTables settings object + * @param {object} settings dataTables settings object * @param {array|node|jQuery} trs The TR element(s) to add to the table * @returns {array} Array of indexes for the added rows * @memberof DataTable#oApi */ - function _fnAddTr( oSettings, trs ) + function _fnAddTr( settings, trs ) { var row; @@ -645,8 +653,8 @@ } return trs.map( function (i, el) { - row = _fnGetRowElements( el ); - return _fnAddData( oSettings, row.data, el, row.cells ); + row = _fnGetRowElements( settings, el ); + return _fnAddData( settings, row.data, el, row.cells ); } ); } @@ -1079,7 +1087,7 @@ // Are we reading last data from DOM or the data object? if ( src === 'dom' || (! src && row.src === 'dom') ) { // Read the data from the DOM - row._aData = _fnGetRowData( row.nTr ).data; + row._aData = _fnGetRowElements( settings, row.nTr ).data; } else { // Reading from data object, update the DOM @@ -1099,6 +1107,7 @@ * Build a data source object from an HTML row, reading the contents of the * cells that are in the row. * + * @param {object} settings DataTables settings object * @param {node} TR element from which to read data * @returns {object} Object with two parameters: `data` the data read, in * document order, and `cells` and array of nodes (they can be useful to the @@ -1106,20 +1115,50 @@ * them from here). * @memberof DataTable#oApi */ - function _fnGetRowElements( row ) + function _fnGetRowElements( settings, row ) { var d = [], tds = [], td = row.firstChild, - name; + name, col, o, i=0, contents, + columns = settings.aoColumns; + + var attr = function ( str, data, td ) { + if ( typeof str === 'string' ) { + var idx = str.indexOf('@'); + + if ( idx !== -1 ) { + var src = str.substring( idx+1 ); + o[ '@'+src ] = td.getAttribute( src ); + } + } + }; while ( td ) { name = td.nodeName.toUpperCase(); if ( name == "TD" || name == "TH" ) { - d.push( $.trim(td.innerHTML) ); + col = columns[i]; + contents = $.trim(td.innerHTML); + + if ( col && col._bAttrSrc ) { + o = { + display: contents + }; + + attr( col.mData.sort, o, td ); + attr( col.mData.type, o, td ); + attr( col.mData.filter, o, td ); + + d.push( o ); + } + else { + d.push( contents ); + } + tds.push( td ); + i++; } td = td.nextSibling; @@ -1231,30 +1270,32 @@ var iThs = $('th, td', oSettings.nTHead).length; var iCorrector = 0; var jqChildren; + var classes = oSettings.oClasses; + var columns = oSettings.aoColumns; /* If there is a header in place - then use it - otherwise it's going to get nuked... */ if ( iThs !== 0 ) { /* We've got a thead from the DOM, so remove hidden columns and apply width to vis cols */ - for ( i=0, iLen=oSettings.aoColumns.length ; itr>th, >tr>td').addClass( classes.sHeaderTH ); + $(oSettings.nTFoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH ); /* Cache the footer elements */ if ( oSettings.nTFoot !== null ) { var anCells = _fnGetUniqueThs( oSettings, null, oSettings.aoFooter ); - for ( i=0, iLen=oSettings.aoColumns.length ; i sInput.length || iForce == 1 || - sInput.indexOf(oPrevSearch.sSearch) !== 0 ) + if ( invalidated || iForce == 1 || + oPrevSearch.sSearch.length > sInput.length || + sInput.indexOf(oPrevSearch.sSearch) !== 0 ) { /* Nuke the old display array - we are going to rebuild it */ oSettings.aiDisplay.length = 0; @@ -2650,10 +2690,10 @@ formatter = settings.fnFormatNumber; return str. - replace(/_START_/g, formatter( start ) ). - replace(/_END_/g, formatter( settings.fnDisplayEnd() ) ). - replace(/_TOTAL_/g, formatter( settings.fnRecordsDisplay() ) ). - replace(/_MAX_/g, formatter( settings.fnRecordsTotal() ) ); + replace(/_START_/g, formatter.call( settings, start ) ). + replace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ). + replace(/_TOTAL_/g, formatter.call( settings, settings.fnRecordsDisplay() ) ). + replace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ); } @@ -2844,19 +2884,44 @@ var type = settings.sPaginationType, plugin = DataTable.ext.oPagination[ type ], + modern = typeof plugin === 'function', redraw = function( settings ) { _fnDraw( settings ); }, - node = $('
').addClass( settings.oClasses.sPaging + type )[0]; + node = $('
').addClass( settings.oClasses.sPaging + type )[0], + features = settings.aanFeatures; - plugin.fnInit( settings, node, redraw ); + if ( ! modern ) { + plugin.fnInit( settings, node, redraw ); + } /* Add a draw callback for the pagination on first instance, to update the paging display */ - if ( ! settings.aanFeatures.p ) + if ( ! features.p ) { + node.id = settings.sTableId+'_paginate'; + settings.aoDrawCallback.push( { "fn": function( settings ) { - plugin.fnUpdate( settings, redraw ); + if ( modern ) { + var + start = settings._iDisplayStart, + len = settings._iDisplayLength, + visRecords = settings.fnRecordsDisplay(), + all = len === -1, + page = all ? 0 : Math.ceil( start / len ), + pages = all ? 1 : Math.ceil( visRecords / len ), + buttons = plugin(page, pages), + i, ien; + + for ( i=0, ien=features.p.length ; isPaginationType initialisation parameter. Each pagination type that - * is added is an object (the property name of which is what sPaginationType refers - * to) that has two properties, both methods that are used by DataTables to update the - * control's state. - *
    - *
  • - * fnInit - Initialisation of the paging controls. Called only during initialisation - * of the table. It is expected that this function will add the required DOM elements - * to the page for the paging controls to work. The element pointer - * 'oSettings.aanFeatures.p' array is provided by DataTables to contain the paging - * controls (note that this is a 2D array to allow for multiple instances of each - * DataTables DOM element). It is suggested that you add the controls to this element - * as children - *
      - *
    • - * Function input parameters: - *
        - *
      • {object} DataTables settings object: see {@link DataTable.models.oSettings}.
      • - *
      • {node} Container into which the pagination controls must be inserted
      • - *
      • {function} Draw callback function - whenever the controls cause a page - * change, this method must be called to redraw the table.
      • - *
      - *
    • - *
    • - * Function return: - *
        - *
      • No return required
      • - *
      - * - *
    - * - *
  • - * fnInit - This function is called whenever the paging status of the table changes and is - * typically used to update classes and/or text of the paging controls to reflex the new - * status. - *
      - *
    • - * Function input parameters: - *
        - *
      • {object} DataTables settings object: see {@link DataTable.models.oSettings}.
      • - *
      • {function} Draw callback function - in case you need to redraw the table again - * or attach new event listeners
      • - *
      - *
    • - *
    • - * Function return: - *
        - *
      • No return required
      • - *
      - * - *
    - * - *
+ * Pagination plug-in methods. Each entry in this object is a function + * and defines which buttons should be shown by pagination rendering method + * that is used for the table: {@link DataTable.ext.renderer.paging}. The + * renderer addresses how the buttons are displayed in the document, while + * the functions here tell it what buttons to display, in order by returning + * an array of button descriptions (what each button will down). + * + * Pagination types (the four built in options and any additional plug-in + * options) and be used through the `paginationType` initialisation + * parameter. + * + * The functions defined take two parameters: + * + * 1. `{int} page` The current page index + * 2. `{int} pages` The number of pages in the table + * + * Each function is expected to return an array where each element of the + * array can be one of: + * + * * `first` - Jump to first page when activated + * * `last` - Jump to last page when activated + * * `previous` - Show previous page when activated + * * `next` - Show next page when activated + * * `{int}` - Show page of the index given + * * `{array}` - A nested array containing the above elements to add a + * containing 'DIV' element (might be useful for styling). + * + * Note that DataTables v1.9- used this object slightly differently whereby + * an object with two functions would be defined for each plug-in. That + * ability is still supported by DataTables 1.10+ to provide backwards + * compatibility, but this option of use is now decremented and no longer + * documented in DataTables 1.10+. + * * @type object * @default {} * * @example - * $.fn.dataTableExt.oPagination.four_button = { - * "fnInit": function ( oSettings, nPaging, fnCallbackDraw ) { - * nFirst = document.createElement( 'span' ); - * nPrevious = document.createElement( 'span' ); - * nNext = document.createElement( 'span' ); - * nLast = document.createElement( 'span' ); - * - * nFirst.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sFirst ) ); - * nPrevious.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sPrevious ) ); - * nNext.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sNext ) ); - * nLast.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sLast ) ); - * - * nFirst.className = "paginate_button first"; - * nPrevious.className = "paginate_button previous"; - * nNext.className="paginate_button next"; - * nLast.className = "paginate_button last"; - * - * nPaging.appendChild( nFirst ); - * nPaging.appendChild( nPrevious ); - * nPaging.appendChild( nNext ); - * nPaging.appendChild( nLast ); - * - * $(nFirst).click( function () { - * oSettings.oApi._fnPageChange( oSettings, "first" ); - * fnCallbackDraw( oSettings ); - * } ); - * - * $(nPrevious).click( function() { - * oSettings.oApi._fnPageChange( oSettings, "previous" ); - * fnCallbackDraw( oSettings ); - * } ); - * - * $(nNext).click( function() { - * oSettings.oApi._fnPageChange( oSettings, "next" ); - * fnCallbackDraw( oSettings ); - * } ); - * - * $(nLast).click( function() { - * oSettings.oApi._fnPageChange( oSettings, "last" ); - * fnCallbackDraw( oSettings ); - * } ); - * - * $(nFirst).bind( 'selectstart', function () { return false; } ); - * $(nPrevious).bind( 'selectstart', function () { return false; } ); - * $(nNext).bind( 'selectstart', function () { return false; } ); - * $(nLast).bind( 'selectstart', function () { return false; } ); - * }, - * - * "fnUpdate": function ( oSettings, fnCallbackDraw ) { - * if ( !oSettings.aanFeatures.p ) { - * return; - * } - * - * // Loop over each instance of the pager - * var an = oSettings.aanFeatures.p; - * for ( var i=0, iLen=an.length ; i'+oLang.sPrevious+''+ - ''+oLang.sNext+'' - : - ''+ - ''; - $(nPaging).append( sAppend ); - var els = $('a', nPaging); - var nPrevious = els[0], - nNext = els[1]; - oSettings.oApi._fnBindAction( nPrevious, {action: "previous"}, fnClickHandler ); - oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler ); + (function() { - /* ID the first elements only */ - if ( !oSettings.aanFeatures.p ) - { - nPaging.id = oSettings.sTableId+'_paginate'; - nPrevious.id = oSettings.sTableId+'_previous'; - nNext.id = oSettings.sTableId+'_next'; - nPrevious.setAttribute('aria-controls', oSettings.sTableId); - nNext.setAttribute('aria-controls', oSettings.sTableId); - } - }, + var extPagination = DataTable.ext.oPagination; - /* - * Function: oPagination.two_button.fnUpdate - * Purpose: Update the two button pagination at the end of the draw - * Returns: - - * Inputs: object:oSettings - dataTables settings object - * function:fnCallbackDraw - draw function to call on page change - */ - "fnUpdate": function ( oSettings, fnCallbackDraw ) - { - if ( !oSettings.aanFeatures.p ) - { - return; - } + function _numbers ( page, pages ) { + var + numbers = [], + buttons = extPagination.numbers_length, + half = Math.floor( buttons / 2 ), + i = 1; - var oClasses = oSettings.oClasses; - var an = oSettings.aanFeatures.p; - var nNode; + if ( pages <= buttons ) { + numbers = _range( 0, pages ); + } + else if ( page <= half ) { + numbers = _range( 0, buttons-2 ); + numbers.push( 'ellipsis' ); + numbers.push( pages-1 ); + } + else if ( page >= pages - 1 - half ) { + numbers = _range( pages-(buttons-2), pages ); + numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6 + numbers.splice( 0, 0, 0 ); + } + else { + numbers = _range( page-1, page+2 ); + numbers.push( 'ellipsis' ); + numbers.push( pages-1 ); + numbers.splice( 0, 0, 'ellipsis' ); + numbers.splice( 0, 0, 0 ); + } - /* Loop over each instance of the pager */ - for ( var i=0, iLen=an.length ; i' ) + .appendTo( container ); + attach( inner, button ); + } + else { + btnDisplay = ''; + btnClass = ''; + + switch ( button ) { + case 'ellipsis': + container.append(''); + break; + + case 'first': + btnDisplay = lang.sFirst; + btnClass = button + (page > 0 ? + '' : ' '+classes.sPageButtonDisabled); + break; + + case 'previous': + btnDisplay = lang.sPrevious; + btnClass = button + (page > 0 ? + '' : ' '+classes.sPageButtonDisabled); + break; + + case 'next': + btnDisplay = lang.sNext; + btnClass = button + (page < pages-1 ? + '' : ' '+classes.sPageButtonDisabled); + break; + + case 'last': + btnDisplay = lang.sLast; + btnClass = button + (page < pages-1 ? + '' : ' '+classes.sPageButtonDisabled); + break; + + default: + btnDisplay = button + 1; + btnClass = page === button ? + classes.sPageButtonActive : ''; + break; + } + + if ( btnDisplay ) { + node = $('', { + 'class': classes.sPageButton+' '+btnClass, + 'aria-controls': settings.sTableId, + 'tabindex': settings.iTabIndex, + 'id': idx === 0 && typeof button === 'string' ? + settings.sTableId +'_'+ button : + null + } ) + .html( btnDisplay ) + .appendTo( container ); + + _fnBindAction( + node, {action: button}, clickHandler + ); + } + } } }; - $(nPaging).append( - ''+oLang.sFirst+''+ - ''+oLang.sPrevious+''+ - ''+ - ''+oLang.sNext+''+ - ''+oLang.sLast+'' - ); - var els = $('a', nPaging); - var nFirst = els[0], - nPrev = els[1], - nNext = els[2], - nLast = els[3]; - - oSettings.oApi._fnBindAction( nFirst, {action: "first"}, fnClickHandler ); - oSettings.oApi._fnBindAction( nPrev, {action: "previous"}, fnClickHandler ); - oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler ); - oSettings.oApi._fnBindAction( nLast, {action: "last"}, fnClickHandler ); - - /* ID the first elements only */ - if ( !oSettings.aanFeatures.p ) - { - nPaging.id = oSettings.sTableId+'_paginate'; - nFirst.id =oSettings.sTableId+'_first'; - nPrev.id =oSettings.sTableId+'_previous'; - nNext.id =oSettings.sTableId+'_next'; - nLast.id =oSettings.sTableId+'_last'; - } - }, - - /* - * Function: oPagination.full_numbers.fnUpdate - * Purpose: Update the list of page buttons shows - * Returns: - - * Inputs: object:oSettings - dataTables settings object - * function:fnCallbackDraw - draw function to call on page change - */ - "fnUpdate": function ( oSettings, fnCallbackDraw ) - { - if ( !oSettings.aanFeatures.p ) - { - return; - } - - var iPageCount = DataTable.ext.oPagination.iFullNumbersShowPages; - var iPageCountHalf = Math.floor(iPageCount / 2); - var iPages = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength); - var iCurrentPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1; - var sList = ""; - var iStartButton, iEndButton, i, iLen; - var oClasses = oSettings.oClasses; - var anButtons, anStatic, nPaginateList, nNode; - var an = oSettings.aanFeatures.p; - var fnBind = function (j) { - oSettings.oApi._fnBindAction( this, {"page": j+iStartButton-1}, function(e) { - /* Use the information in the element to jump to the required page */ - oSettings.oApi._fnPageChange( oSettings, e.data.page ); - fnCallbackDraw( oSettings ); - e.preventDefault(); - } ); - }; - - /* Pages calculation */ - if ( oSettings._iDisplayLength === -1 ) - { - iStartButton = 1; - iEndButton = 1; - iCurrentPage = 1; - } - else if (iPages < iPageCount) - { - iStartButton = 1; - iEndButton = iPages; - } - else if (iCurrentPage <= iPageCountHalf) - { - iStartButton = 1; - iEndButton = iPageCount; - } - else if (iCurrentPage >= (iPages - iPageCountHalf)) - { - iStartButton = iPages - iPageCount + 1; - iEndButton = iPages; - } - else - { - iStartButton = iCurrentPage - Math.ceil(iPageCount / 2) + 1; - iEndButton = iStartButton + iPageCount - 1; - } - - - /* Build the dynamic list */ - for ( i=iStartButton ; i<=iEndButton ; i++ ) - { - sList += (iCurrentPage !== i) ? - ''+oSettings.fnFormatNumber(i)+'' : - ''+oSettings.fnFormatNumber(i)+''; - } - - /* Loop over each instance of the pager */ - for ( i=0, iLen=an.length ; i