-/*\r
- paginate table object v2.0 by frequency-decoder.com\r
-\r
- Released under a creative commons Attribution-ShareAlike 2.5 license (http://creativecommons.org/licenses/by-sa/2.5/)\r
-\r
- Please credit frequency decoder in any derivative work - thanks\r
-\r
- You are free:\r
-\r
- * to copy, distribute, display, and perform the work\r
- * to make derivative works\r
- * to make commercial use of the work\r
-\r
- Under the following conditions:\r
-\r
- by Attribution.\r
- --------------\r
- You must attribute the work in the manner specified by the author or licensor.\r
-\r
- sa\r
- --\r
- Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one.\r
-\r
- * For any reuse or distribution, you must make clear to others the license terms of this work.\r
- * Any of these conditions can be waived if you get permission from the copyright holder.\r
-*/\r
-\r
-var tablePaginater = (function() {\r
- /*\r
-\r
- Localise the button titles here...\r
-\r
- %p is replaced with the appropriate page number\r
- %t is replaced with the total number of pages\r
- \r
- */\r
- var tableInfo = {},\r
- uniqueID = 0,\r
- text = ["First Page","Previous Page (Page %p)","Next Page (Page %p)","Last Page (Page %t)","Page %p of %t"];\r
- \r
- var addClass = function(e,c) {\r
- if(new RegExp("(^|\\s)" + c + "(\\s|$)").test(e.className)) return;\r
- e.className += ( e.className ? " " : "" ) + c;\r
- }; \r
- \r
- /*@cc_on\r
- /*@if (@_win32)\r
- var removeClass = function(e,c) {\r
- e.className = !c ? "" : e.className.replace(new RegExp("(^|\\s)" + c + "(\\s|$)"), " ").replace(/^\s*((?:[\S\s]*\S)?)\s*$/, '$1');\r
- };\r
- @else @*/\r
- var removeClass = function(e,c) { \r
- e.className = !c ? "" : (e.className || "").replace(new RegExp("(^|\\s)" + c + "(\\s|$)"), " ").replace(/^\s\s*/, '').replace(/\s\s*$/, '');\r
- };\r
- /*@end\r
- @*/ \r
- \r
- var addEvent = function(obj, type, fn) {\r
- if( obj.attachEvent ) {\r
- obj["e"+type+fn] = fn;\r
- obj[type+fn] = function(){obj["e"+type+fn]( window.event );};\r
- obj.attachEvent( "on"+type, obj[type+fn] );\r
- } else {\r
- obj.addEventListener( type, fn, true );\r
- };\r
- };\r
- var removeEvent = function(obj, type, fn) {\r
- try {\r
- if( obj.detachEvent ) {\r
- obj.detachEvent( "on"+type, obj[type+fn] );\r
- obj[type+fn] = null;\r
- } else {\r
- obj.removeEventListener( type, fn, true );\r
- };\r
- } catch(err) {};\r
- };\r
- var stopEvent = function(e) {\r
- e = e || window.event;\r
- if(e.stopPropagation) {\r
- e.stopPropagation();\r
- e.preventDefault();\r
- };\r
- \r
- /*@cc_on@*/\r
- /*@if(@_win32)\r
- e.cancelBubble = true;\r
- e.returnValue = false;\r
- /*@end@*/\r
- return false;\r
- }; \r
- \r
- var init = function(tableId) {\r
- var tables = tableId && typeof(tableId) == "string" ? [document.getElementById(tableId)] : document.getElementsByTagName('table'),\r
- hook, maxPages, visibleRows, numPages, cp, cb, rowList;\r
- \r
- for(var t = 0, tbl; tbl = tables[t]; t++) {\r
- if(tbl.className.search(/paginate-([0-9]+)/) == -1) { continue; };\r
-\r
- if(!tbl.id) { tbl.id = "fdUniqueTableId_" + uniqueID++; };\r
-\r
- maxPages = tbl.className.search(/max-pages-([0-9]+)/) == -1 ? null : Number(tbl.className.match(/max-pages-([0-9]+)/)[1]);\r
- if(maxPages % 2 == 0 && maxPages > 1) { maxPages--; };\r
- \r
- hook = tbl.getElementsByTagName('tbody');\r
- hook = (hook.length) ? hook[0] : tbl;\r
-\r
- visibleRows = calculateVisibleRows(hook);\r
- \r
- if(maxPages > (visibleRows / Number(tbl.className.match(/paginate-([0-9]+)/)[1]))) {\r
- maxPages = null;\r
- };\r
- \r
- numPages = Math.ceil(visibleRows / Number(tbl.className.match(/paginate-([0-9]+)/)[1]));\r
- \r
- if(numPages < 2 && !(tbl.id in tableInfo)) {\r
- continue;\r
- };\r
- \r
- cp = (tbl.id in tableInfo) ? Math.min(tableInfo[tbl.id].currentPage, numPages) : 1;\r
- \r
- tableInfo[tbl.id] = {\r
- rowsPerPage:Number(tbl.className.match(/paginate-([0-9]+)/)[1]),\r
- currentPage:cp,\r
- totalRows:hook.getElementsByTagName('tr').length,\r
- hook:hook,\r
- maxPages:maxPages,\r
- numPages:numPages,\r
- rowStyle:tbl.className.search(/rowstyle-([\S]+)/) != -1 ? tbl.className.match(/rowstyle-([\S]+)/)[1] : false,\r
- callbacks:parseCallback(/^paginationcallback-/i, /paginationcallback-([\S-]+)/ig, tbl.className)\r
- };\r
- \r
- showPage(tbl.id);\r
- hook = null;\r
- };\r
- };\r
- \r
- var parseCallback = function(head, regExp, cname) {\r
- var cbs = [],\r
- matchs = cname.match(regExp),\r
- parts, obj, func;\r
- \r
- if(!matchs) { return []; };\r
- \r
- for(var i = 0, mtch; mtch = matchs[i]; i++) { \r
- mtch = mtch.replace(head, "").replace(/-/g, ".");\r
- \r
- try {\r
- if(mtch.indexOf(".") != -1) {\r
- parts = mtch.split('.');\r
- obj = window;\r
- for (var x = 0, part; part = obj[parts[x]]; x++) {\r
- if(part instanceof Function) {\r
- (function() {\r
- var method = part;\r
- func = function (data) { method.apply(obj, [data]) };\r
- })();\r
- } else {\r
- obj = part;\r
- };\r
- };\r
- } else {\r
- func = window[mtch];\r
- };\r
- \r
- if(!(func instanceof Function)) continue;\r
- cbs[cbs.length] = func; \r
- } catch(err) {};\r
- };\r
- \r
- return cbs; \r
- };\r
- \r
- var callback = function(tblId, opts) { \r
- if(!(tblId in tableInfo) || !(tableInfo[tblId]["callbacks"].length)) return; \r
- for(var i = 0, func; func = tableInfo[tblId]["callbacks"][i]; i++) {\r
- func(opts || {});\r
- };\r
- };\r
- \r
- var calculateVisibleRows = function(hook) {\r
- var trs = hook.rows,\r
- cnt = 0,\r
- reg = /(^|\s)invisibleRow(\s|$)/;\r
- \r
- for(var i = 0, tr; tr = trs[i]; i++) {\r
- if(tr.parentNode != hook || tr.getElementsByTagName("th").length || (tr.parentNode && tr.parentNode.tagName.toLowerCase().search(/thead|tfoot/) != -1)) continue;\r
- if(tr.className.search(reg) == -1) { cnt++; };\r
- };\r
- \r
- return cnt;\r
- };\r
- \r
- var createButton = function(details, ul, pseudo) {\r
- var li = document.createElement("li"),\r
- but = document.createElement(pseudo ? "div" : "a"),\r
- span = document.createElement("span");\r
-\r
- if(!pseudo) { \r
- but.href = "#"; \r
- but.title = details.title; \r
- };\r
- \r
- but.className = details.className;\r
-\r
- ul.appendChild(li);\r
- li.appendChild(but);\r
- but.appendChild(span);\r
- span.appendChild(document.createTextNode(details.text));\r
-\r
- if(!pseudo) { \r
- li.onclick = but.onclick = buttonClick; \r
- if(details.id) { but.id = details.id; };\r
- }; \r
- \r
- li = but = span = null;\r
- };\r
- var removePagination = function(tableId) {\r
- var wrapT = document.getElementById(tableId + "-fdtablePaginaterWrapTop"),\r
- wrapB = document.getElementById(tableId + "-fdtablePaginaterWrapBottom");\r
- if(wrapT) { wrapT.parentNode.removeChild(wrapT); };\r
- if(wrapB) { wrapB.parentNode.removeChild(wrapB); };\r
- };\r
- var buildPagination = function(tblId) {\r
- if(!(tblId in tableInfo)) { return; };\r
-\r
- removePagination(tblId);\r
-\r
- var details = tableInfo[tblId];\r
- \r
- if(details.numPages < 2) return;\r
- \r
- function resolveText(txt, curr) {\r
- curr = curr || details.currentPage;\r
- return txt.replace("%p", curr).replace("%t", details.numPages);\r
- };\r
-\r
- if(details.maxPages) {\r
- findex = Math.max(0, Math.floor(Number(details.currentPage - 1) - (Number(details.maxPages - 1) / 2)));\r
- lindex = findex + Number(details.maxPages);\r
- if(lindex > details.numPages) {\r
- lindex = details.numPages;\r
- findex = Math.max(0, details.numPages - Number(details.maxPages));\r
- };\r
- } else {\r
- findex = 0;\r
- lindex = details.numPages;\r
- };\r
- \r
-\r
- var wrapT = document.createElement("div");\r
- wrapT.className = "fdtablePaginaterWrap";\r
- wrapT.id = tblId + "-fdtablePaginaterWrapTop";\r
-\r
- var wrapB = document.createElement("div");\r
- wrapB.className = "fdtablePaginaterWrap";\r
- wrapB.id = tblId + "-fdtablePaginaterWrapBottom";\r
-\r
- // Create list scaffold\r
- var ulT = document.createElement("ul");\r
- ulT.id = tblId + "-tablePaginater";\r
-\r
- var ulB = document.createElement("ul");\r
- ulB.id = tblId + "-tablePaginaterClone";\r
- ulT.className = ulB.className = "fdtablePaginater";\r
-\r
- // Add to the wrapper DIVs\r
- wrapT.appendChild(ulT);\r
- wrapB.appendChild(ulB);\r
-\r
- // FIRST (only created if maxPages set)\r
- if(details.maxPages) {\r
- createButton({title:text[0], className:"first-page", text:"\u00ab"}, ulT, !findex);\r
- createButton({title:text[0], className:"first-page", text:"\u00ab"}, ulB, !findex);\r
- };\r
- \r
- // PREVIOUS (only created if there are more than two pages)\r
- if(details.numPages > 2) {\r
- createButton({title:resolveText(text[1], details.currentPage-1), className:"previous-page", text:"\u2039", id:tblId+"-previousPage"}, ulT, details.currentPage == 1);\r
- createButton({title:resolveText(text[1], details.currentPage-1), className:"previous-page", text:"\u2039", id:tblId+"-previousPageC"}, ulB, details.currentPage == 1);\r
- };\r
- \r
- // NUMBERED\r
- for(var i = findex; i < lindex; i++) {\r
- createButton({title:resolveText(text[4], i+1), className:i != (details.currentPage-1) ? "page-"+(i+1) : "currentPage page-"+(i+1), text:(i+1), id:i == (details.currentPage-1) ? tblId + "-currentPage" : ""}, ulT);\r
- createButton({title:resolveText(text[4], i+1), className:i != (details.currentPage-1) ? "page-"+(i+1) : "currentPage page-"+(i+1), text:(i+1), id:i == (details.currentPage-1) ? tblId + "-currentPageC" : ""}, ulB);\r
- };\r
-\r
- // NEXT (only created if there are more than two pages)\r
- if(details.numPages > 2) {\r
- createButton({title:resolveText(text[2], details.currentPage + 1), className:"next-page", text:"\u203a", id:tblId+"-nextPage"}, ulT, details.currentPage == details.numPages);\r
- createButton({title:resolveText(text[2], details.currentPage + 1), className:"next-page", text:"\u203a", id:tblId+"-nextPageC"}, ulB, details.currentPage == details.numPages);\r
- };\r
- \r
- // LAST (only created if maxPages set)\r
- if(details.maxPages) {\r
- createButton({title:resolveText(text[3], details.numPages), className:"last-page", text:"\u00bb"}, ulT, lindex == details.numPages);\r
- createButton({title:resolveText(text[3], details.numPages), className:"last-page", text:"\u00bb"}, ulB, lindex == details.numPages);\r
- };\r
- \r
- // DOM inject wrapper DIVs (FireFox 2.x Bug: this has to be done here if you use display:table)\r
- if(document.getElementById(tblId+"-paginationListWrapTop")) {\r
- document.getElementById(tblId+"-paginationListWrapTop").appendChild(wrapT);\r
- } else {\r
- document.getElementById(tblId).parentNode.insertBefore(wrapT, document.getElementById(tblId));\r
- };\r
-\r
- if(document.getElementById(tblId+"-paginationListWrapBottom")) {\r
- document.getElementById(tblId+"-paginationListWrapBottom").appendChild(wrapB);\r
- } else {\r
- document.getElementById(tblId).parentNode.insertBefore(wrapB, document.getElementById(tblId).nextSibling);\r
- };\r
- };\r
- \r
- // The tableSort script uses this function to redraw.\r
- var tableSortRedraw = function(tableid, identical) {\r
- if(!tableid || !(tableid in fdTableSort.tableCache) || !(tableid in tableInfo)) { return; };\r
- \r
- var dataObj = fdTableSort.tableCache[tableid],\r
- data = dataObj.data,\r
- len1 = data.length,\r
- len2 = len1 ? data[0].length - 1 : 0,\r
- hook = dataObj.hook,\r
- colStyle = dataObj.colStyle,\r
- rowStyle = dataObj.rowStyle,\r
- colOrder = dataObj.colOrder, \r
- page = tableInfo[tableid].currentPage - 1,\r
- d1 = tableInfo[tableid].rowsPerPage * page,\r
- d2 = Math.min(tableInfo[tableid].totalRows, d1 + tableInfo[tableid].rowsPerPage), \r
- cnt = 0,\r
- rs = 0,\r
- reg = /(^|\s)invisibleRow(\s|$)/, \r
- tr, tds, cell, pos;\r
- \r
- for(var i = 0; i < len1; i++) {\r
- tr = data[i][len2];\r
- \r
- if(colStyle) {\r
- tds = tr.cells;\r
- for(thPos in colOrder) {\r
- if(!colOrder[thPos]) removeClass(tds[thPos], colStyle);\r
- else addClass(tds[thPos], colStyle);\r
- };\r
- };\r
- \r
- if(tr.className.search(reg) != -1) { continue; };\r
- \r
- if(!identical) {\r
- cnt++;\r
-\r
- if(cnt > d1 && cnt <= d2) {\r
- if(rowStyle) {\r
- if(rs++ & 1) addClass(tr, rowStyle);\r
- else removeClass(tr, rowStyle);\r
- };\r
- tr.style.display = "";\r
- } else {\r
- tr.style.display = "none";\r
- };\r
-\r
- // Netscape 8.1.2 requires the removeChild call or it freaks out, so add the line if you want to support this browser\r
- // hook.removeChild(tr);\r
- hook.appendChild(tr);\r
- };\r
- };\r
-\r
- tr = tds = hook = null;\r
- };\r
- \r
- var showPage = function(tblId, pageNum) {\r
- if(!(tblId in tableInfo)) { return; };\r
-\r
- var page = Math.max(0, !pageNum ? tableInfo[tblId].currentPage - 1 : pageNum - 1),\r
- d1 = tableInfo[tblId].rowsPerPage * page,\r
- d2 = Math.min(tableInfo[tblId].totalRows, d1 + tableInfo[tblId].rowsPerPage),\r
- trs = tableInfo[tblId].hook.rows,\r
- cnt = 0,\r
- rc = 0,\r
- len = trs.length,\r
- rs = tableInfo[tblId].rowStyle,\r
- reg = /(^|\s)invisibleRow(\s|$)/,\r
- row = [];\r
- \r
- for(var i = 0; i < len; i++) {\r
- if(trs[i].className.search(reg) != -1 || trs[i].getElementsByTagName("th").length || (trs[i].parentNode && trs[i].parentNode.tagName.toLowerCase().search(/thead|tfoot/) != -1)) { continue; };\r
- \r
- cnt++;\r
- \r
- if(cnt > d1 && cnt <= d2) {\r
- if(rs) {\r
- if(rc++ & 1) {\r
- addClass(trs[i], rs);\r
- } else {\r
- removeClass(trs[i], rs);\r
- }\r
- };\r
- trs[i].style.display = "";\r
- row[row.length] = trs[i];\r
- } else {\r
- trs[i].style.display = "none";\r
- };\r
- };\r
-\r
- buildPagination(tblId);\r
- callback(tblId, {"totalRows":len, "currentPage":(page+1), "rowsPerPage":tableInfo[tblId].rowsPerPage, "visibleRows":row});\r
- };\r
- \r
- var buttonClick = function(e) {\r
- e = e || window.event;\r
-\r
- var a = this.tagName.toLowerCase() == "a" ? this : this.getElementsByTagName("a")[0];\r
-\r
- if(a.className.search("currentPage") != -1) return false;\r
-\r
- var ul = this;\r
- while(ul.tagName.toLowerCase() != "ul") ul = ul.parentNode;\r
-\r
- var tblId = ul.id.replace("-tablePaginaterClone","").replace("-tablePaginater", "");\r
-\r
- tableInfo[tblId].lastPage = tableInfo[tblId].currentPage;\r
- \r
- var showPrevNext = 0;\r
- \r
- if(a.className.search("previous-page") != -1) {\r
- tableInfo[tblId].currentPage = tableInfo[tblId].currentPage > 1 ? tableInfo[tblId].currentPage - 1 : tableInfo[tblId].numPages;\r
- showPrevNext = 1;\r
- } else if(a.className.search("next-page") != -1) {\r
- tableInfo[tblId].currentPage = tableInfo[tblId].currentPage < tableInfo[tblId].numPages ? tableInfo[tblId].currentPage + 1 : 1;\r
- showPrevNext = 2;\r
- } else if(a.className.search("first-page") != -1) {\r
- tableInfo[tblId].currentPage = 1;\r
- } else if(a.className.search("last-page") != -1) {\r
- tableInfo[tblId].currentPage = tableInfo[tblId].numPages;\r
- } else {\r
- tableInfo[tblId].currentPage = parseInt(a.className.match(/page-([0-9]+)/)[1]) || 1;\r
- };\r
-\r
- showPage(tblId);\r
-\r
- // Focus on the appropriate button (previous, next or the current page)\r
- // I'm hoping screen readers are savvy enough to indicate the focus event to the user\r
- if(showPrevNext == 1) {\r
- var elem = document.getElementById(ul.id.search("-tablePaginaterClone") != -1 ? tblId + "-previousPageC" : tblId + "-previousPage");\r
- } else if(showPrevNext == 2) {\r
- var elem = document.getElementById(ul.id.search("-tablePaginaterClone") != -1 ? tblId + "-nextPageC" : tblId + "-nextPage");\r
- } else {\r
- var elem = document.getElementById(ul.id.search("-tablePaginaterClone") != -1 ? tblId + "-currentPageC" : tblId + "-currentPage");\r
- };\r
- \r
- if(elem && elem.tagName.toLowerCase() == "a") { elem.focus(); }; \r
- \r
- return stopEvent(e);\r
- };\r
- \r
- var onUnLoad = function(e) {\r
- var tbl, lis, pagination, uls;\r
- for(tblId in tableInfo) {\r
- uls = [tblId + "-tablePaginater", tblId + "-tablePaginaterClone"];\r
- for(var z = 0; z < 2; z++) {\r
- pagination = document.getElementById(uls[z]);\r
- if(!pagination) { continue; };\r
- lis = pagination.getElementsByTagName("li");\r
- for(var i = 0, li; li = lis[i]; i++) {\r
- li.onclick = null;\r
- if(li.getElementsByTagName("a").length) { li.getElementsByTagName("a")[0].onclick = null; };\r
- };\r
- };\r
- };\r
- };\r
- \r
- addEvent(window, "load", init);\r
- addEvent(window, "unload", onUnLoad); \r
- \r
- return { \r
- init: function(tableId) { init(tableId); }, \r
- redraw: function(tableid, identical) { tableSortRedraw(tableid, identical); },\r
- tableIsPaginated: function(tableId) { return (tableId in tableInfo); },\r
- changeTranslations: function(translations) { text = translations; }\r
- }; \r
+/*
+ paginate table object v2.0 by frequency-decoder.com
+
+ Released under a creative commons Attribution-ShareAlike 2.5 license (http://creativecommons.org/licenses/by-sa/2.5/)
+
+ Please credit frequency decoder in any derivative work - thanks
+
+ You are free:
+
+ * to copy, distribute, display, and perform the work
+ * to make derivative works
+ * to make commercial use of the work
+
+ Under the following conditions:
+
+ by Attribution.
+ --------------
+ You must attribute the work in the manner specified by the author or licensor.
+
+ sa
+ --
+ Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one.
+
+ * For any reuse or distribution, you must make clear to others the license terms of this work.
+ * Any of these conditions can be waived if you get permission from the copyright holder.
+*/
+
+var tablePaginater = (function() {
+ /*
+
+ Localise the button titles here...
+
+ %p is replaced with the appropriate page number
+ %t is replaced with the total number of pages
+
+ */
+ var tableInfo = {},
+ uniqueID = 0,
+ text = ["First Page","Previous Page (Page %p)","Next Page (Page %p)","Last Page (Page %t)","Page %p of %t"];
+
+ var addClass = function(e,c) {
+ if(new RegExp("(^|\\s)" + c + "(\\s|$)").test(e.className)) return;
+ e.className += ( e.className ? " " : "" ) + c;
+ };
+
+ /*@cc_on
+ /*@if (@_win32)
+ var removeClass = function(e,c) {
+ e.className = !c ? "" : e.className.replace(new RegExp("(^|\\s)" + c + "(\\s|$)"), " ").replace(/^\s*((?:[\S\s]*\S)?)\s*$/, '$1');
+ };
+ @else @*/
+ var removeClass = function(e,c) {
+ e.className = !c ? "" : (e.className || "").replace(new RegExp("(^|\\s)" + c + "(\\s|$)"), " ").replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+ /*@end
+ @*/
+
+ var addEvent = function(obj, type, fn) {
+ if( obj.attachEvent ) {
+ obj["e"+type+fn] = fn;
+ obj[type+fn] = function(){obj["e"+type+fn]( window.event );};
+ obj.attachEvent( "on"+type, obj[type+fn] );
+ } else {
+ obj.addEventListener( type, fn, true );
+ };
+ };
+ var removeEvent = function(obj, type, fn) {
+ try {
+ if( obj.detachEvent ) {
+ obj.detachEvent( "on"+type, obj[type+fn] );
+ obj[type+fn] = null;
+ } else {
+ obj.removeEventListener( type, fn, true );
+ };
+ } catch(err) {};
+ };
+ var stopEvent = function(e) {
+ e = e || window.event;
+ if(e.stopPropagation) {
+ e.stopPropagation();
+ e.preventDefault();
+ };
+
+ /*@cc_on@*/
+ /*@if(@_win32)
+ e.cancelBubble = true;
+ e.returnValue = false;
+ /*@end@*/
+ return false;
+ };
+
+ var init = function(tableId) {
+ var tables = tableId && typeof(tableId) == "string" ? [document.getElementById(tableId)] : document.getElementsByTagName('table'),
+ hook, maxPages, visibleRows, numPages, cp, cb, rowList;
+
+ for(var t = 0, tbl; tbl = tables[t]; t++) {
+ if(tbl.className.search(/paginate-([0-9]+)/) == -1) { continue; };
+
+ if(!tbl.id) { tbl.id = "fdUniqueTableId_" + uniqueID++; };
+
+ maxPages = tbl.className.search(/max-pages-([0-9]+)/) == -1 ? null : Number(tbl.className.match(/max-pages-([0-9]+)/)[1]);
+ if(maxPages % 2 == 0 && maxPages > 1) { maxPages--; };
+
+ hook = tbl.getElementsByTagName('tbody');
+ hook = (hook.length) ? hook[0] : tbl;
+
+ visibleRows = calculateVisibleRows(hook);
+
+ if(maxPages > (visibleRows / Number(tbl.className.match(/paginate-([0-9]+)/)[1]))) {
+ maxPages = null;
+ };
+
+ numPages = Math.ceil(visibleRows / Number(tbl.className.match(/paginate-([0-9]+)/)[1]));
+
+ if(numPages < 2 && !(tbl.id in tableInfo)) {
+ continue;
+ };
+
+ cp = (tbl.id in tableInfo) ? Math.min(tableInfo[tbl.id].currentPage, numPages) : 1;
+
+ tableInfo[tbl.id] = {
+ rowsPerPage:Number(tbl.className.match(/paginate-([0-9]+)/)[1]),
+ currentPage:cp,
+ totalRows:hook.getElementsByTagName('tr').length,
+ hook:hook,
+ maxPages:maxPages,
+ numPages:numPages,
+ rowStyle:tbl.className.search(/rowstyle-([\S]+)/) != -1 ? tbl.className.match(/rowstyle-([\S]+)/)[1] : false,
+ callbacks:parseCallback(/^paginationcallback-/i, /paginationcallback-([\S-]+)/ig, tbl.className)
+ };
+
+ showPage(tbl.id);
+ hook = null;
+ };
+ };
+
+ var parseCallback = function(head, regExp, cname) {
+ var cbs = [],
+ matchs = cname.match(regExp),
+ parts, obj, func;
+
+ if(!matchs) { return []; };
+
+ for(var i = 0, mtch; mtch = matchs[i]; i++) {
+ mtch = mtch.replace(head, "").replace(/-/g, ".");
+
+ try {
+ if(mtch.indexOf(".") != -1) {
+ parts = mtch.split('.');
+ obj = window;
+ for (var x = 0, part; part = obj[parts[x]]; x++) {
+ if(part instanceof Function) {
+ (function() {
+ var method = part;
+ func = function (data) { method.apply(obj, [data]) };
+ })();
+ } else {
+ obj = part;
+ };
+ };
+ } else {
+ func = window[mtch];
+ };
+
+ if(!(func instanceof Function)) continue;
+ cbs[cbs.length] = func;
+ } catch(err) {};
+ };
+
+ return cbs;
+ };
+
+ var callback = function(tblId, opts) {
+ if(!(tblId in tableInfo) || !(tableInfo[tblId]["callbacks"].length)) return;
+ for(var i = 0, func; func = tableInfo[tblId]["callbacks"][i]; i++) {
+ func(opts || {});
+ };
+ };
+
+ var calculateVisibleRows = function(hook) {
+ var trs = hook.rows,
+ cnt = 0,
+ reg = /(^|\s)invisibleRow(\s|$)/;
+
+ for(var i = 0, tr; tr = trs[i]; i++) {
+ if(tr.parentNode != hook || tr.getElementsByTagName("th").length || (tr.parentNode && tr.parentNode.tagName.toLowerCase().search(/thead|tfoot/) != -1)) continue;
+ if(tr.className.search(reg) == -1) { cnt++; };
+ };
+
+ return cnt;
+ };
+
+ var createButton = function(details, ul, pseudo) {
+ var li = document.createElement("li"),
+ but = document.createElement(pseudo ? "div" : "a"),
+ span = document.createElement("span");
+
+ if(!pseudo) {
+ but.href = "#";
+ but.title = details.title;
+ };
+
+ but.className = details.className;
+
+ ul.appendChild(li);
+ li.appendChild(but);
+ but.appendChild(span);
+ span.appendChild(document.createTextNode(details.text));
+
+ if(!pseudo) {
+ li.onclick = but.onclick = buttonClick;
+ if(details.id) { but.id = details.id; };
+ };
+
+ li = but = span = null;
+ };
+ var removePagination = function(tableId) {
+ var wrapT = document.getElementById(tableId + "-fdtablePaginaterWrapTop"),
+ wrapB = document.getElementById(tableId + "-fdtablePaginaterWrapBottom");
+ if(wrapT) { wrapT.parentNode.removeChild(wrapT); };
+ if(wrapB) { wrapB.parentNode.removeChild(wrapB); };
+ };
+ var buildPagination = function(tblId) {
+ if(!(tblId in tableInfo)) { return; };
+
+ removePagination(tblId);
+
+ var details = tableInfo[tblId];
+
+ if(details.numPages < 2) return;
+
+ function resolveText(txt, curr) {
+ curr = curr || details.currentPage;
+ return txt.replace("%p", curr).replace("%t", details.numPages);
+ };
+
+ if(details.maxPages) {
+ findex = Math.max(0, Math.floor(Number(details.currentPage - 1) - (Number(details.maxPages - 1) / 2)));
+ lindex = findex + Number(details.maxPages);
+ if(lindex > details.numPages) {
+ lindex = details.numPages;
+ findex = Math.max(0, details.numPages - Number(details.maxPages));
+ };
+ } else {
+ findex = 0;
+ lindex = details.numPages;
+ };
+
+
+ var wrapT = document.createElement("div");
+ wrapT.className = "fdtablePaginaterWrap";
+ wrapT.id = tblId + "-fdtablePaginaterWrapTop";
+
+ var wrapB = document.createElement("div");
+ wrapB.className = "fdtablePaginaterWrap";
+ wrapB.id = tblId + "-fdtablePaginaterWrapBottom";
+
+ // Create list scaffold
+ var ulT = document.createElement("ul");
+ ulT.id = tblId + "-tablePaginater";
+
+ var ulB = document.createElement("ul");
+ ulB.id = tblId + "-tablePaginaterClone";
+ ulT.className = ulB.className = "fdtablePaginater";
+
+ // Add to the wrapper DIVs
+ wrapT.appendChild(ulT);
+ wrapB.appendChild(ulB);
+
+ // FIRST (only created if maxPages set)
+ if(details.maxPages) {
+ createButton({title:text[0], className:"first-page", text:"\u00ab"}, ulT, !findex);
+ createButton({title:text[0], className:"first-page", text:"\u00ab"}, ulB, !findex);
+ };
+
+ // PREVIOUS (only created if there are more than two pages)
+ if(details.numPages > 2) {
+ createButton({title:resolveText(text[1], details.currentPage-1), className:"previous-page", text:"\u2039", id:tblId+"-previousPage"}, ulT, details.currentPage == 1);
+ createButton({title:resolveText(text[1], details.currentPage-1), className:"previous-page", text:"\u2039", id:tblId+"-previousPageC"}, ulB, details.currentPage == 1);
+ };
+
+ // NUMBERED
+ for(var i = findex; i < lindex; i++) {
+ createButton({title:resolveText(text[4], i+1), className:i != (details.currentPage-1) ? "page-"+(i+1) : "currentPage page-"+(i+1), text:(i+1), id:i == (details.currentPage-1) ? tblId + "-currentPage" : ""}, ulT);
+ createButton({title:resolveText(text[4], i+1), className:i != (details.currentPage-1) ? "page-"+(i+1) : "currentPage page-"+(i+1), text:(i+1), id:i == (details.currentPage-1) ? tblId + "-currentPageC" : ""}, ulB);
+ };
+
+ // NEXT (only created if there are more than two pages)
+ if(details.numPages > 2) {
+ createButton({title:resolveText(text[2], details.currentPage + 1), className:"next-page", text:"\u203a", id:tblId+"-nextPage"}, ulT, details.currentPage == details.numPages);
+ createButton({title:resolveText(text[2], details.currentPage + 1), className:"next-page", text:"\u203a", id:tblId+"-nextPageC"}, ulB, details.currentPage == details.numPages);
+ };
+
+ // LAST (only created if maxPages set)
+ if(details.maxPages) {
+ createButton({title:resolveText(text[3], details.numPages), className:"last-page", text:"\u00bb"}, ulT, lindex == details.numPages);
+ createButton({title:resolveText(text[3], details.numPages), className:"last-page", text:"\u00bb"}, ulB, lindex == details.numPages);
+ };
+
+ // DOM inject wrapper DIVs (FireFox 2.x Bug: this has to be done here if you use display:table)
+ if(document.getElementById(tblId+"-paginationListWrapTop")) {
+ document.getElementById(tblId+"-paginationListWrapTop").appendChild(wrapT);
+ } else {
+ document.getElementById(tblId).parentNode.insertBefore(wrapT, document.getElementById(tblId));
+ };
+
+ if(document.getElementById(tblId+"-paginationListWrapBottom")) {
+ document.getElementById(tblId+"-paginationListWrapBottom").appendChild(wrapB);
+ } else {
+ document.getElementById(tblId).parentNode.insertBefore(wrapB, document.getElementById(tblId).nextSibling);
+ };
+ };
+
+ // The tableSort script uses this function to redraw.
+ var tableSortRedraw = function(tableid, identical) {
+ if(!tableid || !(tableid in fdTableSort.tableCache) || !(tableid in tableInfo)) { return; };
+
+ var dataObj = fdTableSort.tableCache[tableid],
+ data = dataObj.data,
+ len1 = data.length,
+ len2 = len1 ? data[0].length - 1 : 0,
+ hook = dataObj.hook,
+ colStyle = dataObj.colStyle,
+ rowStyle = dataObj.rowStyle,
+ colOrder = dataObj.colOrder,
+ page = tableInfo[tableid].currentPage - 1,
+ d1 = tableInfo[tableid].rowsPerPage * page,
+ d2 = Math.min(tableInfo[tableid].totalRows, d1 + tableInfo[tableid].rowsPerPage),
+ cnt = 0,
+ rs = 0,
+ reg = /(^|\s)invisibleRow(\s|$)/,
+ tr, tds, cell, pos;
+
+ for(var i = 0; i < len1; i++) {
+ tr = data[i][len2];
+
+ if(colStyle) {
+ tds = tr.cells;
+ for(thPos in colOrder) {
+ if(!colOrder[thPos]) removeClass(tds[thPos], colStyle);
+ else addClass(tds[thPos], colStyle);
+ };
+ };
+
+ if(tr.className.search(reg) != -1) { continue; };
+
+ if(!identical) {
+ cnt++;
+
+ if(cnt > d1 && cnt <= d2) {
+ if(rowStyle) {
+ if(rs++ & 1) addClass(tr, rowStyle);
+ else removeClass(tr, rowStyle);
+ };
+ tr.style.display = "";
+ } else {
+ tr.style.display = "none";
+ };
+
+ // Netscape 8.1.2 requires the removeChild call or it freaks out, so add the line if you want to support this browser
+ // hook.removeChild(tr);
+ hook.appendChild(tr);
+ };
+ };
+
+ tr = tds = hook = null;
+ };
+
+ var showPage = function(tblId, pageNum) {
+ if(!(tblId in tableInfo)) { return; };
+
+ var page = Math.max(0, !pageNum ? tableInfo[tblId].currentPage - 1 : pageNum - 1),
+ d1 = tableInfo[tblId].rowsPerPage * page,
+ d2 = Math.min(tableInfo[tblId].totalRows, d1 + tableInfo[tblId].rowsPerPage),
+ trs = tableInfo[tblId].hook.rows,
+ cnt = 0,
+ rc = 0,
+ len = trs.length,
+ rs = tableInfo[tblId].rowStyle,
+ reg = /(^|\s)invisibleRow(\s|$)/,
+ row = [];
+
+ for(var i = 0; i < len; i++) {
+ if(trs[i].className.search(reg) != -1 || trs[i].getElementsByTagName("th").length || (trs[i].parentNode && trs[i].parentNode.tagName.toLowerCase().search(/thead|tfoot/) != -1)) { continue; };
+
+ cnt++;
+
+ if(cnt > d1 && cnt <= d2) {
+ if(rs) {
+ if(rc++ & 1) {
+ addClass(trs[i], rs);
+ } else {
+ removeClass(trs[i], rs);
+ }
+ };
+ trs[i].style.display = "";
+ row[row.length] = trs[i];
+ } else {
+ trs[i].style.display = "none";
+ };
+ };
+
+ buildPagination(tblId);
+ callback(tblId, {"totalRows":len, "currentPage":(page+1), "rowsPerPage":tableInfo[tblId].rowsPerPage, "visibleRows":row});
+ };
+
+ var buttonClick = function(e) {
+ e = e || window.event;
+
+ var a = this.tagName.toLowerCase() == "a" ? this : this.getElementsByTagName("a")[0];
+
+ if(a.className.search("currentPage") != -1) return false;
+
+ var ul = this;
+ while(ul.tagName.toLowerCase() != "ul") ul = ul.parentNode;
+
+ var tblId = ul.id.replace("-tablePaginaterClone","").replace("-tablePaginater", "");
+
+ tableInfo[tblId].lastPage = tableInfo[tblId].currentPage;
+
+ var showPrevNext = 0;
+
+ if(a.className.search("previous-page") != -1) {
+ tableInfo[tblId].currentPage = tableInfo[tblId].currentPage > 1 ? tableInfo[tblId].currentPage - 1 : tableInfo[tblId].numPages;
+ showPrevNext = 1;
+ } else if(a.className.search("next-page") != -1) {
+ tableInfo[tblId].currentPage = tableInfo[tblId].currentPage < tableInfo[tblId].numPages ? tableInfo[tblId].currentPage + 1 : 1;
+ showPrevNext = 2;
+ } else if(a.className.search("first-page") != -1) {
+ tableInfo[tblId].currentPage = 1;
+ } else if(a.className.search("last-page") != -1) {
+ tableInfo[tblId].currentPage = tableInfo[tblId].numPages;
+ } else {
+ tableInfo[tblId].currentPage = parseInt(a.className.match(/page-([0-9]+)/)[1]) || 1;
+ };
+
+ showPage(tblId);
+
+ // Focus on the appropriate button (previous, next or the current page)
+ // I'm hoping screen readers are savvy enough to indicate the focus event to the user
+ if(showPrevNext == 1) {
+ var elem = document.getElementById(ul.id.search("-tablePaginaterClone") != -1 ? tblId + "-previousPageC" : tblId + "-previousPage");
+ } else if(showPrevNext == 2) {
+ var elem = document.getElementById(ul.id.search("-tablePaginaterClone") != -1 ? tblId + "-nextPageC" : tblId + "-nextPage");
+ } else {
+ var elem = document.getElementById(ul.id.search("-tablePaginaterClone") != -1 ? tblId + "-currentPageC" : tblId + "-currentPage");
+ };
+
+ if(elem && elem.tagName.toLowerCase() == "a") { elem.focus(); };
+
+ return stopEvent(e);
+ };
+
+ var onUnLoad = function(e) {
+ var tbl, lis, pagination, uls;
+ for(tblId in tableInfo) {
+ uls = [tblId + "-tablePaginater", tblId + "-tablePaginaterClone"];
+ for(var z = 0; z < 2; z++) {
+ pagination = document.getElementById(uls[z]);
+ if(!pagination) { continue; };
+ lis = pagination.getElementsByTagName("li");
+ for(var i = 0, li; li = lis[i]; i++) {
+ li.onclick = null;
+ if(li.getElementsByTagName("a").length) { li.getElementsByTagName("a")[0].onclick = null; };
+ };
+ };
+ };
+ };
+
+ addEvent(window, "load", init);
+ addEvent(window, "unload", onUnLoad);
+
+ return {
+ init: function(tableId) { init(tableId); },
+ redraw: function(tableid, identical) { tableSortRedraw(tableid, identical); },
+ tableIsPaginated: function(tableId) { return (tableId in tableInfo); },
+ changeTranslations: function(translations) { text = translations; }
+ };
})();
\ No newline at end of file