diff --git a/share/static/css/main.css b/share/static/css/main.css index ab80cb8abc..40250a1b2c 100644 --- a/share/static/css/main.css +++ b/share/static/css/main.css @@ -213,6 +213,10 @@ div.dataTables_paginate { margin: 0; } +div.dataTables_paginate a.btn { + margin-left: 3px; +} + /* --------- Datatable Field (inside modal) ------------*/ diff --git a/share/static/js/libs/datatables-bootstrap-paging.js b/share/static/js/libs/datatables-bootstrap-paging.js index b2af271429..f53d7d9841 100644 --- a/share/static/js/libs/datatables-bootstrap-paging.js +++ b/share/static/js/libs/datatables-bootstrap-paging.js @@ -1,91 +1,132 @@ - -/* API method to get paging information */ -$.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings ) -{ - return { - "iStart": oSettings._iDisplayStart, - "iEnd": oSettings.fnDisplayEnd(), - "iLength": oSettings._iDisplayLength, - "iTotal": oSettings.fnRecordsTotal(), - "iFilteredTotal": oSettings.fnRecordsDisplay(), - "iPage": Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ), - "iTotalPages": Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength ) - }; -} - -/* Bootstrap style pagination control */ -$.extend( $.fn.dataTableExt.oPagination, { - "bootstrap": { - "fnInit": function( oSettings, nPaging, fnDraw ) { - var oLang = oSettings.oLanguage.oPaginate; - var fnClickHandler = function ( e ) { - e.preventDefault(); - if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) { - fnDraw( oSettings ); - } - }; - - $(nPaging).addClass('pagination').append( - '' - ); - var els = $('a', nPaging); - $(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler ); - $(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler ); - }, - - "fnUpdate": function ( oSettings, fnDraw ) { - var iListLength = 5; - var oPaging = oSettings.oInstance.fnPagingInfo(); - var an = oSettings.aanFeatures.p; - var i, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2); - - if ( oPaging.iTotalPages < iListLength) { - iStart = 1; - iEnd = oPaging.iTotalPages; - } - else if ( oPaging.iPage <= iHalf ) { - iStart = 1; - iEnd = iListLength; - } else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) { - iStart = oPaging.iTotalPages - iListLength + 1; - iEnd = oPaging.iTotalPages; - } else { - iStart = oPaging.iPage - iHalf + 1; - iEnd = iStart + iListLength - 1; - } - - for ( i=0, iLen=an.length ; i'+j+'') - .insertBefore( $('li:last', an[i])[0] ) - .bind('click', function (e) { - e.preventDefault(); - oSettings._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength; - fnDraw( oSettings ); - } ); - } - - // Add / remove disabled classes from the static elements - if ( oPaging.iPage === 0 ) { - $('li:first', an[i]).addClass('disabled'); - } else { - $('li:first', an[i]).removeClass('disabled'); - } - - if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) { - $('li:last', an[i]).addClass('disabled'); - } else { - $('li:last', an[i]).removeClass('disabled'); - } - } - } - } -} ); +$.extend($.fn.dataTableExt.oStdClasses, { + 'sPageEllipsis': 'paginate_ellipsis', + 'sPageNumber': 'paginate_number', + 'sPageNumbers': 'paginate_numbers' +}); + +$.fn.dataTableExt.oPagination.bootstrap = { + 'oDefaults': { + 'iShowPages': 5 + }, + 'fnClickHandler': function(e) { + var fnCallbackDraw = e.data.fnCallbackDraw, + oSettings = e.data.oSettings, + sPage = e.data.sPage; + + if ($(this).is('[disabled]')) { + return false; + } + + oSettings.oApi._fnPageChange(oSettings, sPage); + fnCallbackDraw(oSettings); + + return true; + }, + // fnInit is called once for each instance of pager + 'fnInit': function(oSettings, nPager, fnCallbackDraw) { + var oClasses = oSettings.oClasses, + oLang = oSettings.oLanguage.oPaginate, + that = this; + + var iShowPages = oSettings.oInit.iShowPages || this.oDefaults.iShowPages, + iShowPagesHalf = Math.floor(iShowPages / 2); + + $.extend(oSettings, { + _iShowPages: iShowPages, + _iShowPagesHalf: iShowPagesHalf, + }); + + var oFirst = $(''), + oPrevious = $(''), + oNumbers = $(''), + oNext = $(''), + oLast = $(''); + + oFirst.click({ 'fnCallbackDraw': fnCallbackDraw, 'oSettings': oSettings, 'sPage': 'first' }, that.fnClickHandler); + oPrevious.click({ 'fnCallbackDraw': fnCallbackDraw, 'oSettings': oSettings, 'sPage': 'previous' }, that.fnClickHandler); + oNext.click({ 'fnCallbackDraw': fnCallbackDraw, 'oSettings': oSettings, 'sPage': 'next' }, that.fnClickHandler); + oLast.click({ 'fnCallbackDraw': fnCallbackDraw, 'oSettings': oSettings, 'sPage': 'last' }, that.fnClickHandler); + + // Draw + $(nPager).append(oFirst, oPrevious, oNumbers, oNext, oLast); + }, + // fnUpdate is only called once while table is rendered + 'fnUpdate': function(oSettings, fnCallbackDraw) { + var oClasses = oSettings.oClasses, + that = this; + + var tableWrapper = oSettings.nTableWrapper; + + // Update stateful properties + this.fnUpdateState(oSettings); + + if (oSettings._iCurrentPage === 1) { + $('.paging_first', tableWrapper).attr('disabled', true); + $('.paging_prev', tableWrapper).attr('disabled', true); + } else { + $('.paging_first', tableWrapper).removeAttr('disabled'); + $('.paging_prev', tableWrapper).removeAttr('disabled'); + } + + if (oSettings._iTotalPages === 0 || oSettings._iCurrentPage === oSettings._iTotalPages) { + $('.paging_next', tableWrapper).attr('disabled', true); + $('.paging_last', tableWrapper).attr('disabled', true); + } else { + $('.paging_next', tableWrapper).removeAttr('disabled'); + $('.paging_last', tableWrapper).removeAttr('disabled'); + } + + var i, oNumber, oNumbers = $('.paging_num', tableWrapper); + + // Erase + oNumbers.html(''); + + for (i = oSettings._iFirstPage; i <= oSettings._iLastPage; i++) { + oNumber = $('' + oSettings.fnFormatNumber(i) + ''); + + if (oSettings._iCurrentPage === i) { + oNumber.attr('active', true).attr('disabled', true).addClass('btn-primary'); + } else { + oNumber.click({ 'fnCallbackDraw': fnCallbackDraw, 'oSettings': oSettings, 'sPage': i - 1 }, that.fnClickHandler); + } + + // Draw + oNumbers.append(oNumber); + } + + // Add ellipses + if (1 < oSettings._iFirstPage) { + oNumbers.prepend('...'); + } + + if (oSettings._iLastPage < oSettings._iTotalPages) { + oNumbers.append('...'); + } + }, + // fnUpdateState used to be part of fnUpdate + // The reason for moving is so we can access current state info before fnUpdate is called + 'fnUpdateState': function(oSettings) { + var iCurrentPage = Math.ceil((oSettings._iDisplayStart + 1) / oSettings._iDisplayLength), + iTotalPages = Math.ceil(oSettings.fnRecordsTotal() / oSettings._iDisplayLength), + iFirstPage = iCurrentPage - oSettings._iShowPagesHalf, + iLastPage = iCurrentPage + oSettings._iShowPagesHalf; + + if (iTotalPages < oSettings._iShowPages) { + iFirstPage = 1; + iLastPage = iTotalPages; + } else if (iFirstPage < 1) { + iFirstPage = 1; + iLastPage = oSettings._iShowPages; + } else if (iLastPage > iTotalPages) { + iFirstPage = (iTotalPages - oSettings._iShowPages) + 1; + iLastPage = iTotalPages; + } + + $.extend(oSettings, { + _iCurrentPage: iCurrentPage, + _iTotalPages: iTotalPages, + _iFirstPage: iFirstPage, + _iLastPage: iLastPage + }); + } +}; diff --git a/share/templates/helpers/datatables.tt b/share/templates/helpers/datatables.tt index 5cb61edee1..acc94a4ad9 100644 --- a/share/templates/helpers/datatables.tt +++ b/share/templates/helpers/datatables.tt @@ -20,6 +20,7 @@ $(document).ready(function() { "bSort": true, "bInfo": true, "iDisplayLength": 5, + 'iShowPages': 5, "sAjaxSource": "[% helper.ajax_uri %]", [% IF helper.column_sort -%] "aaSorting": [ diff --git a/share/templates/helpers/datatables_field.tt b/share/templates/helpers/datatables_field.tt index 3c74a2503e..b1354919df 100644 --- a/share/templates/helpers/datatables_field.tt +++ b/share/templates/helpers/datatables_field.tt @@ -23,6 +23,7 @@ $(document).ready(function() { "bSort": true, "bInfo": true, "iDisplayLength": 4, + 'iShowPages': 5, "sAjaxSource": "[% ajax_src %]", "aoColumns": [