1
0
mirror of https://github.com/DataTables/DataTables.git synced 2025-01-19 12:52:11 +01:00

New: Rewrite of how pagination is handled to make it hugely more

flexible and simple to actually use.

New: Two additional built-in pagination types: 'simple_numbers' and
'full'.

Update: 'two_buttons' type pagination (previous default) renamed to
'simple'.

New: Default pagination type is now 'simple_numbers'.

New: Introducing renderers to DataTables (something that will play an
important part moving forward).

New: Simplified pagination button classes to simply:
 * "sPageButton": "paginate_button"
 * "sPageButtonActive": "current"
 * "sPageButtonDisabled": "disabled"

- The basis for this commit is a restructuring of how pagination
  plug-ins work in DataTables, whereby the pagination plug-in simply
  returns an array of button types which should be shown. These are then
  actually displayed by the renderer. This seperates the logic for which
  buttons to show from the display logic, making it much easier, both to
  customise which buttons will be shown, and for integration plug-ins to
  customise the display of the buttons (since they don't need to
  replicate the button calculation logic). This change allows us to
  introduce two new built-in pagination types to DataTables with minimal
  size cost. Indeed, this change as a whole reduces the compressed
  DataTables size by 2.5K (additional functionality, simpler and smaller
  - what's not to like!?).

- Pagination button classes in DataTables were a mess before, with
  different classes used for the two built in types, with the additional
  complexity of only one of the defined class options being used, rather
  than concatinating the classes based on the type. This was bonkers and
  a barrier to new users styling the form as they wanted. Reducing to
  just three class options, and having the active and disabled options
  added to the base class makes it MUCH simpiler. This could hit
  backwards compatiblity for those who had styled the mad old style, but
  it would have been crazy to keep it while writing the rest.
This commit is contained in:
Allan Jardine 2013-06-09 20:16:50 +01:00
parent e36609713c
commit 3ab5af5ff5
8 changed files with 259 additions and 416 deletions

View File

@ -173,6 +173,7 @@
* @extends DataTable.models.ext * @extends DataTable.models.ext
*/ */
DataTable.ext = $.extend( true, {}, DataTable.models.ext ); DataTable.ext = $.extend( true, {}, DataTable.models.ext );
DataTable.ext.renderer = {};
require('ext.classes.js'); require('ext.classes.js');
require('ext.paging.js'); require('ext.paging.js');
require('ext.sorting.js'); require('ext.sorting.js');

View File

@ -90,11 +90,21 @@ var _selector_opts = function ( opts )
}; };
}; };
var _range = function ( len ) var _range = function ( len, start )
{ {
var out = []; var out = [];
var end;
for ( var i=0 ; i<len ; i++ ) { if ( start === undefined ) {
start = 0;
end = len;
}
else {
end = start;
start = len;
}
for ( var i=start ; i<end ; i++ ) {
out.push( i ); out.push( i );
} }

View File

@ -51,6 +51,8 @@ function _fnBuildAjax( oSettings, data, fn )
oSettings.oApi._fnLog( oSettings, 0, json.sError ); oSettings.oApi._fnLog( oSettings, 0, json.sError );
} }
// add a transform function call xxx
$(oSettings.oInstance).trigger('xhr', [oSettings, json]); $(oSettings.oInstance).trigger('xhr', [oSettings, json]);
fn( json ); fn( json );
}, },

View File

