From 01a4a0436451e87ef22f9ddde6bb3d4eae209f3e Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Thu, 23 Jun 2011 10:43:41 +0000 Subject: [PATCH] New implementation for displaying long lists: pagination SVN:trunk[1294] --- js/extkeywidget.js | 7 +- js/jquery.tablesorter.pager.js | 393 +++++++++++++++++++++++++++++++++ js/linkswidget.js | 86 ++++++-- js/utils.js | 11 +- 4 files changed, 472 insertions(+), 25 deletions(-) create mode 100644 js/jquery.tablesorter.pager.js diff --git a/js/extkeywidget.js b/js/extkeywidget.js index 1942a59a8..60158d9ea 100644 --- a/js/extkeywidget.js +++ b/js/extkeywidget.js @@ -78,6 +78,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper me.UpdateSizes(); me.UpdateButtons(); me.ajax_request = null; + me.DoSearchObjects(); }, 'html' ); @@ -110,7 +111,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper this.UpdateButtons = function() { var okBtn = $('#btn_ok_'+me.id); - if ($('#fr_'+me.id+' input[name=selectObject]:checked').length > 0) + if ($('#count_'+me.id).val() > 0) { okBtn.attr('disabled', ''); } @@ -167,10 +168,12 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper { $(sSearchAreaId).html(data); $(sSearchAreaId+' .listResults').tableHover(); - $(sSearchAreaId+' .listResults').tablesorter( { headers: {0: {sorter: false}}, widgets: ['myZebra', 'truncatedList']} ); // sortable and zebra tables $('#fr_'+me.id+' input:radio').click(function() { me.UpdateButtons(); }); me.UpdateButtons(); me.ajax_request = null; + $('#count_'+me.id).change(function(){ + me.UpdateButtons(); + }); }, 'html' ); diff --git a/js/jquery.tablesorter.pager.js b/js/jquery.tablesorter.pager.js new file mode 100644 index 000000000..75d000781 --- /dev/null +++ b/js/jquery.tablesorter.pager.js @@ -0,0 +1,393 @@ +function sprintf(format, etc) { + var arg = arguments; + var i = 1; + return format.replace(/%((%)|s)/g, function (m) { return m[2] || arg[i++] }) +} + + +(function($) { + $.extend({ + tablesorterPager: new function() { + + function updatePageDisplay(c) { + var s = $(c.cssPageDisplay,c.container).val((c.page+1) + c.seperator + c.totalPages); + } + + function setPageSize(table,size) { + var c = table.config; + c.size = size; + c.totalPages = Math.ceil(c.totalRows / c.size); + c.pagerPositionSet = false; + moveToPage(table); + fixPosition(table); + } + + function fixPosition(table) { + var c = table.config; + if(!c.pagerPositionSet && c.positionFixed) { + var c = table.config, o = $(table); + if(o.offset) { + c.container.css({ + top: o.offset().top + o.height() + 'px', + position: 'absolute' + }); + } + c.pagerPositionSet = true; + } + } + + function moveToFirstPage(table) { + var c = table.config; + c.page = 0; + moveToPage(table); + } + + function moveToLastPage(table) { + var c = table.config; + c.page = (c.totalPages-1); + moveToPage(table); + } + + function moveToNextPage(table) { + var c = table.config; + c.page++; + if(c.page >= (c.totalPages-1)) { + c.page = (c.totalPages-1); + } + moveToPage(table); + } + + function moveToPrevPage(table) { + var c = table.config; + c.page--; + if(c.page <= 0) { + c.page = 0; + } + moveToPage(table); + } + + + function moveToPage(table) { + var c = table.config; + if(c.page < 0 || c.page > (c.totalPages-1)) { + c.page = 0; + } + + renderTable(table,c.rowsCopy); + } + + function checkAll(table, pager, value) + { + // Mark all the displayed items as check or unchecked depending on the value + $(table).find(':checkbox[name^=selectObj]').attr('checked', value); + // Set the 'selectionMode' for the future objects to load + if (value) + { + table.config.selectionMode = 'negative'; + } + else + { + table.config.selectionMode = 'positive'; + } + $(pager).find(':input[name=selectionMode]').val(table.config.selectionMode); + // Reset the list of saved selection... + resetStoredSelection(pager); + updateCounter(table, pager); + return true; + } + + function resetStoredSelection(pager) + { + $(':input[name^=storedSelection]', pager).remove(); + } + + function updateSelection(table, pager, id, value) + { + var valueToStore = value; + if (table.config.selectionMode == 'negative') + { + valueToStore = !(valueToStore); + } + if (valueToStore) + { + if (table.config.select_mode == 'single') + { + $(':input[name^=storedSelection]', pager).remove(); // Remove any previous selection + } + if ($('#'+id, pager).length ==0) + { + $(pager).append($('')); + } + } + else + { + if ($('#'+id, pager).length !=0) + { + $('#'+id, pager).remove(); + } + } + updateCounter(table, pager); + } + + function updateCounter(table, pager) + { + var ex = $(':input[name^=storedSelection]', pager).length; + var s = ex; + if (table.config.selectionMode == 'negative') + { + s = table.config.totalRows - ex; + } + $('.selectedCount',pager).text(s); + if (table.config.cssCount != '') + { + $(table.config.cssCount).val(s); + $(table.config.cssCount).trigger('change'); + } + } + + function getData(table, start, end) + { + var c = table.config; + var s = c.sortList[0]; + var s_col = null; + var s_order = null; + if (s != undefined) + { + s_col = s[0]; + s_order = (s[1] == 0) ? 'asc' : 'desc'; + } + $('#loading', table.config.container).html(''); + $.post("../pages/ajax.render.php", + { operation: 'pagination', + filter: c.filter, + extra_param: c.extra_params, + start: start, + end: end, + sort_col: s_col, + sort_order: s_order, + select_mode: c.select_mode, + display_key: c.displayKey, + display_list: c.displayList + }, + function(data) + { + oData = $(data); + var tableBody = $(table.tBodies[0]); + + // clear the table body + + $.tablesorter.clearTableBody(table); + + for(var i = 0; i < end-start; i++) { + + //tableBody.append(rows[i]); + + //var o = rows[i]; + var r = $(oData[i]); + var l = r.length; + for(var j=0; j < l; j++) { + + //tableBody[0].appendChild(r); + tableBody[0].appendChild(r[j]); + + } + } + + fixPosition(table,tableBody); + if (c.selectionMode == 'negative') + { + $(table).find(':checkbox[name^=selectObj]').attr('checked', true); + } + + if (table.config.select_mode == 'multiple') + { + $(table).find(':checkbox[name^=selectObj]').each(function() { + var id = parseInt(this.value, 10); + if ($('#'+id, table.config.container).length > 0) + { + if (c.selectionMode == 'positive') + { + $(this).attr('checked', true); + } + else + { + $(this).attr('checked', false); + } + } + }); + + $(table).find(':checkbox[name^=selectObj]').change(function() { + updateSelection(table, table.config.container, this.value, this.checked); + }); + } + else if (table.config.select_mode == 'single') + { + $(table).find('input[name^=selectObject]:radio').each(function() { + var id = parseInt(this.value, 10); + if ($('#'+id, table.config.container).length > 0) + { + if (c.selectionMode == 'positive') + { + $(this).attr('checked', true); + } + else + { + $(this).attr('checked', false); + } + } + }); + + $(table).find('input[name^=selectObject]:radio').change(function() { + updateSelection(table, table.config.container, this.value, this.checked); + }); + } + + $(table).trigger("applyWidgets"); + + if( c.page >= c.totalPages ) { + moveToLastPage(table); + } + + updatePageDisplay(c); + updateCounter(table, table.config.container); + renderPager(table, table.config.container); + $('#loading', table.config.container).empty(); + }); + } + + function renderPager(table, pager) + { + var c = table.config; + var s = c.page - 2; + var nb = Math.ceil(c.totalRows / c.size); + if (s < 0) + { + s = 0; + } + var e = s +5; + if (e > nb) + { + e = nb; + } + txt = ''; + for(var i=s; i'+page+' '; + } + txt += link; + } + txt += ''; + $('#total', pager).text(c.totalRows); + $('#index', pager).html(txt); + for(var j=s; j c.totalRows ) { + e = c.totalRows; + } + + getData(table, s, e); + } + + this.appender = function(table,rows) { + + var c = table.config; + + if (c.totalRows == 0) + { + c.totalRows = rows.length; + } + c.totalPages = Math.ceil(c.totalRows / c.size); + + renderTable(table,rows); + }; + + this.defaults = { + size: 10, + offset: 0, + page: 0, + totalRows: 0, + totalPages: 0, + container: null, + cssNext: '.next', + cssPrev: '.prev', + cssFirst: '.first', + cssLast: '.last', + cssPageDisplay: '.pagedisplay', + cssPageSize: '.pagesize', + cssCount: '', + seperator: "/", + positionFixed: false, + appender: this.appender, + filter: '', + extra_params: '', + select_mode: '', + totalSelected: 0, + selectionMode: 'positive', + displayKey: true, + displayList: [] + }; + + this.construct = function(settings) { + + return this.each(function() { + + config = $.extend(this.config, $.tablesorterPager.defaults, settings); + + var table = this, pager = config.container; + + $(this).trigger("appendCache"); + + config.size = parseInt($(".pagesize",pager).val()); + + $(config.cssFirst,pager).click(function() { + moveToFirstPage(table); + return false; + }); + $(config.cssNext,pager).click(function() { + moveToNextPage(table); + return false; + }); + $(config.cssPrev,pager).click(function() { + moveToPrevPage(table); + return false; + }); + $(config.cssLast,pager).click(function() { + moveToLastPage(table); + return false; + }); + $(config.cssPageSize,pager).change(function() { + setPageSize(table,parseInt($(this).val())); + return false; + }); + $(table).find(':checkbox.checkAll').removeAttr('onclick').click(function() { + return checkAll(table, pager, this.checked); + }); + }); + }; + + } + }); + // extend plugin scope + $.fn.extend({ + tablesorterPager: $.tablesorterPager.construct + }); + +})(jQuery); diff --git a/js/linkswidget.js b/js/linkswidget.js index 7b8aad2fe..6e21bb027 100644 --- a/js/linkswidget.js +++ b/js/linkswidget.js @@ -59,6 +59,7 @@ function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates) { $('#dlg_'+me.id).dialog('open'); this.UpdateSizes(null, null); + this.SearchObjectsToAdd(); } this.SearchObjectsToAdd = function() @@ -101,7 +102,10 @@ function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates) { $(sSearchAreaId).html(data); $(sSearchAreaId+' .listResults').tableHover(); - $(sSearchAreaId+' .listResults').tablesorter( { headers: {0: {sorter: false}}, widgets: ['myZebra', 'truncatedList']} ); // sortable and zebra tables + $('#count_'+me.id).change(function(){ + var c = this.value; + me.UpdateButtons(c); + }); $(sSearchAreaId).unblock(); }, 'html' @@ -110,6 +114,19 @@ function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates) return false; // Don't submit the form, stay in the current page ! } + this.UpdateButtons = function(iCount) + { + var okBtn = $('#btn_ok_'+me.id); + if (iCount > 0) + { + okBtn.attr('disabled', ''); + } + else + { + okBtn.attr('disabled', 'disabled'); + } + } + this.DoAddObjects = function() { var theMap = { sAttCode: me.sAttCode, @@ -120,30 +137,59 @@ function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates) } // Gather the parameters from the search form - $('#SearchResultsToAdd_'+me.id+' :checked').each( - function(i) - { - if ( (this.name != '') && ((this.type != 'checkbox') || (this.checked)) ) - { - //console.log(this.type); - arrayExpr = /\[\]$/; - if (arrayExpr.test(this.name)) - { - // Array - if (theMap[this.name] == undefined) - { - theMap[this.name] = new Array(); - } - theMap[this.name].push(this.value); - } - else + var context = $('#SearchResultsToAdd_'+me.id); + var selectionMode = $(':input[name=selectionMode]', context); + if (selectionMode.length > 0) + { + // Paginated table retrieve the mode and the exceptions + var sMode = selectionMode.val(); + theMap['selectionMode'] = sMode; + $('#fs_SearchFormToAdd_'+me.id+' :input').each( + function(i) { theMap[this.name] = this.value; } + ); + theMap['sRemoteClass'] = theMap['class']; // swap 'class' (defined in the form) and 'remoteClass' + theMap['class'] = me.sClass; + $(' :input[name^=storedSelection]', context).each(function() { + if (theMap[this.name] == undefined) + { + theMap[this.name] = new Array(); + } + theMap[this.name].push(this.value); + $(this).remove(); // Remove the selection for the next time the dialog re-opens + }); + } +// else +// { + // Normal table, retrieve all the checked check-boxes + $(':checked[name^=selectObject]', context).each( + function(i) + { + if ( (this.name != '') && ((this.type != 'checkbox') || (this.checked)) ) + { + //console.log(this.type); + arrayExpr = /\[\]$/; + if (arrayExpr.test(this.name)) + { + // Array + if (theMap[this.name] == undefined) + { + theMap[this.name] = new Array(); + } + theMap[this.name].push(this.value); + } + else + { + theMap[this.name] = this.value; + } + } $(this).parents('tr:first').remove(); // Remove the whole line, so that, next time the dialog gets displayed it's no longer there } - } - ); + ); +// } + theMap['operation'] = 'doAddObjects'; $('#busy_'+me.iInputId).html(' '); // Run the query and display the results diff --git a/js/utils.js b/js/utils.js index 6bd130692..900cf7294 100644 --- a/js/utils.js +++ b/js/utils.js @@ -39,12 +39,12 @@ function ReloadTruncatedList(divId, sSerializedFilter, sExtraParams) if (checkbox) { // There is a checkbox in the first column, don't make it sortable - table.tablesorter( { headers: { 0: {sorter: false}}, widgets: ['myZebra', 'truncatedList']} ); // sortable and zebra tables + table.tablesorter( { headers: { 0: {sorter: false}}, widgets: ['myZebra', 'truncatedList']} ).tablesorterPager({container: $("#pager")}); // sortable and zebra tables } else { // There is NO checkbox in the first column, all columns are considered sortable - table.tablesorter( { widgets: ['myZebra', 'truncatedList']} ); // sortable and zebra tables + table.tablesorter( { widgets: ['myZebra', 'truncatedList']} ).tablesorterPager({container: $("#pager"), totalRows:97, filter: sSerializedFilter, extra_params: sExtraParams }); // sortable and zebra tables } }); $('#'+divId).unblock(); @@ -210,10 +210,15 @@ function CheckAll(sSelector, bValue) { var value = bValue; $(sSelector).each( function() { - this.checked = value; + if (this.checked != value) + { + this.checked = value; + $(this).trigger('change'); + } }); } + /** * Toggle (enabled/disabled) the specified field of a form */