From 9b3e53faca742a36631ef0123be1eeaec65b9c7b Mon Sep 17 00:00:00 2001 From: Cath Date: Sat, 6 Apr 2013 18:15:32 +0800 Subject: [PATCH 1/4] add hide row/col and filter --- src/Grid.js | 976 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 598 insertions(+), 378 deletions(-) diff --git a/src/Grid.js b/src/Grid.js index 9aaf7f0..2b36324 100644 --- a/src/Grid.js +++ b/src/Grid.js @@ -6,14 +6,22 @@ //////////////////////////////////// (function(window, document, undefined) { "use strict"; - + var GridProto; var Grid = function(element, options) { if ((this.element = (typeof(element) === "string") ? $(element) : element)) { - this.css = { idRulePrefix : "#" + this.element.id + " ", sheet : null, rules : {} }; + this.css = { + idRulePrefix: "#" + this.element.id + " ", + sheet: null, + rules: {} + }; this.columns = 0; this.columnWidths = []; - this.cellData = { head : [], body : [], foot : [] }; + this.cellData = { + head: [], + body: [], + foot: [] + }; this.alignTimer = null; this.rawData = []; this.sortCache = {}; @@ -27,41 +35,41 @@ this.init(); } }; - + ////////////////////////////////////////////////////////////////////////////////// - (GridProto = Grid.prototype).nothing = function(){}; - + (GridProto = Grid.prototype).nothing = function() {}; + ////////////////////////////////////////////////////////////////////////////////// GridProto.setOptions = function(options) { - var hasOwnProp = Object.prototype.hasOwnProperty, - option; - + var hasOwnProp = Object.prototype.hasOwnProperty, + option; + this.options = { - srcType : "", // "dom", "json", "xml" - srcData : "", - allowGridResize : false, - allowColumnResize : false, - allowClientSideSorting : false, - allowSelections : false, - allowMultipleSelections : false, - showSelectionColumn : false, - onColumnSort : this.nothing, - onResizeGrid : this.nothing, - onResizeGridEnd : this.nothing, - onResizeColumn : this.nothing, - onResizeColumnEnd : this.nothing, - onRowSelect : this.nothing, - onLoad : this.nothing, - supportMultipleGridsInView : false, - fixedCols : 0, - selectedBgColor : "#eaf1f7", - fixedSelectedBgColor : "#dce7f0", - colAlign : [], // "left", "center", "right" - colBGColors : [], - colSortTypes : [], // "string", "number", "date", "custom", "none" - customSortCleaner : null + srcType: "", // "dom", "json", "xml" + srcData: "", + allowGridResize: false, + allowColumnResize: false, + allowClientSideSorting: false, + allowSelections: false, + allowMultipleSelections: false, + showSelectionColumn: false, + onColumnSort: this.nothing, + onResizeGrid: this.nothing, + onResizeGridEnd: this.nothing, + onResizeColumn: this.nothing, + onResizeColumnEnd: this.nothing, + onRowSelect: this.nothing, + onLoad: this.nothing, + supportMultipleGridsInView: false, + fixedCols: 0, + selectedBgColor: "#eaf1f7", + fixedSelectedBgColor: "#dce7f0", + colAlign: [], // "left", "center", "right" + colBGColors: [], + colSortTypes: [], // "string", "number", "date", "custom", "none" + customSortCleaner: null }; - + if (options) { for (option in this.options) { if (hasOwnProp.call(this.options, option) && options[option] !== undefined) { @@ -69,71 +77,85 @@ } } } - + this.options.allowColumnResize = this.options.allowColumnResize && !this.usesTouch; this.options.allowMultipleSelections = this.options.allowMultipleSelections && this.options.allowSelections; this.options.showSelectionColumn = this.options.showSelectionColumn && this.options.allowSelections; this.options.fixedCols = (!this.usesTouch) ? this.options.fixedCols : 0; }; - + ////////////////////////////////////////////////////////////////////////////////// + var data = new Object(); + var ctxArr = new Array(); + GridProto.init = function() { - var srcType = this.options.srcType, - srcData = this.options.srcData, - data; - + var srcType = this.options.srcType, + srcData = this.options.srcData; + this.generateSkeleton(); this.addEvents(); - + // DOM: if (srcType === "dom" && (srcData = (typeof(srcData) === "string") ? $(srcData) : srcData)) { - this.convertData(this.convertDomDataToJsonData(srcData)); - - // JSON: + this.convertData(data = this.convertDomDataToJsonData(srcData)); + + // JSON: } else if (srcType === "json" && (data = parseJSON(srcData))) { this.convertData(data); - - // XML: + + // XML: } else if (srcType === "xml" && (data = parseXML(srcData))) { - this.convertData(this.convertXmlDataToJsonData(data)); + this.convertData(data = this.convertXmlDataToJsonData(data)); } - + + this.initCtxArr(); this.generateGrid(); this.displayGrid(); }; - + ////////////////////////////////////////////////////////////////////////////////// + GridProto.initCtxArr = function() { + for (var i = 0; i < data.Body.length; i++) { + ctxArr[i] = data.Body[i].toString(); + } + } + GridProto.generateSkeleton = function() { - var doc = document, - elems = [["base", "g_Base", "docFrag"], - ["head", "g_Head", "base"], - ["headFixed", "g_HeadFixed", "head"], - ["headStatic", "g_HeadStatic", "head"], - ["foot", "g_Foot", "base"], - ["footFixed", "g_FootFixed", "foot"], - ["footStatic", "g_FootStatic", "foot"], - ["body", "g_Body", "base"], - ["bodyFixed", "g_BodyFixed", "body"], - ["bodyFixed2", "g_BodyFixed2", "bodyFixed"], - ["bodyStatic", "g_BodyStatic", "body"]]; - - this.parentDimensions = { x : this.element.offsetWidth, y : this.element.offsetHeight }; + var doc = document, + elems = [ + ["base", "g_Base", "docFrag"], + ["head", "g_Head", "base"], + ["headFixed", "g_HeadFixed", "head"], + ["headStatic", "g_HeadStatic", "head"], + ["foot", "g_Foot", "base"], + ["footFixed", "g_FootFixed", "foot"], + ["footStatic", "g_FootStatic", "foot"], + ["body", "g_Body", "base"], + ["bodyFixed", "g_BodyFixed", "body"], + ["bodyFixed2", "g_BodyFixed2", "bodyFixed"], + ["bodyStatic", "g_BodyStatic", "body"] + ]; + + this.parentDimensions = { + x: this.element.offsetWidth, + y: this.element.offsetHeight + }; this.docFrag = doc.createDocumentFragment(); - for (var i=0, elem; elem=elems[i]; i++) { + for (var i = 0, elem; elem = elems[i]; i++) { (this[elem[0]] = doc.createElement("DIV")).className = elem[1]; this[elem[2]].appendChild(this[elem[0]]); } - + if (this.options.allowGridResize) { (this.baseResize = doc.createElement("DIV")).className = "g_BaseResize"; this.base.appendChild(this.baseResize); } }; - + ////////////////////////////////////////////////////////////////////////////////// GridProto.addEvents = function() { var wheelEvent; - + // Simulate mouse scrolling over non-scrollable content: if (this.options.fixedCols > 0 && !this.usesTouch && !msie) { try { @@ -145,17 +167,17 @@ addEvent(this.bodyFixed, wheelEvent, bind(this.simulateMouseScroll, this)); } } - + // Grid resizing: if (this.options.allowGridResize) { addEvent(this.baseResize, this.startEvt, bind(this.initResizeGrid, this)); } - + // Column resizing and client side sorting: if (this.options.allowColumnResize || this.options.allowClientSideSorting) { addEvent(this.head, this.startEvt, bind(this.delegateHeaderEvent, this)); } - + // Row selection: if (this.options.allowSelections) { addEvent(this.body, this.startEvt, bind(this.selectRange, this)); @@ -164,52 +186,62 @@ } } }; - + ////////////////////////////////////////////////////////////////////////////////// GridProto.convertDomDataToJsonData = function(data) { - var sections = { "thead" : "Head", "tbody" : "Body", "tfoot" : "Foot" }, - section, rows, row, cells, arr, arr2, i, j, k, - json = {}; - + var sections = { + "thead": "Head", + "tbody": "Body", + "tfoot": "Foot" + }, + section, rows, row, cells, arr, arr2, i, j, k, + json = {}; + // Cycle through all table rows, change sections when needed: if (((data || {}).tagName || "").toLowerCase() === "table") { - for (i=0, j=0, rows=data.rows; row=rows[i]; i++) { + for (i = 0, j = 0, rows = data.rows; row = rows[i]; i++) { if (row.sectionRowIndex === 0 && (section = sections[row.parentNode.tagName.toLowerCase()])) { json[section] = arr = (json[section] || []); j = arr.length; } arr[j++] = arr2 = []; k = (cells = row.cells).length; - while (k) { arr2[--k] = cells[k].innerHTML; } + while (k) { + arr2[--k] = cells[k].innerHTML; + } } } - + return json; }; - + ////////////////////////////////////////////////////////////////////////////////// GridProto.convertXmlDataToJsonData = function(data) { - var sections = { "thead" : "Head", "tbody" : "Body", "tfoot" : "Foot" }, - cellText = (msie < 9) ? "text" : "textContent", - nodes, node, section, rows, row, cells, cell, tag, n, i, j, - arr, arr2, a, a2, - json = {}; - + var sections = { + "thead": "Head", + "tbody": "Body", + "tfoot": "Foot" + }, + cellText = (msie < 9) ? "text" : "textContent", + nodes, node, section, rows, row, cells, cell, tag, n, i, j, + arr, arr2, a, a2, + json = {}; + // By section: if ((nodes = (data.getElementsByTagName("table")[0] || {}).childNodes)) { - for (n=0; node=nodes[n]; n++) { + for (n = 0; node = nodes[n]; n++) { if ((section = sections[node.nodeName]) && (rows = node.childNodes)) { json[section] = arr = (json[section] || []); a = arr.length; - + // By row: - for (i=0; row=rows[i]; i++) { + for (i = 0; row = rows[i]; i++) { if (row.nodeName === "tr" && (cells = row.childNodes)) { arr[a++] = arr2 = []; a2 = 0; - + // By cell: - for (j=0; cell=cells[j]; j++) { + for (j = 0; cell = cells[j]; j++) { if ((tag = cell.nodeName) === "td" || tag === "th") { arr2[a2++] = cell[cellText] || ""; } @@ -219,14 +251,14 @@ } } } - + return json; }; - + ////////////////////////////////////////////////////////////////////////////////// GridProto.convertData = function(data) { var base, cols, h, b, f; - + this.addSelectionColumn(data); this.rawData = data.Body || []; if ((base = data.Head || data.Body || data.Foot || null)) { @@ -234,32 +266,42 @@ h = this.cellData.head; b = this.cellData.body; f = this.cellData.foot; - while (cols) { h[--cols] = []; b[cols] = []; f[cols] = []; } - + while (cols) { + h[--cols] = []; + b[cols] = []; + f[cols] = []; + } + cols = this.columns; if (data.Head) { this.convertDataItem(h, data.Head, "
"; row = rows[rowIdx]; @@ -275,11 +317,11 @@ } } }; - + ////////////////////////////////////////////////////////////////////////////////// GridProto.addSelectionColumn = function(data) { var html, rows, i; - + if (this.options.showSelectionColumn) { this.options.colBGColors.unshift(this.options.colBGColors[0] || ""); this.options.colSortTypes.unshift("none"); @@ -287,22 +329,28 @@ if (!this.usesTouch) { this.options.fixedCols++; } - + if ((rows = data.Head) && (i = rows.length)) { - while (i) { rows[--i].unshift(""); } + while (i) { + rows[--i].unshift(""); + } } if ((rows = data.Body) && (i = rows.length)) { html = "
"); }, - replaceRgx = /@(\d+)@/g, - fixedCols = this.options.fixedCols, - fHtml = [], sHtml = [], - colIdx = cols.length; - + var replaceFunc = function($1, $2) { + return cols[parseInt($2, 10)].join(""); + }, + replaceRgx = /@(\d+)@/g, + fixedCols = this.options.fixedCols, + fHtml = [], + sHtml = [], + colIdx = cols.length; + while (colIdx) { if ((--colIdx) < fixedCols) { fHtml[colIdx] = "
@" + colIdx + "@
"; @@ -373,22 +424,24 @@ sHtml[colIdx] = "
@" + colIdx + "@
"; } } - - return { fixedHTML : (fixedCols) ? fHtml.join("").replace(replaceRgx, replaceFunc) : "", - fullHTML : sHtml.join("").replace(replaceRgx, replaceFunc) }; + + return { + fixedHTML: (fixedCols) ? fHtml.join("").replace(replaceRgx, replaceFunc) : "", + fullHTML: sHtml.join("").replace(replaceRgx, replaceFunc) + }; }; - + ////////////////////////////////////////////////////////////////////////////////// GridProto.displayGrid = function() { - var srcType = this.options.srcType, - srcData = this.options.srcData, - replace = false; - + var srcType = this.options.srcType, + srcData = this.options.srcData, + replace = false; + // Setup scrolling: this.lastScrollLeft = 0; this.lastScrollTop = 0; this.body.onscroll = bind(this.syncScrolls, this); - + // Prep style element: try { this.css.sheet.parentNode.removeChild(this.css.sheet); @@ -396,7 +449,7 @@ (this.css.sheet = document.createElement("STYLE")).id = this.element.id + "SS"; this.css.sheet.type = "text/css"; } - + // Insert grid into DOM: if (srcType === "dom" && (srcData = (typeof(srcData) === "string") ? $(srcData) : srcData)) { if ((replace = (this.element === srcData.parentNode))) { @@ -406,47 +459,131 @@ if (!replace) { this.element.appendChild(this.docFrag); } - + // Align columns: this.alignTimer = window.setTimeout(bind(this.alignColumns, this, false, true), 16); }; - + + GridProto.hideRow = function(rowIdx) { + var toHide = document.getElementsByClassName('g_C g_BR g_R' + rowIdx); + for (var j = 0; j < toHide.length; j++) { + toHide[j].style.display = 'none'; + } + } + + GridProto.showRow = function(rowIdx) { + var toShow = document.getElementsByClassName('g_C g_BR g_R' + rowIdx); + for (var j = 0; j < toShow.length; j++) { + toShow[j].style.display = ''; + } + } + + + GridProto.hideRows = function(rowIdxArr) { + for (var i = 0; i < rowIdxArr.length; i++) { + this.hideRow(rowIdxArr[i]); + } + } + + GridProto.showRows = function(rowIdxArr) { + for (var i = 0; i < rowIdxArr.length; i++) { + this.showRow(rowIdxArr[i]); + } + } + + GridProto.hideColumn = function(colIdx) { + var toHide = document.getElementsByClassName('g_Cl g_Cl' + colIdx); + for (var j = 0; j < toHide.length; j++) { + toHide[j].style.display = 'none'; + } + } + + GridProto.showColumn = function(colIdx) { + var toShow = document.getElementsByClassName('g_Cl g_Cl' + colIdx); + for (var j = 0; j < toShow.length; j++) { + toShow[j].style.display = ''; + } + } + + GridProto.hideColumns = function(colIdxArr) { + for (var i = 0; i < colIdxArr.length; i++) { + this.hideColumn(colIdxArr[i]); + } + } + + GridProto.showColumns = function(colIdxArr) { + for (var i = 0; i < colIdxArr.length; i++) { + this.showColumn(colIdxArr[i]); + } + } + + GridProto.filterSearch = function(searchStr) { + var filterArr = []; + var strArr = searchStr.split(' '); + for (var j = 0, k = 0; j < ctxArr.length; j++) { + var founded = true; + for (var i = 0; i < strArr.length; i++) { + founded &= (ctxArr[j].indexOf(strArr[i]) != -1); + if (!founded) break; + } + if (!founded) { + filterArr[k] = j; + k++; + } + } + var i = 0; //order: asc + for (var j = 0; i < ctxArr.length && j < filterArr.length; i++) { + if (i == filterArr[j]) { + this.hideRow(i); + j++; + } else { + this.showRow(i); + } + } + for (; i < ctxArr.length; i++) { + this.showRow(i); + } + } + ////////////////////////////////////////////////////////////////////////////////// GridProto.alignColumns = function(reAlign, fromInit) { - var sNodes = [this.headStatic.children || [], this.bodyStatic.children || [], this.footStatic.children || []], - fNodes = [this.headFixed.children || [], this.bodyFixed2.children || [], this.footFixed.children || []], - allowColumnResize = this.options.allowColumnResize, - colBGColors = this.options.colBGColors, - colAlign = this.options.colAlign, - fixedCols = this.options.fixedCols, - rules = this.css.rules, - colWidth, nodes; - + var sNodes = [this.headStatic.children || [], this.bodyStatic.children || [], this.footStatic.children || []], + fNodes = [this.headFixed.children || [], this.bodyFixed2.children || [], this.footFixed.children || []], + allowColumnResize = this.options.allowColumnResize, + colBGColors = this.options.colBGColors, + colAlign = this.options.colAlign, + fixedCols = this.options.fixedCols, + rules = this.css.rules, + colWidth, nodes; + // Compute base styles first, or remove old column width styling if realigning the columns: if (reAlign !== true) { this.computeBaseStyles(); } else { - for (var i=0, len=this.columns; i 0) ? this.tmp.origWidth + xDif : this.tmp.origWidth - Math.abs(xDif)); newHeight = Math.max(30, (yDif > 0) ? this.tmp.origHeight + yDif : this.tmp.origHeight - Math.abs(yDif)); - + elemStyle = this.element.style; elemStyle.width = newWidth + "px"; elemStyle.height = newHeight + "px"; - - this.parentDimensions = { x : newWidth, y : newHeight }; + + this.parentDimensions = { + x: newWidth, + y: newHeight + }; this.syncScrolls(); clearTextSelections(); this.options.onResizeGrid.apply(this, [newWidth, newHeight]); } }; - + ////////////////////////////////////////////////////////////////////////////////// GridProto.endResizeGrid = function(event) { removeEvent(document, this.moveEvt, this.tmp.boundMoveEvt); @@ -610,13 +774,13 @@ this.options.onResizeGridEnd.apply(this, [this.parentDimensions.x, this.parentDimensions.y]); this.tmp = undefined; }; - + ////////////////////////////////////////////////////////////////////////////////// GridProto.delegateHeaderEvent = function(event) { - var event = event || window.event, - target = event.target || event.srcElement, - targetClass = target.className || ""; - + var event = event || window.event, + target = event.target || event.srcElement, + targetClass = target.className || ""; + if (event.button !== 2) { if (this.options.allowColumnResize && targetClass.indexOf("g_RS") > -1) { return this.initResizeColumn(event, target, targetClass); @@ -630,57 +794,57 @@ } } }; - + ////////////////////////////////////////////////////////////////////////////////// GridProto.initResizeColumn = function(event, target, targetClass) { - var colIdx = parseInt(targetClass.replace(/g_RS/g, ""), 10), - doc = document; - + var colIdx = parseInt(targetClass.replace(/g_RS/g, ""), 10), + doc = document; + this.tmp = { - lastLeft : -1, - colIdx : colIdx, - origX : getEventPositions(event, "client").x, - origWidth : this.columnWidths[colIdx], - origLeft : target.offsetLeft, - boundMoveEvt : bind(this.resizeColumn, this), - boundEndEvt : bind(this.endResizeColumn, this), - dragger : doc.createElement("DIV") + lastLeft: -1, + colIdx: colIdx, + origX: getEventPositions(event, "client").x, + origWidth: this.columnWidths[colIdx], + origLeft: target.offsetLeft, + boundMoveEvt: bind(this.resizeColumn, this), + boundEndEvt: bind(this.endResizeColumn, this), + dragger: doc.createElement("DIV") }; - + this.tmp.dragger.className = "g_ResizeDragger"; this.tmp.dragger.style.left = this.tmp.origLeft + "px"; this.base.insertBefore(this.tmp.dragger, this.base.firstChild); - + addEvent(doc, this.moveEvt, this.tmp.boundMoveEvt); addEvent(doc, this.endEvt, this.tmp.boundEndEvt); return stopEvent(event); }; - + ////////////////////////////////////////////////////////////////////////////////// GridProto.resizeColumn = function(event) { - var clientX = getEventPositions(event || window.event, "client").x, - xDif = clientX - this.tmp.origX, - newWidth = Math.max(15, (xDif > 0) ? this.tmp.origWidth + xDif : this.tmp.origWidth - Math.abs(xDif)), - newLeft = (xDif > 0) ? this.tmp.origLeft + xDif : this.tmp.origLeft - Math.abs(xDif); - + var clientX = getEventPositions(event || window.event, "client").x, + xDif = clientX - this.tmp.origX, + newWidth = Math.max(15, (xDif > 0) ? this.tmp.origWidth + xDif : this.tmp.origWidth - Math.abs(xDif)), + newLeft = (xDif > 0) ? this.tmp.origLeft + xDif : this.tmp.origLeft - Math.abs(xDif); + this.tmp.newWidth = newWidth; if (this.tmp.lastLeft !== newLeft && newWidth > 15) { this.tmp.dragger.style.left = newLeft + "px"; this.tmp.lastLeft = newLeft; } - + clearTextSelections(); this.options.onResizeColumn.apply(this, [this.tmp.colIdx, newWidth]); }; - + ////////////////////////////////////////////////////////////////////////////////// GridProto.endResizeColumn = function(event) { - var newWidth = this.tmp.newWidth || this.tmp.origWidth, - colIdx = this.tmp.colIdx; - + var newWidth = this.tmp.newWidth || this.tmp.origWidth, + colIdx = this.tmp.colIdx; + removeEvent(document, this.moveEvt, this.tmp.boundMoveEvt); removeEvent(document, this.endEvt, this.tmp.boundEndEvt); - + this.tmp.dragger.parentNode.removeChild(this.tmp.dragger); this.css.rules[".g_Cl" + colIdx]["width"] = newWidth + "px"; this.css.rules[".g_RS" + colIdx]["margin-left"] = (newWidth - 2) + "px"; @@ -690,92 +854,95 @@ this.options.onResizeColumnEnd.apply(this, [colIdx, newWidth]); this.tmp = undefined; }; - + ////////////////////////////////////////////////////////////////////////////////// GridProto.sortColumn = function(colIdx, sortAsc) { - var colIdx = parseInt(colIdx, 10) || ((colIdx === 0) ? 0 : -1), - colSortAs = (colIdx > -1) ? this.options.colSortTypes[colIdx] || "string" : "none", - lastCol = this.lastSortedColumn; - + var colIdx = parseInt(colIdx, 10) || ((colIdx === 0) ? 0 : -1), + colSortAs = (colIdx > -1) ? this.options.colSortTypes[colIdx] || "string" : "none", + lastCol = this.lastSortedColumn; + if (colSortAs !== "none") { - sortAsc = (sortAsc === undefined) ? ((colIdx === lastCol[0]) ? !lastCol[1] : true) : !!sortAsc; + sortAsc = (sortAsc === undefined) ? ((colIdx === lastCol[0]) ? !lastCol[1] : true) : !! sortAsc; this.sortRawData(colIdx, colSortAs, sortAsc); } }; - + ////////////////////////////////////////////////////////////////////////////////// GridProto.sortRawData = function(colIdx, colSortAs, sortAsc) { - var selIndexes, ltVal, gtVal, i, - rawData = this.rawData, - newSelIndexes = [], - newIdxOrder = [], - that = this; - + var selIndexes, ltVal, gtVal, i, + rawData = this.rawData, + newSelIndexes = [], + newIdxOrder = [], + that = this; + // Store prior index order: i = rawData.length; - while (i) { rawData[--i].pIdx = i; } - + while (i) { + rawData[--i].pIdx = i; + } + // Sort the body data by type: ltVal = (sortAsc) ? -1 : 1; gtVal = (sortAsc) ? 1 : -1; rawData.sort(function(a, b) { return that.getSortResult(colSortAs, colIdx, ltVal, gtVal, a[colIdx], b[colIdx]); }); - + // Update the grid body HTML: this.convertDataItem(this.cellData.body, rawData, ""); @@ -433,7 +424,6 @@ }; }; - ////////////////////////////////////////////////////////////////////////////////// GridProto.displayGrid = function() { var srcType = this.options.srcType, srcData = this.options.srcData, @@ -467,20 +457,15 @@ }; GridProto.hideRow = function(rowIdx) { - var toHide = document.getElementsByClassName('g_C g_BR g_R' + rowIdx); - for (var j = 0; j < toHide.length; j++) { - toHide[j].style.display = 'none'; - } + var divArr = doc.getElementsByClassName('g_C g_BR g_R' + rowIdx); + setVisible(divArr, 'none'); } GridProto.showRow = function(rowIdx) { - var toShow = document.getElementsByClassName('g_C g_BR g_R' + rowIdx); - for (var j = 0; j < toShow.length; j++) { - toShow[j].style.display = ''; - } + var divArr = doc.getElementsByClassName('g_C g_BR g_R' + rowIdx); + setVisible(divArr, ''); } - GridProto.hideRows = function(rowIdxArr) { for (var i = 0; i < rowIdxArr.length; i++) { this.hideRow(rowIdxArr[i]); @@ -494,17 +479,13 @@ } GridProto.hideColumn = function(colIdx) { - var toHide = document.getElementsByClassName('g_Cl g_Cl' + colIdx); - for (var j = 0; j < toHide.length; j++) { - toHide[j].style.display = 'none'; - } + var divArr = doc.getElementsByClassName('g_Cl g_Cl' + colIdx); + setVisible(divArr, 'none'); } GridProto.showColumn = function(colIdx) { - var toShow = document.getElementsByClassName('g_Cl g_Cl' + colIdx); - for (var j = 0; j < toShow.length; j++) { - toShow[j].style.display = ''; - } + var divArr = doc.getElementsByClassName('g_Cl g_Cl' + colIdx); + setVisible(divArr, ''); } GridProto.hideColumns = function(colIdxArr) { @@ -519,9 +500,29 @@ } } + GridProto.hideHead = function() { + var divArr = doc.getElementsByClassName('g_C g_HR g_R0'); + setVisible(divArr, 'none'); + } + + GridProto.showHead = function() { + var divArr = doc.getElementsByClassName('g_C g_HR g_R0'); + setVisible(divArr, ''); + } + + GridProto.hideFoot = function() { + var divArr = doc.getElementsByClassName('g_C g_FR g_R0'); + setVisible(divArr, 'none'); + } + + GridProto.showFoot = function() { + var divArr = doc.getElementsByClassName('g_C g_FR g_R0'); + setVisible(divArr, ''); + } + GridProto.filterSearch = function(searchStr) { searchStr = trim(searchStr); - var toFilter = data.clone(); + var toFilter = clone(jsonData); if (searchStr != '') { var strArr = searchStr.split(' '); var founded = true; @@ -537,13 +538,25 @@ } } } + visibleData = toFilter.Body; this.rowLength = toFilter.Body.length; - this.convertData(toFilter); - this.generateGrid(); - this.displayGrid(); + var cols = this.hasBody = this.rowLength > 0 ? toFilter.Body[0].length : 0; + this.convertDataItem(this.cellData.body, visibleData, "
-1), @@ -1050,7 +1046,6 @@ this.options.onRowSelect.apply(this, [toSelect, toRemove, rowIdx]); }; - ////////////////////////////////////////////////////////////////////////////////// GridProto.highlightRows = function(toSelect, toRemove) { var nodes = [this.bodyFixed2.children, this.bodyStatic.children], fixedSelBgColor = this.options.fixedSelectedBgColor, @@ -1088,7 +1083,6 @@ } }; - ////////////////////////////////////////////////////////////////////////////////// GridProto.preventSelectionInputStateChange = function(event) { var event = event || window.event, target = event.target || event.srcElement, @@ -1109,60 +1103,35 @@ } }; - ////////////////////////////////////////////////////////////////////////////////// - GridProto.cleanUp = function() { - this.alignTimer = (this.alignTimer) ? window.clearTimeout(this.alignTimer) : null; - this.element.innerHTML = ""; - try { - this.css.sheet.parentNode.removeChild(this.css.sheet); - } catch (e) {} - return null; - }; - - ////////////////////////////////// - // - // Utility Methods - // - ////////////////////////////////////////////////////////////////////////////////// - Object.prototype.clone = function() { + var clone = function(ori) { var objClone; - if (this.constructor == Object) { - objClone = new this.constructor(); - } else { - objClone = new this.constructor(this.valueOf()); - } - for (var key in this) { - if (objClone[key] != this[key]) { - if (typeof(this[key]) == 'object') { - objClone[key] = this[key].clone(); + if (typeof ori !== 'object') objClone = ori; + else { + objClone = ori && new ori.constructor(); + for (var key in ori) { + if (typeof(ori[key]) !== 'object') { + objClone[key] = ori[key]; } else { - objClone[key] = this[key]; + objClone[key] = clone(ori[key]); } } } - //objClone.toString = this.toString; - //objClone.valueOf = this.valueOf; return objClone; - } + }; var trim = function(str) {   return str.replace(/(^\s*)|(\s*$)/g, "");   } - ////////////////////////////////////////////////////////////////////////////////// - var getIEVersion = function() { - var nav, version; - if ((nav = navigator).appName === "Microsoft Internet Explorer") { - if (new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})").exec(nav.userAgent)) { - version = parseFloat(RegExp.$1); - } + var setVisible = function(divArr, style) { + for (var i = 0, len = divArr.length; i < len; i++) { + divArr[i].style.display = style; } - return (version > 5) ? version : undefined; - }; + } - ////////////////////////////////////////////////////////////////////////////////// var parseJSON = function(source) { - var sourceType, json, win; + var sourceType, json, win, k = 0, + obj = {}; if ((sourceType = typeof(source)) === "string") { if (((win = window).JSON || {}).parse) { @@ -1176,22 +1145,16 @@ } })(); } - } - - if (sourceType === "object") { + } else { json = source; } - var obj = new Object(); - if (!(json.hasOwnProperty('Head') && json.hasOwnProperty('Body'))) { - obj.Head = []; - obj.Body = []; - obj.Head[0] = []; - var k = 0; - for (var p in json[0]) { - obj.Head[0][k] = p; - k++; + //non-formatable object + if (!hasOwnProp.call(json, 'Body')) { + if (this.options.autoHead) { + fillHeadorFoot(obj, json, 'Head', this.options.headArray); } - for (var i = 0; i < json.length; i++) { + obj.Body = []; + for (var i = 0, len = json.length; i < len; i++) { obj.Body[i] = []; k = 0; for (var p in json[i]) { @@ -1199,13 +1162,43 @@ k++; } } + if (this.options.autoFoot) { + fillHeadorFoot(obj, json, 'Foot', this.options.footArray); + } json = obj; + } else { + if (this.options.autoHead) { + json.Head = [ + [] + ]; + json.Head[0] = this.options.headArray; + } + if (this.options.autoFoot) { + json.Foot = [ + [] + ]; + json.Foot[0] = this.options.footArray; + } } return json || null; }; - ////////////////////////////////////////////////////////////////////////////////// + var fillHeadorFoot = function(obj, json, prop, arr) { + obj[prop] = [ + [] + ]; + var k = 0; + if (arr.length > 0) { + obj[prop][0] = arr; + } else { + for (var p in json[0]) { + obj[prop][0][k] = p; + k++; + } + } + } + var parseXML = function(source) { var sourceType, dE, xml; @@ -1227,14 +1220,12 @@ return xml || null; }; - ////////////////////////////////////////////////////////////////////////////////// var addEvent = (document.addEventListener) ? function(elem, type, listener) { elem.addEventListener(type, listener, false); } : function(elem, type, listener) { elem.attachEvent("on" + type, listener); }; - ////////////////////////////////////////////////////////////////////////////////// var stopEvent = function(event) { if (event.stopPropagation) { event.stopPropagation(); @@ -1246,14 +1237,12 @@ return false; }; - ////////////////////////////////////////////////////////////////////////////////// var removeEvent = (document.addEventListener) ? function(elem, type, listener) { elem.removeEventListener(type, listener, false); } : function(elem, type, listener) { elem.detachEvent("on" + type, listener); }; - ////////////////////////////////////////////////////////////////////////////////// var getEventPositions = function(event, type) { var pageX = event.pageX, pageY = event.pageY, @@ -1287,7 +1276,6 @@ }; }; - ////////////////////////////////////////////////////////////////////////////////// var bind = function(func, that) { var a = slice.call(arguments, 2); return function() { @@ -1295,7 +1283,6 @@ }; }; - ////////////////////////////////////////////////////////////////////////////////// var indexOf = ([].indexOf) ? function(arr, item) { return arr.indexOf(item); } : function(arr, item) { @@ -1307,7 +1294,6 @@ return -1; }; - ////////////////////////////////////////////////////////////////////////////////// var clearTextSelections = (window.getSelection) ? function() { window.getSelection().removeAllRanges(); return false; @@ -1318,14 +1304,22 @@ return false; }; - ////////////////////////////////////////////////////////////////////////////////// - var $ = function(elemId) { - return document.getElementById(elemId); - }, - slice = Array.prototype.slice, - msie = getIEVersion(); + var doc = document, + $ = function(elemId) { + return document.getElementById(elemId); + }, + msie = function() { + var nav, version; - // Expose: - window.Grid = Grid; + if ((nav = navigator).appName === "Microsoft Internet Explorer") { + if (new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})").exec(nav.userAgent)) { + version = parseFloat(RegExp.$1); + } + } + return (version > 5) ? version : undefined; + }(), + slice = Array.prototype.slice, + hasOwnProp = Object.prototype.hasOwnProperty; -})(this, this.document); \ No newline at end of file + window.Grid = Grid; +})(window, document); From 1e3eec13729ba6cf411546923afd95bfa0593519 Mon Sep 17 00:00:00 2001 From: cath Date: Wed, 8 May 2013 15:21:18 +0800 Subject: [PATCH 4/4] nullValue added --- src/Grid.js | 46 +++++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/Grid.js b/src/Grid.js index c3f3dc3..2594767 100644 --- a/src/Grid.js +++ b/src/Grid.js @@ -69,7 +69,8 @@ autoFoot: false, footArray: [], autoHead: false, - headArray: [] + headArray: [], + nullValue: '' }; if (options) { @@ -97,7 +98,7 @@ // DOM: if (srcType === "dom" && (srcData = (typeof(srcData) === "string") ? $(srcData) : srcData)) { - this.convertData(jsonData = this.convertDomDataToJsonData(srcData)); + this.convertData(jsonData = parseJSON.call(this, this.convertDomDataToJsonData(srcData))); // JSON: } else if (srcType === "json" && (jsonData = parseJSON.call(this, srcData))) { @@ -105,10 +106,11 @@ // XML: } else if (srcType === "xml" && (jsonData = parseXML(srcData))) { - this.convertData(jsonData = this.convertXmlDataToJsonData(jsonData)); + this.convertData(jsonData = parseJSON.call(this, this.convertXmlDataToJsonData(jsonData))); } this.rowLength = jsonData.Body.length; + visibleData = clone(jsonData.Body); this.initCtxArr(); this.generateGrid(); this.displayGrid(); @@ -879,10 +881,8 @@ } // Sort the body data by type: - ltVal = (sortAsc) ? -1 : 1; - gtVal = (sortAsc) ? 1 : -1; rawData.sort(function(a, b) { - return that.getSortResult(colSortAs, colIdx, ltVal, gtVal, a[colIdx], b[colIdx]); + return that.getSortResult(colSortAs, colIdx, sortAsc, a[colIdx], b[colIdx]); }); // Update the grid body HTML: @@ -909,12 +909,13 @@ lastSortedColumn = [colIdx, sortAsc]; }; - GridProto.getSortResult = function(type, colIdx, ltVal, gtVal, a, b, keyA, keyB) { + GridProto.getSortResult = function(type, colIdx, sortAsc, a, b) { if (a === b) { return 0; } - if (a == null || a == undefined) a = '0'; - if (b == null || b == undefined) b = '0'; + var keyA, keyB, result; + if (a === null || a === undefined || a === '') a = this.options.nullValue; + if (b === null || b === undefined || b === '') b = this.options.nullValue; if (sortCache[(keyA = type + "_" + a)] === undefined) { sortCache[keyA] = (type === "string") ? a : (type === "number") ? parseFloat(a) || -Infinity : (type === "date") ? new Date(a).getTime() || -Infinity : (type === "custom") ? this.options.customSortCleaner(a, colIdx) : a; @@ -922,8 +923,9 @@ if (sortCache[(keyB = type + "_" + b)] === undefined) { sortCache[keyB] = (type === "string") ? b : (type === "number") ? parseFloat(b) || -Infinity : (type === "date") ? new Date(b).getTime() || -Infinity : (type === "custom") ? this.options.customSortCleaner(b, colIdx) : b; } + result = sortCache[keyA] < sortCache[keyB] ? -1 : 1; - return (sortCache[keyA] < sortCache[keyB]) ? ltVal : gtVal; + return sortAsc ? result : -result; }; GridProto.toggleSelectAll = function(toggle) { @@ -1177,20 +1179,38 @@ json.Foot = [ [] ]; - json.Foot[0] = this.options.footArray; + //json.Foot[0] = this.options.footArray; + for (var i = 0; i < this.options.footArray.length; i++) { + if (typeof(this.options.footArray[i]) === 'function') { + json.Foot[0][i] = this.options.footArray[i](visibleData); + } else { + json.Foot[0][i] = this.options.footArray[i]; + } + } } } return json || null; }; + var addHeadorFoot = function() { + + } + var fillHeadorFoot = function(obj, json, prop, arr) { obj[prop] = [ [] ]; var k = 0; if (arr.length > 0) { - obj[prop][0] = arr; + //obj[prop][0] = arr; + for (var i = 0; i < arr.length; i++) { + if (typeof(arr[i]) === 'function') { + obj[prop][0][i] = arr[i](visibleData); + } else { + obj[prop][0][i] = arr[i]; + } + } } else { for (var p in json[0]) { obj[prop][0][k] = p; @@ -1322,4 +1342,4 @@ hasOwnProp = Object.prototype.hasOwnProperty; window.Grid = Grid; -})(window, document); +})(window, document); \ No newline at end of file