@ -21,19 +21,44 @@ function _fnFeatureHtmlPaginate ( settings )
var var
type = settings.sPaginationType, type = settings.sPaginationType,
plugin = DataTable.ext.oPagination[ type ], plugin = DataTable.ext.oPagination[ type ],
modern = typeof plugin === 'function',
redraw = function( settings ) { redraw = function( settings ) {
_fnDraw( settings ); _fnDraw( settings );
}, },
node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0]; node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
features = settings.aanFeatures;
if ( ! modern ) {
plugin.fnInit( settings, node, redraw ); plugin.fnInit( settings, node, redraw );
}
/* Add a draw callback for the pagination on first instance, to update the paging display */ /* 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( { settings.aoDrawCallback.push( {
"fn": function( settings ) { "fn": function( settings ) {
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 ; i<ien ; i++ ) {
_fnRenderer( settings, 'paging' )(
settings, features.p[i], i, buttons, page, pages
);
}
}
else {
plugin.fnUpdate( settings, redraw ); plugin.fnUpdate( settings, redraw );
}
}, },
"sName": "pagination" "sName": "pagination"
} ); } );
@ -43,15 +68,37 @@ function _fnFeatureHtmlPaginate ( settings )
} }
function _fnRenderer( settings, type )
{
var renderer = settings.renderer;
var host = DataTable.ext.renderer[type];
if ( $.isPlainObject( renderer ) && renderer[type] ) {
// Specific renderer for this type. If available use it, otherwise use
// the default.
return host[renderer[type]] || host._;
}
else if ( typeof renderer === 'string' ) {
// Common renderer - if there is one available for this type use it,
// otherwise use the default
return host[renderer] || host._;
}
// Use the default
return host._;
}
/** /**
* Alter the display settings to change the page * Alter the display settings to change the page
* @param {object} settings DataTables settings object * @param {object} settings DataTables settings object
* @param {string|int} action Paging action to take: "first", "previous", * @param {string|int} action Paging action to take: "first", "previous",
* "next" or "last" or page number to jump to (integer) * "next" or "last" or page number to jump to (integer)
* @param [bool] redraw Automatically draw the update or not
* @returns {bool} true page has changed, false - no change * @returns {bool} true page has changed, false - no change
* @memberof DataTable#oApi * @memberof DataTable#oApi
*/ */
function _fnPageChange ( settings, action ) function _fnPageChange ( settings, action, redraw )
{ {
var var
start = settings._iDisplayStart, start = settings._iDisplayStart,
@ -107,6 +154,10 @@ function _fnPageChange ( settings, action )
$(settings.oInstance).trigger('page', settings); $(settings.oInstance).trigger('page', settings);
if ( redraw ) {
_fnDraw( settings );
}
return changed; return changed;
} }

View File

