| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151 |
- // Production steps of ECMA-262, Edition 5, 15.4.4.18
- // Reference: http://es5.github.io/#x15.4.4.18
- if (!Array.prototype.forEach) {
- Array.prototype.forEach = function(callback, thisArg) {
- var T, k;
- if (this === null) {
- throw new TypeError(' this is null or not defined');
- }
- // 1. Let O be the result of calling toObject() passing the
- // |this| value as the argument.
- var O = Object(this);
- // 2. Let lenValue be the result of calling the Get() internal
- // method of O with the argument "length".
- // 3. Let len be toUint32(lenValue).
- var len = O.length >>> 0;
- // 4. If isCallable(callback) is false, throw a TypeError exception.
- // See: http://es5.github.com/#x9.11
- if (typeof callback !== "function") {
- throw new TypeError(callback + ' is not a function');
- }
- // 5. If thisArg was supplied, let T be thisArg; else let
- // T be undefined.
- if (arguments.length > 1) {
- T = thisArg;
- }
- // 6. Let k be 0
- k = 0;
- // 7. Repeat, while k < len
- while (k < len) {
- var kValue;
- // a. Let Pk be ToString(k).
- // This is implicit for LHS operands of the in operator
- // b. Let kPresent be the result of calling the HasProperty
- // internal method of O with argument Pk.
- // This step can be combined with c
- // c. If kPresent is true, then
- if (k in O) {
- // i. Let kValue be the result of calling the Get internal
- // method of O with argument Pk.
- kValue = O[k];
- // ii. Call the Call internal method of callback with T as
- // the this value and argument list containing kValue, k, and O.
- callback.call(T, kValue, k, O);
- }
- // d. Increase k by 1.
- k++;
- }
- // 8. return undefined
- };
- }
- // Production steps of ECMA-262, Edition 5, 15.4.4.19
- // Reference: http://es5.github.io/#x15.4.4.19
- if (!Array.prototype.map) {
- Array.prototype.map = function(callback, thisArg) {
- var T, A, k;
- if (this == null) {
- throw new TypeError(' this is null or not defined');
- }
- // 1. Let O be the result of calling ToObject passing the |this|
- // value as the argument.
- var O = Object(this);
- // 2. Let lenValue be the result of calling the Get internal
- // method of O with the argument "length".
- // 3. Let len be ToUint32(lenValue).
- var len = O.length >>> 0;
- // 4. If IsCallable(callback) is false, throw a TypeError exception.
- // See: http://es5.github.com/#x9.11
- if (typeof callback !== 'function') {
- throw new TypeError(callback + ' is not a function');
- }
- // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
- if (arguments.length > 1) {
- T = thisArg;
- }
- // 6. Let A be a new array created as if by the expression new Array(len)
- // where Array is the standard built-in constructor with that name and
- // len is the value of len.
- A = new Array(len);
- // 7. Let k be 0
- k = 0;
- // 8. Repeat, while k < len
- while (k < len) {
- var kValue, mappedValue;
- // a. Let Pk be ToString(k).
- // This is implicit for LHS operands of the in operator
- // b. Let kPresent be the result of calling the HasProperty internal
- // method of O with argument Pk.
- // This step can be combined with c
- // c. If kPresent is true, then
- if (k in O) {
- // i. Let kValue be the result of calling the Get internal
- // method of O with argument Pk.
- kValue = O[k];
- // ii. Let mappedValue be the result of calling the Call internal
- // method of callback with T as the this value and argument
- // list containing kValue, k, and O.
- mappedValue = callback.call(T, kValue, k, O);
- // iii. Call the DefineOwnProperty internal method of A with arguments
- // Pk, Property Descriptor
- // { Value: mappedValue,
- // Writable: true,
- // Enumerable: true,
- // Configurable: true },
- // and false.
- // In browsers that support Object.defineProperty, use the following:
- // Object.defineProperty(A, k, {
- // value: mappedValue,
- // writable: true,
- // enumerable: true,
- // configurable: true
- // });
- // For best browser support, use the following:
- A[k] = mappedValue;
- }
- // d. Increase k by 1.
- k++;
- }
- // 9. return A
- return A;
- };
- }
- var PagedTable = function (pagedTable) {
- var me = this;
- var source = function(pagedTable) {
- var sourceElems = [].slice.call(pagedTable.children).filter(function(e) {
- return e.hasAttribute("data-pagedtable-source");
- });
- if (sourceElems === null || sourceElems.length !== 1) {
- throw("A single data-pagedtable-source was not found");
- }
- return JSON.parse(sourceElems[0].innerHTML);
- }(pagedTable);
- var options = function(source) {
- var options = typeof(source.options) !== "undefined" &&
- source.options !== null ? source.options : {};
- var columns = typeof(options.columns) !== "undefined" ? options.columns : {};
- var rows = typeof(options.rows) !== "undefined" ? options.rows : {};
- var positiveIntOrNull = function(value) {
- return parseInt(value) >= 0 ? parseInt(value) : null;
- };
- return {
- pages: positiveIntOrNull(options.pages),
- rows: {
- min: positiveIntOrNull(rows.min),
- max: positiveIntOrNull(rows.max),
- total: positiveIntOrNull(rows.total)
- },
- columns: {
- min: positiveIntOrNull(columns.min),
- max: positiveIntOrNull(columns.max),
- total: positiveIntOrNull(columns.total)
- }
- };
- }(source);
- var Measurer = function() {
- // set some default initial values that will get adjusted in runtime
- me.measures = {
- padding: 12,
- character: 8,
- height: 15,
- defaults: true
- };
- me.calculate = function(measuresCell) {
- if (!me.measures.defaults)
- return;
- var measuresCellStyle = window.getComputedStyle(measuresCell, null);
- var newPadding = parsePadding(measuresCellStyle.paddingLeft) +
- parsePadding(measuresCellStyle.paddingRight);
- var sampleString = "ABCDEFGHIJ0123456789";
- var newCharacter = Math.ceil(measuresCell.clientWidth / sampleString.length);
- if (newPadding <= 0 || newCharacter <= 0)
- return;
- me.measures.padding = newPadding;
- me.measures.character = newCharacter;
- me.measures.height = measuresCell.clientHeight;
- me.measures.defaults = false;
- };
- return me;
- };
- var Page = function(data, options) {
- var me = this;
- var defaults = {
- max: 7,
- rows: 10
- };
- var totalPages = function() {
- return Math.ceil(data.length / me.rows);
- };
- me.number = 0;
- me.max = options.pages !== null ? options.pages : defaults.max;
- me.visible = me.max;
- me.rows = options.rows.min !== null ? options.rows.min : defaults.rows;
- me.total = totalPages();
- me.setRows = function(newRows) {
- me.rows = newRows;
- me.total = totalPages();
- };
- me.setPageNumber = function(newPageNumber) {
- if (newPageNumber < 0) newPageNumber = 0;
- if (newPageNumber >= me.total) newPageNumber = me.total - 1;
- me.number = newPageNumber;
- };
- me.setVisiblePages = function(visiblePages) {
- me.visible = Math.min(me.max, visiblePages);
- me.setPageNumber(me.number);
- };
- me.getVisiblePageRange = function() {
- var start = me.number - Math.max(Math.floor((me.visible - 1) / 2), 0);
- var end = me.number + Math.floor(me.visible / 2) + 1;
- var pageCount = me.total;
- if (start < 0) {
- var diffToStart = 0 - start;
- start += diffToStart;
- end += diffToStart;
- }
- if (end > pageCount) {
- var diffToEnd = end - pageCount;
- start -= diffToEnd;
- end -= diffToEnd;
- }
- start = start < 0 ? 0 : start;
- end = end >= pageCount ? pageCount : end;
- var first = false;
- var last = false;
- if (start > 0 && me.visible > 1) {
- start = start + 1;
- first = true;
- }
- if (end < pageCount && me.visible > 2) {
- end = end - 1;
- last = true;
- }
- return {
- first: first,
- start: start,
- end: end,
- last: last
- };
- };
- me.getRowStart = function() {
- var rowStart = page.number * page.rows;
- if (rowStart < 0)
- rowStart = 0;
- return rowStart;
- };
- me.getRowEnd = function() {
- var rowStart = me.getRowStart();
- return Math.min(rowStart + me.rows, data.length);
- };
- me.getPaddingRows = function() {
- var rowStart = me.getRowStart();
- var rowEnd = me.getRowEnd();
- return data.length > me.rows ? me.rows - (rowEnd - rowStart) : 0;
- };
- };
- var Columns = function(data, columns, options) {
- var me = this;
- me.defaults = {
- min: 5
- };
- me.number = 0;
- me.visible = 0;
- me.total = columns.length;
- me.subset = [];
- me.padding = 0;
- me.min = options.columns.min !== null ? options.columns.min : me.defaults.min;
- me.max = options.columns.max !== null ? options.columns.max : null;
- me.widths = {};
- var widthsLookAhead = Math.max(100, options.rows.min);
- var paddingColChars = 10;
- me.emptyNames = function() {
- columns.forEach(function(column) {
- if (columns.label !== null && columns.label !== "")
- return false;
- });
- return true;
- };
- var parsePadding = function(value) {
- return parseInt(value) >= 0 ? parseInt(value) : 0;
- };
- me.calculateWidths = function(measures) {
- columns.forEach(function(column) {
- var maxChars = Math.max(
- column.label.toString().length,
- column.type.toString().length
- );
- for (var idxRow = 0; idxRow < Math.min(widthsLookAhead, data.length); idxRow++) {
- maxChars = Math.max(maxChars, data[idxRow][column.name.toString()].length);
- }
- me.widths[column.name] = {
- // width in characters
- chars: maxChars,
- // width for the inner html columns
- inner: maxChars * measures.character,
- // width adding outer styles like padding
- outer: maxChars * measures.character + measures.padding
- };
- });
- };
- me.getWidth = function() {
- var widthOuter = 0;
- for (var idxCol = 0; idxCol < me.subset.length; idxCol++) {
- var columnName = me.subset[idxCol].name;
- widthOuter = widthOuter + me.widths[columnName].outer;
- }
- widthOuter = widthOuter + me.padding * paddingColChars * measurer.measures.character;
- if (me.hasMoreLeftColumns()) {
- widthOuter = widthOuter + columnNavigationWidthPX + measurer.measures.padding;
- }
- if (me.hasMoreRightColumns()) {
- widthOuter = widthOuter + columnNavigationWidthPX + measurer.measures.padding;
- }
- return widthOuter;
- };
- me.updateSlice = function() {
- if (me.number + me.visible >= me.total)
- me.number = me.total - me.visible;
- if (me.number < 0) me.number = 0;
- me.subset = columns.slice(me.number, Math.min(me.number + me.visible, me.total));
- me.subset = me.subset.map(function(column) {
- Object.keys(column).forEach(function(colKey) {
- column[colKey] = column[colKey] === null ? "" : column[colKey].toString();
- });
- column.width = null;
- return column;
- });
- };
- me.setVisibleColumns = function(columnNumber, newVisibleColumns, paddingCount) {
- me.number = columnNumber;
- me.visible = newVisibleColumns;
- me.padding = paddingCount;
- me.updateSlice();
- };
- me.incColumnNumber = function(increment) {
- me.number = me.number + increment;
- };
- me.setColumnNumber = function(newNumber) {
- me.number = newNumber;
- };
- me.setPaddingCount = function(newPadding) {
- me.padding = newPadding;
- };
- me.getPaddingCount = function() {
- return me.padding;
- };
- me.hasMoreLeftColumns = function() {
- return me.number > 0;
- };
- me.hasMoreRightColumns = function() {
- return me.number + me.visible < me.total;
- };
- me.updateSlice(0);
- return me;
- };
- var data = source.data;
- var page = new Page(data, options);
- var measurer = new Measurer(data, options);
- var columns = new Columns(data, source.columns, options);
- var table = null;
- var tableDiv = null;
- var header = null;
- var footer = null;
- var tbody = null;
- // Caches pagedTable.clientWidth, specially for webkit
- var cachedPagedTableClientWidth = null;
- var onChangeCallbacks = [];
- var clearSelection = function() {
- if(document.selection && document.selection.empty) {
- document.selection.empty();
- } else if(window.getSelection) {
- var sel = window.getSelection();
- sel.removeAllRanges();
- }
- };
- var columnNavigationWidthPX = 5;
- var renderColumnNavigation = function(increment, backwards) {
- var arrow = document.createElement("div");
- arrow.setAttribute("style",
- "border-top: " + columnNavigationWidthPX + "px solid transparent;" +
- "border-bottom: " + columnNavigationWidthPX + "px solid transparent;" +
- "border-" + (backwards ? "right" : "left") + ": " + columnNavigationWidthPX + "px solid;");
- var header = document.createElement("th");
- header.appendChild(arrow);
- header.setAttribute("style",
- "cursor: pointer;" +
- "vertical-align: middle;" +
- "min-width: " + columnNavigationWidthPX + "px;" +
- "width: " + columnNavigationWidthPX + "px;");
- header.onclick = function() {
- columns.incColumnNumber(backwards ? -1 : increment);
- me.animateColumns(backwards);
- renderFooter();
- clearSelection();
- triggerOnChange();
- };
- return header;
- };
- var maxColumnWidth = function(width) {
- var padding = 80;
- var columnMax = Math.max(cachedPagedTableClientWidth - padding, 0);
- return parseInt(width) > 0 ?
- Math.min(columnMax, parseInt(width)) + "px" :
- columnMax + "px";
- };
- var clearHeader = function() {
- var thead = pagedTable.querySelectorAll("thead")[0];
- thead.innerHTML = "";
- };
- var renderHeader = function(clear) {
- cachedPagedTableClientWidth = pagedTable.clientWidth;
- var fragment = document.createDocumentFragment();
- header = document.createElement("tr");
- fragment.appendChild(header);
- if (columns.number > 0)
- header.appendChild(renderColumnNavigation(-columns.visible, true));
- columns.subset = columns.subset.map(function(columnData) {
- var column = document.createElement("th");
- column.setAttribute("align", columnData.align);
- column.style.textAlign = columnData.align;
- column.style.maxWidth = maxColumnWidth(null);
- if (columnData.width) {
- column.style.minWidth =
- column.style.maxWidth = maxColumnWidth(columnData.width);
- }
- var columnName = document.createElement("div");
- columnName.setAttribute("class", "pagedtable-header-name");
- if (columnData.label === "") {
- columnName.innerHTML = " ";
- }
- else {
- columnName.appendChild(document.createTextNode(columnData.label));
- }
- column.appendChild(columnName);
- var columnType = document.createElement("div");
- columnType.setAttribute("class", "pagedtable-header-type");
- if (columnData.type === "") {
- columnType.innerHTML = " ";
- }
- else {
- columnType.appendChild(document.createTextNode("<" + columnData.type + ">"));
- }
- column.appendChild(columnType);
- header.appendChild(column);
- columnData.element = column;
- return columnData;
- });
- for (var idx = 0; idx < columns.getPaddingCount(); idx++) {
- var paddingCol = document.createElement("th");
- paddingCol.setAttribute("class", "pagedtable-padding-col");
- header.appendChild(paddingCol);
- }
- if (columns.number + columns.visible < columns.total)
- header.appendChild(renderColumnNavigation(columns.visible, false));
- if (typeof(clear) == "undefined" || clear) clearHeader();
- var thead = pagedTable.querySelectorAll("thead")[0];
- thead.appendChild(fragment);
- };
- me.animateColumns = function(backwards) {
- var thead = pagedTable.querySelectorAll("thead")[0];
- var headerOld = thead.querySelectorAll("tr")[0];
- var tbodyOld = table.querySelectorAll("tbody")[0];
- me.fitColumns(backwards);
- renderHeader(false);
- header.style.opacity = "0";
- header.style.transform = backwards ? "translateX(-30px)" : "translateX(30px)";
- header.style.transition = "transform 200ms linear, opacity 200ms";
- header.style.transitionDelay = "0";
- renderBody(false);
- if (headerOld) {
- headerOld.style.position = "absolute";
- headerOld.style.transform = "translateX(0px)";
- headerOld.style.opacity = "1";
- headerOld.style.transition = "transform 100ms linear, opacity 100ms";
- headerOld.setAttribute("class", "pagedtable-remove-head");
- if (headerOld.style.transitionEnd) {
- headerOld.addEventListener("transitionend", function() {
- var headerOldByClass = thead.querySelector(".pagedtable-remove-head");
- if (headerOldByClass) thead.removeChild(headerOldByClass);
- });
- }
- else {
- thead.removeChild(headerOld);
- }
- }
- if (tbodyOld) table.removeChild(tbodyOld);
- tbody.style.opacity = "0";
- tbody.style.transition = "transform 200ms linear, opacity 200ms";
- tbody.style.transitionDelay = "0ms";
- // force relayout
- window.getComputedStyle(header).opacity;
- window.getComputedStyle(tbody).opacity;
- if (headerOld) {
- headerOld.style.transform = backwards ? "translateX(20px)" : "translateX(-30px)";
- headerOld.style.opacity = "0";
- }
- header.style.transform = "translateX(0px)";
- header.style.opacity = "1";
- tbody.style.opacity = "1";
- }
- me.onChange = function(callback) {
- onChangeCallbacks.push(callback);
- };
- var triggerOnChange = function() {
- onChangeCallbacks.forEach(function(onChange) {
- onChange();
- });
- };
- var clearBody = function() {
- if (tbody) {
- table.removeChild(tbody);
- tbody = null;
- }
- };
- var renderBody = function(clear) {
- cachedPagedTableClientWidth = pagedTable.clientWidth
- var fragment = document.createDocumentFragment();
- var pageData = data.slice(page.getRowStart(), page.getRowEnd());
- pageData.forEach(function(dataRow, idxRow) {
- var htmlRow = document.createElement("tr");
- htmlRow.setAttribute("class", (idxRow % 2 !==0) ? "even" : "odd");
- if (columns.hasMoreLeftColumns())
- htmlRow.appendChild(document.createElement("td"));
- columns.subset.forEach(function(columnData) {
- var cellName = columnData.name;
- var dataCell = dataRow[cellName];
- var htmlCell = document.createElement("td");
- if (dataCell === "NA") htmlCell.setAttribute("class", "pagedtable-na-cell");
- if (dataCell === "__NA__") dataCell = "NA";
- var cellText = document.createTextNode(dataCell);
- htmlCell.appendChild(cellText);
- if (dataCell.length > 50) {
- htmlCell.setAttribute("title", dataCell);
- }
- htmlCell.setAttribute("align", columnData.align);
- htmlCell.style.textAlign = columnData.align;
- htmlCell.style.maxWidth = maxColumnWidth(null);
- if (columnData.width) {
- htmlCell.style.minWidth = htmlCell.style.maxWidth = maxColumnWidth(columnData.width);
- }
- htmlRow.appendChild(htmlCell);
- });
- for (var idx = 0; idx < columns.getPaddingCount(); idx++) {
- var paddingCol = document.createElement("td");
- paddingCol.setAttribute("class", "pagedtable-padding-col");
- htmlRow.appendChild(paddingCol);
- }
- if (columns.hasMoreRightColumns())
- htmlRow.appendChild(document.createElement("td"));
- fragment.appendChild(htmlRow);
- });
- for (var idxPadding = 0; idxPadding < page.getPaddingRows(); idxPadding++) {
- var paddingRow = document.createElement("tr");
- var paddingCellRow = document.createElement("td");
- paddingCellRow.innerHTML = " ";
- paddingCellRow.setAttribute("colspan", "100%");
- paddingRow.appendChild(paddingCellRow);
- fragment.appendChild(paddingRow);
- }
- if (typeof(clear) == "undefined" || clear) clearBody();
- tbody = document.createElement("tbody");
- tbody.appendChild(fragment);
- table.appendChild(tbody);
- };
- var getLabelInfo = function() {
- var pageStart = page.getRowStart();
- var pageEnd = page.getRowEnd();
- var totalRows = data.length;
- var totalRowsLabel = options.rows.total ? options.rows.total : totalRows;
- var totalRowsLabelFormat = totalRowsLabel.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
- var infoText = (pageStart + 1) + "-" + pageEnd + " of " + totalRowsLabelFormat + " rows";
- if (totalRows < page.rows) {
- infoText = totalRowsLabel + " row" + (totalRows != 1 ? "s" : "");
- }
- if (columns.total > columns.visible) {
- var totalColumnsLabel = options.columns.total ? options.columns.total : columns.total;
- infoText = infoText + " | " + (columns.number + 1) + "-" +
- (Math.min(columns.number + columns.visible, columns.total)) +
- " of " + totalColumnsLabel + " columns";
- }
- return infoText;
- };
- var clearFooter = function() {
- footer = pagedTable.querySelectorAll("div.pagedtable-footer")[0];
- footer.innerHTML = "";
- return footer;
- };
- var createPageLink = function(idxPage) {
- var pageLink = document.createElement("a");
- pageLinkClass = idxPage === page.number ? "pagedtable-index pagedtable-index-current" : "pagedtable-index";
- pageLink.setAttribute("class", pageLinkClass);
- pageLink.setAttribute("data-page-index", idxPage);
- pageLink.onclick = function() {
- page.setPageNumber(parseInt(this.getAttribute("data-page-index")));
- renderBody();
- renderFooter();
- triggerOnChange();
- };
- pageLink.appendChild(document.createTextNode(idxPage + 1));
- return pageLink;
- }
- var renderFooter = function() {
- footer = clearFooter();
- var next = document.createElement("a");
- next.appendChild(document.createTextNode("Next"));
- next.onclick = function() {
- page.setPageNumber(page.number + 1);
- renderBody();
- renderFooter();
- triggerOnChange();
- };
- if (data.length > page.rows) footer.appendChild(next);
- var pageNumbers = document.createElement("div");
- pageNumbers.setAttribute("class", "pagedtable-indexes");
- var pageRange = page.getVisiblePageRange();
- if (pageRange.first) {
- var pageLink = createPageLink(0);
- pageNumbers.appendChild(pageLink);
- var pageSeparator = document.createElement("div");
- pageSeparator.setAttribute("class", "pagedtable-index-separator-left");
- pageSeparator.appendChild(document.createTextNode("..."))
- pageNumbers.appendChild(pageSeparator);
- }
- for (var idxPage = pageRange.start; idxPage < pageRange.end; idxPage++) {
- var pageLink = createPageLink(idxPage);
- pageNumbers.appendChild(pageLink);
- }
- if (pageRange.last) {
- var pageSeparator = document.createElement("div");
- pageSeparator.setAttribute("class", "pagedtable-index-separator-right");
- pageSeparator.appendChild(document.createTextNode("..."))
- pageNumbers.appendChild(pageSeparator);
- var pageLink = createPageLink(page.total - 1);
- pageNumbers.appendChild(pageLink);
- }
- if (data.length > page.rows) footer.appendChild(pageNumbers);
- var previous = document.createElement("a");
- previous.appendChild(document.createTextNode("Previous"));
- previous.onclick = function() {
- page.setPageNumber(page.number - 1);
- renderBody();
- renderFooter();
- triggerOnChange();
- };
- if (data.length > page.rows) footer.appendChild(previous);
- var infoLabel = document.createElement("div");
- infoLabel.setAttribute("class", "pagedtable-info");
- infoLabel.setAttribute("title", getLabelInfo());
- infoLabel.appendChild(document.createTextNode(getLabelInfo()));
- footer.appendChild(infoLabel);
- var enabledClass = "pagedtable-index-nav";
- var disabledClass = "pagedtable-index-nav pagedtable-index-nav-disabled";
- previous.setAttribute("class", page.number <= 0 ? disabledClass : enabledClass);
- next.setAttribute("class", (page.number + 1) * page.rows >= data.length ? disabledClass : enabledClass);
- };
- var measuresCell = null;
- var renderMeasures = function() {
- var measuresTable = document.createElement("table");
- measuresTable.style.visibility = "hidden";
- measuresTable.style.position = "absolute";
- measuresTable.style.whiteSpace = "nowrap";
- measuresTable.style.height = "auto";
- measuresTable.style.width = "auto";
- var measuresRow = document.createElement("tr");
- measuresTable.appendChild(measuresRow);
- measuresCell = document.createElement("td");
- var sampleString = "ABCDEFGHIJ0123456789";
- measuresCell.appendChild(document.createTextNode(sampleString));
- measuresRow.appendChild(measuresCell);
- tableDiv.appendChild(measuresTable);
- }
- me.init = function() {
- tableDiv = document.createElement("div");
- pagedTable.appendChild(tableDiv);
- var pagedTableClass = data.length > 0 ?
- "pagedtable pagedtable-not-empty" :
- "pagedtable pagedtable-empty";
- if (columns.total == 0 || (columns.emptyNames() && data.length == 0)) {
- pagedTableClass = pagedTableClass + " pagedtable-empty-columns";
- }
- tableDiv.setAttribute("class", pagedTableClass);
- renderMeasures();
- measurer.calculate(measuresCell);
- columns.calculateWidths(measurer.measures);
- table = document.createElement("table");
- table.setAttribute("cellspacing", "0");
- table.setAttribute("class", "table table-condensed");
- tableDiv.appendChild(table);
- table.appendChild(document.createElement("thead"));
- var footerDiv = document.createElement("div");
- footerDiv.setAttribute("class", "pagedtable-footer");
- tableDiv.appendChild(footerDiv);
- // if the host has not yet provided horizontal space, render hidden
- if (tableDiv.clientWidth <= 0) {
- tableDiv.style.opacity = "0";
- }
- me.render();
- // retry seizing columns later if the host has not provided space
- function retryFit() {
- if (tableDiv.clientWidth <= 0) {
- setTimeout(retryFit, 100);
- } else {
- me.render();
- triggerOnChange();
- }
- }
- if (tableDiv.clientWidth <= 0) {
- retryFit();
- }
- };
- var registerWidths = function() {
- columns.subset = columns.subset.map(function(column) {
- column.width = columns.widths[column.name].inner;
- return column;
- });
- };
- var parsePadding = function(value) {
- return parseInt(value) >= 0 ? parseInt(value) : 0;
- };
- me.fixedHeight = function() {
- return options.rows.max != null;
- }
- me.fitRows = function() {
- if (me.fixedHeight())
- return;
- measurer.calculate(measuresCell);
- var rows = options.rows.min !== null ? options.rows.min : 0;
- var headerHeight = header !== null && header.offsetHeight > 0 ? header.offsetHeight : 0;
- var footerHeight = footer !== null && footer.offsetHeight > 0 ? footer.offsetHeight : 0;
- if (pagedTable.offsetHeight > 0) {
- var availableHeight = pagedTable.offsetHeight - headerHeight - footerHeight;
- rows = Math.floor((availableHeight) / measurer.measures.height);
- }
- rows = options.rows.min !== null ? Math.max(options.rows.min, rows) : rows;
- page.setRows(rows);
- }
- // The goal of this function is to add as many columns as possible
- // starting from left-to-right, when the right most limit is reached
- // it tries to add columns from the left as well.
- //
- // When startBackwards is true columns are added from right-to-left
- me.fitColumns = function(startBackwards) {
- measurer.calculate(measuresCell);
- columns.calculateWidths(measurer.measures);
- if (tableDiv.clientWidth > 0) {
- tableDiv.style.opacity = 1;
- }
- var visibleColumns = tableDiv.clientWidth <= 0 ? Math.max(columns.min, 1) : 1;
- var columnNumber = columns.number;
- var paddingCount = 0;
- // track a list of added columns as we build the visible ones to allow us
- // to remove columns when they don't fit anymore.
- var columnHistory = [];
- var lastTableHeight = 0;
- var backwards = startBackwards;
- var tableDivStyle = window.getComputedStyle(tableDiv, null);
- var tableDivPadding = parsePadding(tableDivStyle.paddingLeft) +
- parsePadding(tableDivStyle.paddingRight);
- var addPaddingCol = false;
- var currentWidth = 0;
- while (true) {
- columns.setVisibleColumns(columnNumber, visibleColumns, paddingCount);
- currentWidth = columns.getWidth();
- if (tableDiv.clientWidth - tableDivPadding < currentWidth) {
- break;
- }
- columnHistory.push({
- columnNumber: columnNumber,
- visibleColumns: visibleColumns,
- paddingCount: paddingCount
- });
- if (columnHistory.length > 100) {
- console.error("More than 100 tries to fit columns, aborting");
- break;
- }
- if (columns.max !== null &&
- columns.visible + columns.getPaddingCount() >= columns.max) {
- break;
- }
- // if we run out of right-columns
- if (!backwards && columnNumber + columns.visible >= columns.total) {
- // if we started adding right-columns, try adding left-columns
- if (!startBackwards && columnNumber > 0) {
- backwards = true;
- }
- else if (columns.min === null || visibleColumns + columns.getPaddingCount() >= columns.min) {
- break;
- }
- else {
- paddingCount = paddingCount + 1;
- }
- }
- // if we run out of left-columns
- if (backwards && columnNumber == 0) {
- // if we started adding left-columns, try adding right-columns
- if (startBackwards && columnNumber + columns.visible < columns.total) {
- backwards = false;
- }
- else if (columns.min === null || visibleColumns + columns.getPaddingCount() >= columns.min) {
- break;
- }
- else {
- paddingCount = paddingCount + 1;
- }
- }
- // when moving backwards try fitting left columns first
- if (backwards && columnNumber > 0) {
- columnNumber = columnNumber - 1;
- }
- if (columnNumber + visibleColumns < columns.total) {
- visibleColumns = visibleColumns + 1;
- }
- }
- var lastRenderableColumn = {
- columnNumber: columnNumber,
- visibleColumns: visibleColumns,
- paddingCount: paddingCount
- };
- if (columnHistory.length > 0) {
- lastRenderableColumn = columnHistory[columnHistory.length - 1];
- }
- columns.setVisibleColumns(
- lastRenderableColumn.columnNumber,
- lastRenderableColumn.visibleColumns,
- lastRenderableColumn.paddingCount);
- if (pagedTable.offsetWidth > 0) {
- page.setVisiblePages(Math.max(Math.ceil(1.0 * (pagedTable.offsetWidth - 250) / 40), 2));
- }
- registerWidths();
- };
- me.fit = function(startBackwards) {
- me.fitRows();
- me.fitColumns(startBackwards);
- }
- me.render = function() {
- me.fitColumns(false);
- // render header/footer to measure height accurately
- renderHeader();
- renderFooter();
- me.fitRows();
- renderBody();
- // re-render footer to match new rows
- renderFooter();
- }
- var resizeLastWidth = -1;
- var resizeLastHeight = -1;
- var resizeNewWidth = -1;
- var resizeNewHeight = -1;
- var resizePending = false;
- me.resize = function(newWidth, newHeight) {
- function resizeDelayed() {
- resizePending = false;
- if (
- (resizeNewWidth !== resizeLastWidth) ||
- (!me.fixedHeight() && resizeNewHeight !== resizeLastHeight)
- ) {
- resizeLastWidth = resizeNewWidth;
- resizeLastHeight = resizeNewHeight;
- setTimeout(resizeDelayed, 200);
- resizePending = true;
- } else {
- me.render();
- triggerOnChange();
- resizeLastWidth = -1;
- resizeLastHeight = -1;
- }
- }
- resizeNewWidth = newWidth;
- resizeNewHeight = newHeight;
- if (!resizePending) resizeDelayed();
- };
- };
- var PagedTableDoc;
- (function (PagedTableDoc) {
- var allPagedTables = [];
- PagedTableDoc.initAll = function() {
- allPagedTables = [];
- var pagedTables = [].slice.call(document.querySelectorAll('[data-pagedtable="false"],[data-pagedtable=""]'));
- pagedTables.forEach(function(pagedTable, idx) {
- pagedTable.setAttribute("data-pagedtable", "true");
- pagedTable.setAttribute("pagedtable-page", 0);
- pagedTable.setAttribute("class", "pagedtable-wrapper");
- var pagedTableInstance = new PagedTable(pagedTable);
- pagedTableInstance.init();
- allPagedTables.push(pagedTableInstance);
- });
- };
- PagedTableDoc.resizeAll = function() {
- allPagedTables.forEach(function(pagedTable) {
- pagedTable.render();
- });
- };
- window.addEventListener("resize", PagedTableDoc.resizeAll);
- return PagedTableDoc;
- })(PagedTableDoc || (PagedTableDoc = {}));
- window.onload = function() {
- PagedTableDoc.initAll();
- };
|