@ -2,22 +2,10 @@
$.extend( DataTable.ext.oStdClasses, { $.extend( DataTable.ext.oStdClasses, {
"sTable": "dataTable", "sTable": "dataTable",
/* Two buttons buttons */ /* Paging buttons */
"sPagePrevEnabled": "paginate_enabled_previous",
"sPagePrevDisabled": "paginate_disabled_previous",
"sPageNextEnabled": "paginate_enabled_next",
"sPageNextDisabled": "paginate_disabled_next",
"sPageJUINext": "",
"sPageJUIPrev": "",
/* Full numbers paging buttons */
"sPageButton": "paginate_button", "sPageButton": "paginate_button",
"sPageButtonActive": "paginate_active", "sPageButtonActive": "current",
"sPageButtonStaticDisabled": "paginate_button paginate_button_disabled", "sPageButtonDisabled": "disabled",
"sPageFirst": "first",
"sPagePrevious": "previous",
"sPageNext": "next",
"sPageLast": "last",
/* Striping classes */ /* Striping classes */
"sStripeOdd": "odd", "sStripeOdd": "odd",
@ -66,20 +54,10 @@ $.extend( DataTable.ext.oStdClasses, {
$.extend( DataTable.ext.oJUIClasses, DataTable.ext.oStdClasses, { $.extend( DataTable.ext.oJUIClasses, DataTable.ext.oStdClasses, {
/* Two buttons buttons */
"sPagePrevEnabled": "fg-button ui-button ui-state-default ui-corner-left",
"sPagePrevDisabled": "fg-button ui-button ui-state-default ui-corner-left ui-state-disabled",
"sPageNextEnabled": "fg-button ui-button ui-state-default ui-corner-right",
"sPageNextDisabled": "fg-button ui-button ui-state-default ui-corner-right ui-state-disabled",
"sPageJUINext": "ui-icon ui-icon-circle-arrow-e",
"sPageJUIPrev": "ui-icon ui-icon-circle-arrow-w",
/* Full numbers paging buttons */ /* Full numbers paging buttons */
"sPageButton": "fg-button ui-button ui-state-default", "sPageButton": "fg-button ui-button ui-state-default",
"sPageButtonActive": "fg-button ui-button ui-state-default ui-state-disabled", "sPageButtonActive": "ui-state-disabled",
"sPageButtonStaticDisabled": "fg-button ui-button ui-state-default ui-state-disabled", "sPageButtonDisabled": "ui-state-disabled",
"sPageFirst": "first ui-corner-tl ui-corner-bl",
"sPageLast": "last ui-corner-tr ui-corner-br",
/* Features */ /* Features */
"sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+ "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+

View File

@ -1,262 +1,152 @@
/*
* Variable: oPagination
* Purpose: (function() {
* Scope: jQuery.fn.dataTableExt
*/
$.extend( DataTable.ext.oPagination, { var extPagination = DataTable.ext.oPagination;
/*
* Variable: two_button function _numbers ( page, pages ) {
* Purpose: Standard two button (forward/back) pagination var
* Scope: jQuery.fn.dataTableExt.oPagination numbers = [],
*/ buttons = extPagination.numbers_length,
"two_button": { half = Math.floor( buttons / 2 ),
/* i = 1;
* Function: oPagination.two_button.fnInit
* Purpose: Initialise dom elements required for pagination with forward/back buttons only if ( pages <= buttons ) {
* Returns: - numbers = _range( 0, pages );
* Inputs: object:oSettings - dataTables settings object }
* node:nPaging - the DIV which contains this pagination control else if ( page <= half ) {
* function:fnCallbackDraw - draw function which must be called on update numbers = _range( 0, buttons-2 );
*/ numbers.push( 'ellipsis' );
"fnInit": function ( oSettings, nPaging, fnCallbackDraw ) numbers.push( pages-1 );
{ }
var oLang = oSettings.oLanguage.oPaginate; else if ( page >= pages - 1 - half ) {
var oClasses = oSettings.oClasses; numbers = _range( pages-(buttons-2), pages );
var fnClickHandler = function ( e ) { numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) ) numbers.splice( 0, 0, 0 );
{ }
fnCallbackDraw( oSettings ); else {
numbers = _range( page-1, page+2 );
numbers.push( 'ellipsis' );
numbers.push( pages-1 );
numbers.splice( 0, 0, 'ellipsis' );
numbers.splice( 0, 0, 0 );
}
numbers.DT_el = 'span';
return numbers;
}
$.extend( extPagination, {
simple: function ( page, pages ) {
return [ 'previous', 'next' ];
},
full: function ( page, pages ) {
return [ 'previous', 'previous', 'next', 'next' ];
},
simple_numbers: function ( page, pages ) {
return [ 'previous', _numbers(page, pages), 'next' ];
},
full_numbers: function ( page, pages ) {
return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
},
// For testing and plug-ins to use
_numbers: _numbers,
numbers_length: 7
} );
$.extend( true, DataTable.ext.renderer, {
paging: {
_: function ( settings, host, idx, buttons, page, pages ) {
var classes = settings.oClasses;
var lang = settings.oLanguage.oPaginate;
var btnDisplay, btnClass;
var attach = function( container, buttons ) {
var i, ien, node, button;
var clickHandler = function ( e ) {
_fnPageChange( settings, e.data.action, true );
};
for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
button = buttons[i];
if ( $.isArray( button ) ) {
var inner = $( '<'+(button.DT_el || 'div')+'/>' )
.appendTo( container );
attach( inner, button );
}
else {
btnDisplay = '';
btnClass = '';
switch ( button ) {
case 'ellipsis':
container.append('<span>&hellip;</span>');
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 = $('<a>', {
'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
);
}
}
} }
}; };
var sAppend = (!oSettings.bJUI) ? attach( $(host).empty(), buttons );
'<a class="'+oSettings.oClasses.sPagePrevDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button">'+oLang.sPrevious+'</a>'+
'<a class="'+oSettings.oClasses.sPageNextDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button">'+oLang.sNext+'</a>'
:
'<a class="'+oSettings.oClasses.sPagePrevDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button"><span class="'+oSettings.oClasses.sPageJUIPrev+'"></span></a>'+
'<a class="'+oSettings.oClasses.sPageNextDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button"><span class="'+oSettings.oClasses.sPageJUINext+'"></span></a>';
$(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 );
/* 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);
}
},
/*
* 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;
}
var oClasses = oSettings.oClasses;
var an = oSettings.aanFeatures.p;
var nNode;
/* Loop over each instance of the pager */
for ( var i=0, iLen=an.length ; i<iLen ; i++ )
{
nNode = an[i].firstChild;
if ( nNode )
{
/* Previous page */
nNode.className = ( oSettings._iDisplayStart === 0 ) ?
oClasses.sPagePrevDisabled : oClasses.sPagePrevEnabled;
/* Next page */
nNode = nNode.nextSibling;
nNode.className = ( oSettings.fnDisplayEnd() == oSettings.fnRecordsDisplay() ) ?
oClasses.sPageNextDisabled : oClasses.sPageNextEnabled;
}
}
}
},
/*
* Variable: iFullNumbersShowPages
* Purpose: Change the number of pages which can be seen
* Scope: jQuery.fn.dataTableExt.oPagination
*/
"iFullNumbersShowPages": 5,
/*
* Variable: full_numbers
* Purpose: Full numbers pagination
* Scope: jQuery.fn.dataTableExt.oPagination
*/
"full_numbers": {
/*
* Function: oPagination.full_numbers.fnInit
* Purpose: Initialise dom elements required for pagination with a list of the pages
* Returns: -
* Inputs: object:oSettings - dataTables settings object
* node:nPaging - the DIV which contains this pagination control
* function:fnCallbackDraw - draw function which must be called on update
*/
"fnInit": function ( oSettings, nPaging, fnCallbackDraw )
{
var oLang = oSettings.oLanguage.oPaginate;
var oClasses = oSettings.oClasses;
var fnClickHandler = function ( e ) {
if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) )
{
fnCallbackDraw( oSettings );
}
};
$(nPaging).append(
'<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageFirst+'">'+oLang.sFirst+'</a>'+
'<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPagePrevious+'">'+oLang.sPrevious+'</a>'+
'<span></span>'+
'<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageNext+'">'+oLang.sNext+'</a>'+
'<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageLast+'">'+oLang.sLast+'</a>'
);
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) ?
'<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+'">'+oSettings.fnFormatNumber(i)+'</a>' :
'<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButtonActive+'">'+oSettings.fnFormatNumber(i)+'</a>';
}
/* Loop over each instance of the pager */
for ( i=0, iLen=an.length ; i<iLen ; i++ )
{
nNode = an[i];
if ( !nNode.hasChildNodes() )
{
continue;
}
/* Build up the dynamic list first - html and listeners */
$('span:eq(0)', nNode)
.html( sList )
.children('a').each( fnBind );
/* Update the permanent button's classes */
anButtons = nNode.getElementsByTagName('a');
anStatic = [
anButtons[0], anButtons[1],
anButtons[anButtons.length-2], anButtons[anButtons.length-1]
];
$(anStatic).removeClass( oClasses.sPageButton+" "+oClasses.sPageButtonActive+" "+oClasses.sPageButtonStaticDisabled );
$([anStatic[0], anStatic[1]]).addClass(
(iCurrentPage==1) ?
oClasses.sPageButtonStaticDisabled :
oClasses.sPageButton
);
$([anStatic[2], anStatic[3]]).addClass(
(iPages===0 || iCurrentPage===iPages || oSettings._iDisplayLength===-1) ?
oClasses.sPageButtonStaticDisabled :
oClasses.sPageButton
);
}
} }
} }
} ); } );
}());

View File

@ -1547,8 +1547,8 @@ DataTable.defaults = {
}, },
/** /**
* Pagination string used by DataTables for the two built-in pagination * Pagination string used by DataTables for the built-in pagination
* control types ("two_button" and "full_numbers") * control types.
* @namespace * @namespace
* @name DataTable.defaults.language.paginate * @name DataTable.defaults.language.paginate
*/ */
@ -2069,11 +2069,18 @@ DataTable.defaults = {
/** /**
* DataTables features two different built-in pagination interaction methods * DataTables features four different built-in options for the buttons to
* ('two_button' or 'full_numbers') which present different page controls to * display for pagination control:
* the end user. Further methods can be added using the API (see below). *
* * `simple` - 'Previous' and 'Next' buttons only
* * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
* * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
* * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus
* page numbers
*
* Further methods can be added using {@link DataTable.ext.oPagination}.
* @type string * @type string
* @default two_button * @default simple_numbers
* *
* @dtopt Options * @dtopt Options
* @name DataTable.defaults.paginationType * @name DataTable.defaults.paginationType
@ -2085,7 +2092,7 @@ DataTable.defaults = {
* } ); * } );
* } ) * } )
*/ */
"sPaginationType": "two_button", "sPaginationType": "simple_numbers",
/** /**

View File

@ -285,142 +285,46 @@ DataTable.models.ext = {
/** /**
* Pagination plug-in methods - The style and controls of the pagination can significantly * Pagination plug-in methods. Each entry in this object is a function
* impact on how the end user interacts with the data in your table, and DataTables allows * and defines which buttons should be shown by pagination rendering method
* the addition of pagination controls by extending this object, which can then be enabled * that is used for the table: {@link DataTable.ext.renderer.paging}. The
* through the <i>sPaginationType</i> initialisation parameter. Each pagination type that * renderer addresses how the buttons are displayed in the document, while
* is added is an object (the property name of which is what <i>sPaginationType</i> refers * the functions here tell it what buttons to display, in order by returning
* to) that has two properties, both methods that are used by DataTables to update the * an array of button descriptions (what each button will down).
* control's state. *
* <ul> * Pagination types (the four built in options and any additional plug-in
* <li> * options) and be used through the `paginationType` initialisation
* fnInit - Initialisation of the paging controls. Called only during initialisation * parameter.
* 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 * The functions defined take two parameters:
* '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 * 1. `{int} page` The current page index
* DataTables DOM element). It is suggested that you add the controls to this element * 2. `{int} pages` The number of pages in the table
* as children *
* <ul> * Each function is expected to return an array where each element of the
* <li> * array can be one of:
* Function input parameters: *
* <ul> * * `first` - Jump to first page when activated
* <li>{object} DataTables settings object: see {@link DataTable.models.oSettings}.</li> * * `last` - Jump to last page when activated
* <li>{node} Container into which the pagination controls must be inserted</li> * * `previous` - Show previous page when activated
* <li>{function} Draw callback function - whenever the controls cause a page * * `next` - Show next page when activated
* change, this method must be called to redraw the table.</li> * * `{int}` - Show page of the index given
* </ul> * * `{array}` - A nested array containing the above elements to add a
* </li> * containing 'DIV' element (might be useful for styling).
* <li> *
* Function return: * Note that DataTables v1.9- used this object slightly differently whereby
* <ul> * an object with two functions would be defined for each plug-in. That
* <li>No return required</li> * ability is still supported by DataTables 1.10+ to provide backwards
* </ul> * compatibility, but this option of use is now decremented and no longer
* </il> * documented in DataTables 1.10+.
* </ul> *
* </il>
* <li>
* 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.
* <ul>
* <li>
* Function input parameters:
* <ul>
* <li>{object} DataTables settings object: see {@link DataTable.models.oSettings}.</li>
* <li>{function} Draw callback function - in case you need to redraw the table again
* or attach new event listeners</li>
* </ul>
* </li>
* <li>
* Function return:
* <ul>
* <li>No return required</li>
* </ul>
* </il>
* </ul>
* </il>
* </ul>
* @type object * @type object
* @default {} * @default {}
* *
* @example * @example
* $.fn.dataTableExt.oPagination.four_button = { * // Show previous, next and current page buttons only
* "fnInit": function ( oSettings, nPaging, fnCallbackDraw ) { * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
* nFirst = document.createElement( 'span' ); * return [ 'previous', page, 'next' ];
* 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<iLen ; i++ ) {
* var buttons = an[i].getElementsByTagName('span');
* if ( oSettings._iDisplayStart === 0 ) {
* buttons[0].className = "paginate_disabled_previous";
* buttons[1].className = "paginate_disabled_previous";
* }
* else {
* buttons[0].className = "paginate_enabled_previous";
* buttons[1].className = "paginate_enabled_previous";
* }
*
* if ( oSettings.fnDisplayEnd() == oSettings.fnRecordsDisplay() ) {
* buttons[2].className = "paginate_disabled_next";
* buttons[3].className = "paginate_disabled_next";
* }
* else {
* buttons[2].className = "paginate_enabled_next";
* buttons[3].className = "paginate_enabled_next";
* }
* }
* }
* }; * };
*/ */
"oPagination": {}, "oPagination": {},