diff --git a/editablegrid.css b/editablegrid.css index 1bb6318..52e5411 100644 --- a/editablegrid.css +++ b/editablegrid.css @@ -1,6 +1,21 @@ +td.vertical-align-top +{ + vertical-align: top; +} + +td.vertical-align-center +{ + vertical-align: center; +} + +td.vertical-align-bottom +{ + vertical-align: bottom; +} + td.number { text-align: right; - font-weight: bold; + padding-right: 5px; white-space: nowrap; } diff --git a/editablegrid.js b/editablegrid.js index 1c3de8d..22bec78 100644 --- a/editablegrid.js +++ b/editablegrid.js @@ -8,39 +8,39 @@ if (typeof _$ == 'undefined') { * @class Represents a column in the editable grid * @param {Object} config */ -function Column(config) -{ +function Column(config) { // default properties var props = { - name: "", - label: "", - editable: true, - renderable: true, - datatype: "string", - unit: null, - precision: -1, // means that all decimals are displayed - nansymbol: '', - decimal_point: ',', - thousands_separator: '.', - unit_before_number: false, - bar: true, // is the column to be displayed in a bar chart ? relevant only for numerical columns - hidden: false, // should the column be hidden by default - headerRenderer: null, - headerEditor: null, - cellRenderer: null, - cellEditor: null, - cellValidators: [], - enumProvider: null, - optionValues: null, - optionValuesForRender: null, - columnIndex: -1 + name: "", + label: "", + vertical_alignment: 'top', //top, center, or bottom + editable: true, + renderable: true, + datatype: "string", //string, integer, double, email, html, boolean + unit: null, + precision: -1, // means that all decimals are displayed + nansymbol: '', + decimal_point: '.', + thousands_separator: ',', + unit_before_number: false, + bar: true, // is the column to be displayed in a bar chart ? relevant only for numerical columns + hidden: false, // should the column be hidden by default + headerRenderer: null, + headerEditor: null, + cellRenderer: null, + cellEditor: null, + cellValidators: [], + enumProvider: null, + optionValues: null, + optionValuesForRender: null, + columnIndex: -1 }; // override default properties with the ones given for (var p in props) this[p] = (typeof config == 'undefined' || typeof config[p] == 'undefined') ? props[p] : config[p]; } -Column.prototype.getOptionValuesForRender = function(rowIndex) { +Column.prototype.getOptionValuesForRender = function (rowIndex) { if (!this.enumProvider) { console.log('getOptionValuesForRender called on column ' + this.name + ' but there is no EnumProvider'); return null; @@ -49,7 +49,7 @@ Column.prototype.getOptionValuesForRender = function(rowIndex) { return values ? values : this.optionValuesForRender; }; -Column.prototype.getOptionValuesForEdit = function(rowIndex) { +Column.prototype.getOptionValuesForEdit = function (rowIndex) { if (!this.enumProvider) { console.log('getOptionValuesForEdit called on column ' + this.name + ' but there is no EnumProvider'); return null; @@ -58,13 +58,13 @@ Column.prototype.getOptionValuesForEdit = function(rowIndex) { return values ? this.editablegrid._convertOptions(values) : this.optionValues; }; -Column.prototype.isValid = function(value) { +Column.prototype.isValid = function (value) { for (var i = 0; i < this.cellValidators.length; i++) if (!this.cellValidators[i].isValid(value)) return false; return true; }; -Column.prototype.isNumerical = function() { - return this.datatype =='double' || this.datatype =='integer'; +Column.prototype.isNumerical = function () { + return this.datatype == 'double' || this.datatype == 'integer'; }; /** @@ -73,11 +73,10 @@ Column.prototype.isNumerical = function() { * @class Base class for all enumeration providers * @param {Object} config */ -function EnumProvider(config) -{ +function EnumProvider(config) { // default properties - this.getOptionValuesForRender = function(grid, column, rowIndex) { return null; }; - this.getOptionValuesForEdit = function(grid, column, rowIndex) { return null; }; + this.getOptionValuesForRender = function (grid, column, rowIndex) { return null; }; + this.getOptionValuesForEdit = function (grid, column, rowIndex) { return null; }; // override default properties with the ones given for (var p in config) this[p] = config[p]; @@ -118,14 +117,14 @@ function EnumProvider(config) * @constructor * @class EditableGrid */ -function EditableGrid(name, config) { - if (typeof name != 'undefined' && name.replace(/\s+/g,'') == "") console.error("EditableGrid() : parameter [name] cannot be empty."); +function EditableGrid(name, config) { + if (typeof name != 'undefined' && name.replace(/\s+/g, '') == "") console.error("EditableGrid() : parameter [name] cannot be empty."); if (name) this.init(name, config); } /** * Default properties - */ + */ EditableGrid.prototype.enableSort = true; EditableGrid.prototype.enableStore = true; EditableGrid.prototype.doubleclick = false; @@ -138,8 +137,8 @@ EditableGrid.prototype.ignoreLastRow = false; EditableGrid.prototype.caption = null; EditableGrid.prototype.dateFormat = "EU"; EditableGrid.prototype.shortMonthNames = null; -EditableGrid.prototype.smartColorsBar = ["#dc243c","#4040f6","#00f629","#efe100","#f93fb1","#6f8183","#111111"]; -EditableGrid.prototype.smartColorsPie = ["#FF0000","#00FF00","#0000FF","#FFD700","#FF00FF","#00FFFF","#800080"]; +EditableGrid.prototype.smartColorsBar = ["#dc243c", "#4040f6", "#00f629", "#efe100", "#f93fb1", "#6f8183", "#111111"]; +EditableGrid.prototype.smartColorsPie = ["#FF0000", "#00FF00", "#0000FF", "#FFD700", "#FF00FF", "#00FFFF", "#800080"]; EditableGrid.prototype.pageSize = 0; // client-side pagination, don't set this for server-side pagination! //server-side pagination, sorting and filtering @@ -150,8 +149,7 @@ EditableGrid.prototype.unfilteredRowCount = 0; EditableGrid.prototype.paginatorAttributes = null; EditableGrid.prototype.lastURL = null; -EditableGrid.prototype.init = function (name, config) -{ +EditableGrid.prototype.init = function (name, config) { if (typeof name != "string" || (typeof config != "object" && typeof config != "undefined")) { alert("The EditableGrid constructor takes two arguments:\n- name (string)\n- config (object)\n\nGot instead " + (typeof name) + " and " + (typeof config) + "."); }; @@ -160,11 +158,11 @@ EditableGrid.prototype.init = function (name, config) if (typeof config != 'undefined') for (var p in config) this[p] = config[p]; this.Browser = { - IE: !!(window.attachEvent && navigator.userAgent.indexOf('Opera') === -1), - Opera: navigator.userAgent.indexOf('Opera') > -1, - WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, - Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') === -1, - MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) + IE: !!(window.attachEvent && navigator.userAgent.indexOf('Opera') === -1), + Opera: navigator.userAgent.indexOf('Opera') > -1, + WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, + Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') === -1, + MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) }; if (typeof this.detectDir != 'function') { @@ -185,12 +183,12 @@ EditableGrid.prototype.init = function (name, config) this.lastSelectedRowIndex = -1; this.currentPageIndex = 0; this.currentFilter = null; - this.currentContainerid = null; - this.currentClassName = null; + this.currentContainerid = null; + this.currentClassName = null; this.currentTableid = null; if (this.enableSort) { - if ( typeof config != "undefined" && typeof config['sortIconUp'] != "undefined" ) { + if (typeof config != "undefined" && typeof config['sortIconUp'] != "undefined") { this.sortUpElement = new Image(); this.sortUpElement.src = config['sortIconUp']; } else { @@ -198,7 +196,7 @@ EditableGrid.prototype.init = function (name, config) this.sortUpElement.innerHTML = '↑' // Unicode 'up' arrow } - if ( typeof config != "undefined" && typeof config['sortIconDown'] != "undefined" ) { + if (typeof config != "undefined" && typeof config['sortIconDown'] != "undefined") { this.sortDownElement = new Image(); this.sortDownElement.src = config['sortIconDown']; } else { @@ -218,34 +216,32 @@ EditableGrid.prototype.init = function (name, config) * Callback functions */ -EditableGrid.prototype.tableLoaded = function() {}; -EditableGrid.prototype.chartRendered = function() {}; -EditableGrid.prototype.tableRendered = function(containerid, className, tableid) {}; -EditableGrid.prototype.tableSorted = function(columnIndex, descending) {}; -EditableGrid.prototype.tableFiltered = function() {}; -EditableGrid.prototype.openedCellEditor = function(rowIndex, columnIndex) {}; -EditableGrid.prototype.modelChanged = function(rowIndex, columnIndex, oldValue, newValue, row) {}; -EditableGrid.prototype.rowSelected = function(oldRowIndex, newRowIndex) {}; -EditableGrid.prototype.isHeaderEditable = function(rowIndex, columnIndex) { return false; }; -EditableGrid.prototype.isEditable =function(rowIndex, columnIndex) { return true; }; -EditableGrid.prototype.readonlyWarning = function() {}; +EditableGrid.prototype.tableLoaded = function () { }; +EditableGrid.prototype.chartRendered = function () { }; +EditableGrid.prototype.tableRendered = function (containerid, className, tableid) { }; +EditableGrid.prototype.tableSorted = function (columnIndex, descending) { }; +EditableGrid.prototype.tableFiltered = function () { }; +EditableGrid.prototype.openedCellEditor = function (rowIndex, columnIndex) { }; +EditableGrid.prototype.modelChanged = function (rowIndex, columnIndex, oldValue, newValue, row) { }; +EditableGrid.prototype.rowSelected = function (oldRowIndex, newRowIndex) { }; +EditableGrid.prototype.isHeaderEditable = function (rowIndex, columnIndex) { return false; }; +EditableGrid.prototype.isEditable = function (rowIndex, columnIndex) { return true; }; +EditableGrid.prototype.readonlyWarning = function () { }; /** Notifies that a row has been deleted */ -EditableGrid.prototype.rowRemoved = function(oldRowIndex, rowId) {}; +EditableGrid.prototype.rowRemoved = function (oldRowIndex, rowId) { }; /** * Load metadata and/or data from an XML url * The callback "tableLoaded" is called when loading is complete. */ -EditableGrid.prototype.loadXML = function(url, callback, dataOnly) -{ - this.lastURL = url; +EditableGrid.prototype.loadXML = function (url, callback, dataOnly) { + this.lastURL = url; var self = this; // IE - if (window.ActiveXObject) - { + if (window.ActiveXObject) { this.xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); - this.xmlDoc.onreadystatechange = function() { + this.xmlDoc.onreadystatechange = function () { if (self.xmlDoc.readyState == 4) { self.processXML(); self._callback('xml', callback); @@ -255,8 +251,7 @@ EditableGrid.prototype.loadXML = function(url, callback, dataOnly) } // generic Ajax - else if (window.XMLHttpRequest) - { + else if (window.XMLHttpRequest) { this.xmlDoc = new XMLHttpRequest(); this.xmlDoc.onreadystatechange = function () { if (this.readyState == 4) { @@ -271,10 +266,9 @@ EditableGrid.prototype.loadXML = function(url, callback, dataOnly) } // Firefox (and some other browsers) - else if (document.implementation && document.implementation.createDocument) - { + else if (document.implementation && document.implementation.createDocument) { this.xmlDoc = document.implementation.createDocument("", "", null); - this.xmlDoc.onload = function() { + this.xmlDoc.onload = function () { self.processXML(); self._callback('xml', callback); }; @@ -282,8 +276,8 @@ EditableGrid.prototype.loadXML = function(url, callback, dataOnly) } // should never happen - else { - alert("Cannot load a XML url with this browser!"); + else { + alert("Cannot load a XML url with this browser!"); return false; } @@ -297,8 +291,7 @@ EditableGrid.prototype.loadXML = function(url, callback, dataOnly) * Contributed by Tim Consolazio of Tcoz Tech Services, tcoz@tcoz.com * http://tcoztechwire.blogspot.com/2012/04/setxmlfromstring-extension-for.html */ -EditableGrid.prototype.loadXMLFromString = function(xml) -{ +EditableGrid.prototype.loadXMLFromString = function (xml) { if (window.DOMParser) { var parser = new DOMParser(); this.xmlDoc = parser.parseFromString(xml, "application/xml"); @@ -316,8 +309,7 @@ EditableGrid.prototype.loadXMLFromString = function(xml) * Process the XML content * @private */ -EditableGrid.prototype.processXML = function() -{ +EditableGrid.prototype.processXML = function () { with (this) { // clear model and pointer to current table @@ -353,10 +345,10 @@ EditableGrid.prototype.processXML = function() for (var v = 0; v < enumValues.length; v++) { var _value = enumValues[v].getAttribute("value"); var _label = enumValues[v].firstChild ? enumValues[v].firstChild.nodeValue : ""; - optionValuesForRender[_value] = _label; + optionValuesForRender[_value] = _label; groupOptionValues.push({ value: _value, label: _label }); } - optionValues.push({ label: enumGroups[g].getAttribute("label"), values: groupOptionValues}); + optionValues.push({ label: enumGroups[g].getAttribute("label"), values: groupOptionValues }); } } else { @@ -364,7 +356,7 @@ EditableGrid.prototype.processXML = function() for (var v = 0; v < enumValues.length; v++) { var _value = enumValues[v].getAttribute("value"); var _label = enumValues[v].firstChild ? enumValues[v].firstChild.nodeValue : ""; - optionValuesForRender[_value] = _label; + optionValuesForRender[_value] = _label; optionValues.push({ value: _value, label: _label }); } } @@ -374,15 +366,21 @@ EditableGrid.prototype.processXML = function() columns.push(new Column({ name: col.getAttribute("name"), label: (typeof col.getAttribute("label") == 'string' ? col.getAttribute("label") : col.getAttribute("name")), + vertical_alignment: col.getAttribute("verticalAlignment"), datatype: (col.getAttribute("datatype") ? col.getAttribute("datatype") : "string"), editable: col.getAttribute("editable") == "true", bar: (col.getAttribute("bar") ? col.getAttribute("bar") == "true" : true), hidden: (col.getAttribute("hidden") ? col.getAttribute("hidden") == "true" : false), optionValuesForRender: optionValuesForRender, - optionValues: optionValues + optionValues: optionValues, + precision: col.getAttribute("precision"), + decimal_point: col.getAttribute("decimal_point"), + thousands_separator: col.getAttribute("thousands_separator"), + unit_before_number: col.getAttribute("unit_before_number"), + nansymbol: col.getAttribute("nansymbol") })); - } - + } + // process columns processColumns(); } @@ -401,25 +399,24 @@ EditableGrid.prototype.processXML = function() // load content var rows = xmlDoc.getElementsByTagName("row"); - for (var i = 0; i < rows.length; i++) - { + for (var i = 0; i < rows.length; i++) { // get all defined cell values var cellValues = {}; var cols = rows[i].getElementsByTagName("column"); for (var j = 0; j < cols.length; j++) { var colname = cols[j].getAttribute("name"); if (!colname) { - if (j >= columns.length) console.error("You defined too many columns for row " + (i+1)); - else colname = columns[j].name; + if (j >= columns.length) console.error("You defined too many columns for row " + (i + 1)); + else colname = columns[j].name; } cellValues[colname] = cols[j].firstChild ? cols[j].firstChild.nodeValue : ""; } // for each row we keep the orginal index, the id and all other attributes that may have been set in the XML - var rowData = { visible: true, originalIndex: i, id: rows[i].getAttribute("id") !== null ? rows[i].getAttribute("id") : defaultRowId++ }; + var rowData = { visible: true, originalIndex: i, id: rows[i].getAttribute("id") !== null ? rows[i].getAttribute("id") : defaultRowId++ }; for (var attrIndex = 0; attrIndex < rows[i].attributes.length; attrIndex++) { var node = rows[i].attributes.item(attrIndex); - if (node.nodeName != "id") rowData[node.nodeName] = node.nodeValue; + if (node.nodeName != "id") rowData[node.nodeName] = node.nodeValue; } // get column values for this rows @@ -441,14 +438,13 @@ EditableGrid.prototype.processXML = function() * Load metadata and/or data from a JSON url * The callback "tableLoaded" is called when loading is complete. */ -EditableGrid.prototype.loadJSON = function(url, callback, dataOnly) -{ - this.lastURL = url; +EditableGrid.prototype.loadJSON = function (url, callback, dataOnly) { + this.lastURL = url; var self = this; // should never happen if (!window.XMLHttpRequest) { - alert("Cannot load a JSON url with this browser!"); + alert("Cannot load a JSON url with this browser!"); return false; } @@ -467,33 +463,31 @@ EditableGrid.prototype.loadJSON = function(url, callback, dataOnly) return true; }; -EditableGrid.prototype._addUrlParameters = function(baseUrl, dataOnly) -{ +EditableGrid.prototype._addUrlParameters = function (baseUrl, dataOnly) { // we add a dummy timestamp parameter to avoid getting an old version from the browser's cache - var sep = baseUrl.indexOf('?') >= 0 ? '&' : '?'; + var sep = baseUrl.indexOf('?') >= 0 ? '&' : '?'; baseUrl += sep + (new Date().getTime()); if (!this.serverSide) return baseUrl; // add pagination, filtering and sorting parameters to the base url return baseUrl - + "&page=" + (this.currentPageIndex + 1) - + "&filter=" + (this.currentFilter ? encodeURIComponent(this.currentFilter) : "") - + "&sort=" + (this.sortedColumnName && this.sortedColumnName != -1 ? encodeURIComponent(this.sortedColumnName) : "") - + "&asc=" + (this.sortDescending ? 0 : 1) - + (dataOnly ? '&data_only=1' : ''); + + "&page=" + (this.currentPageIndex + 1) + + "&filter=" + (this.currentFilter ? encodeURIComponent(this.currentFilter) : "") + + "&sort=" + (this.sortedColumnName && this.sortedColumnName != -1 ? encodeURIComponent(this.sortedColumnName) : "") + + "&asc=" + (this.sortDescending ? 0 : 1) + + (dataOnly ? '&data_only=1' : ''); }; -EditableGrid.prototype._callback = function(type, callback) -{ - if (callback) callback.call(this); +EditableGrid.prototype._callback = function (type, callback) { + if (callback) callback.call(this); else { if (this.serverSide) { // deferred refreshGrid: first load the updated data from the server then call the original refreshGrid - this.refreshGrid = function(baseUrl) { - var callback = function() { EditableGrid.prototype.refreshGrid.call(this); }; + this.refreshGrid = function (baseUrl) { + var callback = function () { EditableGrid.prototype.refreshGrid.call(this); }; var load = type == 'xml' ? this.loadXML : this.loadJSON; load.call(this, baseUrl || this.lastURL, callback, true); }; @@ -507,8 +501,7 @@ EditableGrid.prototype._callback = function(type, callback) * Load metadata and/or data from a JSON string * No callback "tableLoaded" is called since this is a synchronous operation. */ -EditableGrid.prototype.loadJSONFromString = function(json) -{ +EditableGrid.prototype.loadJSONFromString = function (json) { return this.processJSON(json); }; @@ -516,18 +509,15 @@ EditableGrid.prototype.loadJSONFromString = function(json) * Load metadata and/or data from a Javascript object * No callback "tableLoaded" is called since this is a synchronous operation. */ -EditableGrid.prototype.load = function(object) -{ +EditableGrid.prototype.load = function (object) { return this.processJSON(object); }; /** * Update and render data for given rows from a Javascript object */ -EditableGrid.prototype.update = function(object) -{ - if (object.data) for (var i = 0; i < object.data.length; i++) - { +EditableGrid.prototype.update = function (object) { + if (object.data) for (var i = 0; i < object.data.length; i++) { var row = object.data[i]; if (!row.id || !row.values) continue; @@ -536,7 +526,7 @@ EditableGrid.prototype.update = function(object) var rowData = this.data[rowIndex]; // row values can be given as an array (same order as columns) or as an object (associative array) - if (Object.prototype.toString.call(row.values) !== '[object Array]' ) cellValues = row.values; + if (Object.prototype.toString.call(row.values) !== '[object Array]') cellValues = row.values; else { cellValues = {}; for (var j = 0; j < row.values.length && j < this.columns.length; j++) cellValues[this.columns[j].name] = row.values[j]; @@ -554,7 +544,7 @@ EditableGrid.prototype.update = function(object) // render row var tr = this.getRow(rowIndex); - for (var j = 0; j < tr.cells.length && j < this.columns.length; j++) if (this.columns[j].renderable) this.columns[j].cellRenderer._render(rowIndex, j, tr.cells[j], this.getValueAt(rowIndex,j)); + for (var j = 0; j < tr.cells.length && j < this.columns.length; j++) if (this.columns[j].renderable) this.columns[j].cellRenderer._render(rowIndex, j, tr.cells[j], this.getValueAt(rowIndex, j)); this.tableRendered(this.currentContainerid, this.currentClassName, this.currentTableid); } }; @@ -563,8 +553,7 @@ EditableGrid.prototype.update = function(object) * Process the JSON content * @private */ -EditableGrid.prototype.processJSON = function(jsonData) -{ +EditableGrid.prototype.processJSON = function (jsonData) { if (typeof jsonData == "string") jsonData = eval("(" + jsonData + ")"); if (!jsonData) return false; @@ -602,12 +591,18 @@ EditableGrid.prototype.processJSON = function(jsonData) this.columns.push(new Column({ name: columndata.name, label: (columndata.label ? columndata.label : columndata.name), + vertical_alignment: columndata.verticalAlignment, datatype: (columndata.datatype ? columndata.datatype : "string"), editable: (columndata.editable ? true : false), bar: (typeof columndata.bar == 'undefined' ? true : (columndata.bar || false)), hidden: (typeof columndata.hidden == 'undefined' ? false : (columndata.hidden ? true : false)), optionValuesForRender: optionValuesForRender, - optionValues: optionValues + optionValues: optionValues, + precision: columndata.precision, + decimal_point: columndata.decimal_point, + thousands_separator: columndata.thousands_separator, + unit_before_number: columndata.unit_before_number, + nansymbol: columndata.nansymbol })); } @@ -627,20 +622,19 @@ EditableGrid.prototype.processJSON = function(jsonData) var defaultRowId = 1; // load content - if (jsonData.data) for (var i = 0; i < jsonData.data.length; i++) - { + if (jsonData.data) for (var i = 0; i < jsonData.data.length; i++) { var row = jsonData.data[i]; if (!row.values) continue; // row values can be given as an array (same order as columns) or as an object (associative array) - if (Object.prototype.toString.call(row.values) !== '[object Array]' ) cellValues = row.values; + if (Object.prototype.toString.call(row.values) !== '[object Array]') cellValues = row.values; else { cellValues = {}; for (var j = 0; j < row.values.length && j < this.columns.length; j++) cellValues[this.columns[j].name] = row.values[j]; } // for each row we keep the orginal index, the id and all other attributes that may have been set in the JSON - var rowData = { visible: true, originalIndex: i, id: row.id !== undefined && row.id !== null ? row.id : defaultRowId++ }; + var rowData = { visible: true, originalIndex: i, id: row.id !== undefined && row.id !== null ? row.id : defaultRowId++ }; for (var attributeName in row) if (attributeName != "id" && attributeName != "values") rowData[attributeName] = row[attributeName]; // get column values for this rows @@ -661,8 +655,7 @@ EditableGrid.prototype.processJSON = function(jsonData) * Process columns * @private */ -EditableGrid.prototype.processColumns = function() -{ +EditableGrid.prototype.processColumns = function () { for (var columnIndex = 0; columnIndex < this.columns.length; columnIndex++) { var column = this.columns[columnIndex]; @@ -682,7 +675,7 @@ EditableGrid.prototype.processColumns = function() if (!column.headerRenderer) this._createHeaderRenderer(column); // create suited cell editor if none given - if (!column.cellEditor) this._createCellEditor(column); + if (!column.cellEditor) this._createCellEditor(column); if (!column.headerEditor) this._createHeaderEditor(column); // add default cell validators based on the column type @@ -695,15 +688,7 @@ EditableGrid.prototype.processColumns = function() * @private */ -EditableGrid.prototype.parseColumnType = function(column) -{ - // reset - column.unit = null; - column.precision = -1; - column.decimal_point = ','; - column.thousands_separator = '.'; - column.unit_before_number = false; - column.nansymbol = ''; +EditableGrid.prototype.parseColumnType = function (column) { // extract precision, unit and number format from type if 6 given if (column.datatype.match(/(.*)\((.*),(.*),(.*),(.*),(.*),(.*)\)$/)) { @@ -777,13 +762,12 @@ EditableGrid.prototype.parseColumnType = function(column) * @private */ -EditableGrid.prototype.getTypedValue = function(columnIndex, cellValue) -{ +EditableGrid.prototype.getTypedValue = function (columnIndex, cellValue) { if (cellValue === null) return cellValue; var colType = this.getColumnType(columnIndex); if (colType == 'boolean') cellValue = (cellValue && cellValue != 0 && cellValue != "false" && cellValue != "f") ? true : false; - if (colType == 'integer') { cellValue = parseInt(cellValue, 10); } + if (colType == 'integer') { cellValue = parseInt(cellValue, 10); } if (colType == 'double') { cellValue = parseFloat(cellValue); } if (colType == 'string') { cellValue = "" + cellValue; } @@ -795,8 +779,7 @@ EditableGrid.prototype.getTypedValue = function(columnIndex, cellValue) * The second parameter can be used to give the column definitions. * This parameter is left for compatibility, but is deprecated: you should now use "load" to setup the metadata. */ -EditableGrid.prototype.attachToHTMLTable = function(_table, _columns) -{ +EditableGrid.prototype.attachToHTMLTable = function (_table, _columns) { // clear model and pointer to current table this.data = []; this.dataUnfiltered = null; @@ -810,7 +793,7 @@ EditableGrid.prototype.attachToHTMLTable = function(_table, _columns) } // get pointers to table components - this.table = typeof _table == 'string' ? _$(_table) : _table ; + this.table = typeof _table == 'string' ? _$(_table) : _table; if (!this.table) console.error("Invalid table given: " + _table); this.tHead = this.table.tHead; this.tBody = this.table.tBodies[0]; @@ -828,7 +811,7 @@ EditableGrid.prototype.attachToHTMLTable = function(_table, _columns) } // if header is empty use first body row as header - if (this.tHead.rows.length == 0 && this.tBody.rows.length > 0) + if (this.tHead.rows.length == 0 && this.tBody.rows.length > 0) this.tHead.appendChild(this.tBody.rows[0]); // get number of rows in header @@ -862,47 +845,44 @@ EditableGrid.prototype.attachToHTMLTable = function(_table, _columns) * Creates a suitable cell renderer for the column * @private */ -EditableGrid.prototype._createCellRenderer = function(column) -{ - column.cellRenderer = +EditableGrid.prototype._createCellRenderer = function (column) { + column.cellRenderer = column.enumProvider && column.datatype == "list" && typeof MultiselectCellRenderer != 'undefined' ? new MultiselectCellRenderer() : column.enumProvider ? new EnumCellRenderer() : column.datatype == "integer" || column.datatype == "double" ? new NumberCellRenderer() : - column.datatype == "boolean" ? new CheckboxCellRenderer() : - column.datatype == "email" ? new EmailCellRenderer() : - column.datatype == "website" || column.datatype == "url" ? new WebsiteCellRenderer() : + column.datatype == "boolean" ? new CheckboxCellRenderer() : + column.datatype == "email" ? new EmailCellRenderer() : + column.datatype == "website" || column.datatype == "url" ? new WebsiteCellRenderer() : column.datatype == "date" ? new DateCellRenderer() : new CellRenderer(); - // give access to the column from the cell renderer - if (column.cellRenderer) { - column.cellRenderer.editablegrid = this; - column.cellRenderer.column = column; - } + // give access to the column from the cell renderer + if (column.cellRenderer) { + column.cellRenderer.editablegrid = this; + column.cellRenderer.column = column; + } }; /** * Creates a suitable header cell renderer for the column * @private */ -EditableGrid.prototype._createHeaderRenderer = function(column) -{ +EditableGrid.prototype._createHeaderRenderer = function (column) { column.headerRenderer = (this.enableSort && column.datatype != "html") ? new SortHeaderRenderer(column.name) : new CellRenderer(); // give access to the column from the header cell renderer if (column.headerRenderer) { column.headerRenderer.editablegrid = this; column.headerRenderer.column = column; - } + } }; /** * Creates a suitable cell editor for the column * @private */ -EditableGrid.prototype._createCellEditor = function(column) -{ - column.cellEditor = +EditableGrid.prototype._createCellEditor = function (column) { + column.cellEditor = column.enumProvider && column.datatype == "list" && typeof MultiselectCellEditor != 'undefined' ? new MultiselectCellEditor() : column.enumProvider ? new SelectCellEditor() : column.datatype == "integer" || column.datatype == "double" ? new NumberCellEditor(column.datatype) : @@ -910,13 +890,13 @@ EditableGrid.prototype._createCellEditor = function(column) column.datatype == "email" ? new TextCellEditor(column.precision) : column.datatype == "website" || column.datatype == "url" ? new TextCellEditor(column.precision) : column.datatype == "date" ? (typeof jQuery == 'undefined' || typeof jQuery.datepicker == 'undefined' ? new TextCellEditor(column.precision, 10) : new DateCellEditor({ fieldSize: column.precision, maxLength: 10 })) : - new TextCellEditor(column.precision); + new TextCellEditor(column.precision); - // give access to the column from the cell editor - if (column.cellEditor) { - column.cellEditor.editablegrid = this; - column.cellEditor.column = column; - } + // give access to the column from the cell editor + if (column.cellEditor) { + column.cellEditor.editablegrid = this; + column.cellEditor.column = column; + } }; @@ -925,9 +905,8 @@ EditableGrid.prototype._createCellEditor = function(column) * Creates a suitable header cell editor for the column * @private */ -EditableGrid.prototype._createHeaderEditor = function(column) -{ - column.headerEditor = new TextCellEditor(); +EditableGrid.prototype._createHeaderEditor = function (column) { + column.headerEditor = new TextCellEditor(); // give access to the column from the cell editor if (column.headerEditor) { @@ -939,28 +918,25 @@ EditableGrid.prototype._createHeaderEditor = function(column) /** * Returns the number of rows */ -EditableGrid.prototype.getRowCount = function() -{ +EditableGrid.prototype.getRowCount = function () { return this.data.length; }; /** * Returns the number of rows, not taking the filter into account if any */ -EditableGrid.prototype.getUnfilteredRowCount = function() -{ +EditableGrid.prototype.getUnfilteredRowCount = function () { // given if server-side filtering is involved if (this.unfilteredRowCount > 0) return this.unfilteredRowCount; - var _data = this.dataUnfiltered == null ? this.data : this.dataUnfiltered; + var _data = this.dataUnfiltered == null ? this.data : this.dataUnfiltered; return _data.length; }; /** * Returns the number of rows in all pages */ -EditableGrid.prototype.getTotalRowCount = function() -{ +EditableGrid.prototype.getTotalRowCount = function () { // different from getRowCount only is server-side pagination is involved if (this.totalRowCount > 0) return this.totalRowCount; @@ -970,8 +946,7 @@ EditableGrid.prototype.getTotalRowCount = function() /** * Returns the number of columns */ -EditableGrid.prototype.getColumnCount = function() -{ +EditableGrid.prototype.getColumnCount = function () { return this.columns.length; }; @@ -979,8 +954,7 @@ EditableGrid.prototype.getColumnCount = function() * Returns true if the column exists * @param {Object} columnIndexOrName index or name of the column */ -EditableGrid.prototype.hasColumn = function(columnIndexOrName) -{ +EditableGrid.prototype.hasColumn = function (columnIndexOrName) { return this.getColumnIndex(columnIndexOrName) >= 0; }; @@ -988,8 +962,7 @@ EditableGrid.prototype.hasColumn = function(columnIndexOrName) * Returns the column * @param {Object} columnIndexOrName index or name of the column */ -EditableGrid.prototype.getColumn = function(columnIndexOrName) -{ +EditableGrid.prototype.getColumn = function (columnIndexOrName) { var colIndex = this.getColumnIndex(columnIndexOrName); if (colIndex < 0) { console.error("[getColumn] Column not found with index or name " + columnIndexOrName); return null; } return this.columns[colIndex]; @@ -999,8 +972,7 @@ EditableGrid.prototype.getColumn = function(columnIndexOrName) * Returns the name of a column * @param {Object} columnIndexOrName index or name of the column */ -EditableGrid.prototype.getColumnName = function(columnIndexOrName) -{ +EditableGrid.prototype.getColumnName = function (columnIndexOrName) { return this.getColumn(columnIndexOrName).name; }; @@ -1008,8 +980,7 @@ EditableGrid.prototype.getColumnName = function(columnIndexOrName) * Returns the label of a column * @param {Object} columnIndexOrName index or name of the column */ -EditableGrid.prototype.getColumnLabel = function(columnIndexOrName) -{ +EditableGrid.prototype.getColumnLabel = function (columnIndexOrName) { return this.getColumn(columnIndexOrName).label; }; @@ -1017,8 +988,7 @@ EditableGrid.prototype.getColumnLabel = function(columnIndexOrName) * Returns the type of a column * @param {Object} columnIndexOrName index or name of the column */ -EditableGrid.prototype.getColumnType = function(columnIndexOrName) -{ +EditableGrid.prototype.getColumnType = function (columnIndexOrName) { return this.getColumn(columnIndexOrName).datatype; }; @@ -1026,8 +996,7 @@ EditableGrid.prototype.getColumnType = function(columnIndexOrName) * Returns the unit of a column * @param {Object} columnIndexOrName index or name of the column */ -EditableGrid.prototype.getColumnUnit = function(columnIndexOrName) -{ +EditableGrid.prototype.getColumnUnit = function (columnIndexOrName) { return this.getColumn(columnIndexOrName).unit; }; @@ -1035,8 +1004,7 @@ EditableGrid.prototype.getColumnUnit = function(columnIndexOrName) * Returns the precision of a column * @param {Object} columnIndexOrName index or name of the column */ -EditableGrid.prototype.getColumnPrecision = function(columnIndexOrName) -{ +EditableGrid.prototype.getColumnPrecision = function (columnIndexOrName) { return this.getColumn(columnIndexOrName).precision; }; @@ -1044,8 +1012,7 @@ EditableGrid.prototype.getColumnPrecision = function(columnIndexOrName) * Returns true if the column is to be displayed in a bar chart * @param {Object} columnIndexOrName index or name of the column */ -EditableGrid.prototype.isColumnBar = function(columnIndexOrName) -{ +EditableGrid.prototype.isColumnBar = function (columnIndexOrName) { var column = this.getColumn(columnIndexOrName); return (column.bar && column.isNumerical()); }; @@ -1054,8 +1021,7 @@ EditableGrid.prototype.isColumnBar = function(columnIndexOrName) * Returns the stack of a column (for stacked bar charts) * @param {Object} columnIndexOrName index or name of the column */ -EditableGrid.prototype.getColumnStack = function(columnIndexOrName) -{ +EditableGrid.prototype.getColumnStack = function (columnIndexOrName) { var column = this.getColumn(columnIndexOrName); return column.isNumerical() ? column.bar : ''; }; @@ -1065,8 +1031,7 @@ EditableGrid.prototype.getColumnStack = function(columnIndexOrName) * Returns true if the column is numerical (double or integer) * @param {Object} columnIndexOrName index or name of the column */ -EditableGrid.prototype.isColumnNumerical = function(columnIndexOrName) -{ +EditableGrid.prototype.isColumnNumerical = function (columnIndexOrName) { var column = this.getColumn(columnIndexOrName); return column.isNumerical();; }; @@ -1076,8 +1041,7 @@ EditableGrid.prototype.isColumnNumerical = function(columnIndexOrName) * @param {Integer} rowIndex * @param {Integer} columnIndex */ -EditableGrid.prototype.getValueAt = function(rowIndex, columnIndex) -{ +EditableGrid.prototype.getValueAt = function (rowIndex, columnIndex) { // check and get column if (columnIndex < 0 || columnIndex >= this.columns.length) { console.error("[getValueAt] Invalid column index " + columnIndex); return null; } var column = this.columns[columnIndex]; @@ -1095,11 +1059,10 @@ EditableGrid.prototype.getValueAt = function(rowIndex, columnIndex) * @param {Integer} rowIndex * @param {Integer} columnIndex */ -EditableGrid.prototype.getDisplayValueAt = function(rowIndex, columnIndex) -{ +EditableGrid.prototype.getDisplayValueAt = function (rowIndex, columnIndex) { // use renderer to get the value that must be used for sorting and filtering var value = this.getValueAt(rowIndex, columnIndex); - var renderer = rowIndex < 0 ? this.columns[columnIndex].headerRenderer : this.columns[columnIndex].cellRenderer; + var renderer = rowIndex < 0 ? this.columns[columnIndex].headerRenderer : this.columns[columnIndex].cellRenderer; return renderer.getDisplayValue(rowIndex, value); }; @@ -1111,8 +1074,7 @@ EditableGrid.prototype.getDisplayValueAt = function(rowIndex, columnIndex) * @param {Object} value * @param {Boolean} render */ -EditableGrid.prototype.setValueAt = function(rowIndex, columnIndex, value, render) -{ +EditableGrid.prototype.setValueAt = function (rowIndex, columnIndex, value, render) { if (typeof render == "undefined") render = true; var previousValue = null;; @@ -1151,8 +1113,7 @@ EditableGrid.prototype.setValueAt = function(rowIndex, columnIndex, value, rende * Find column index from its name * @param {Object} columnIndexOrName index or name of the column */ -EditableGrid.prototype.getColumnIndex = function(columnIndexOrName) -{ +EditableGrid.prototype.getColumnIndex = function (columnIndexOrName) { if (typeof columnIndexOrName == "undefined" || columnIndexOrName === "") return -1; // TODO: problem because the name of a column could be a valid index, and we cannot make the distinction here! @@ -1170,8 +1131,7 @@ EditableGrid.prototype.getColumnIndex = function(columnIndexOrName) * Get HTML row object at given index * @param {Integer} index of the row */ -EditableGrid.prototype.getRow = function(rowIndex) -{ +EditableGrid.prototype.getRow = function (rowIndex) { if (rowIndex < 0) return this.tHead.rows[rowIndex + this.nbHeaderRows]; if (typeof this.data[rowIndex] == 'undefined') { console.error("[getRow] Invalid row index " + rowIndex); return null; } return _$(this._getRowDOMId(this.data[rowIndex].id)); @@ -1181,8 +1141,7 @@ EditableGrid.prototype.getRow = function(rowIndex) * Get row id for given row index * @param {Integer} index of the row */ -EditableGrid.prototype.getRowId = function(rowIndex) -{ +EditableGrid.prototype.getRowId = function (rowIndex) { return (rowIndex < 0 || rowIndex >= this.data.length) ? null : this.data[rowIndex]['id']; }; @@ -1190,11 +1149,10 @@ EditableGrid.prototype.getRowId = function(rowIndex) * Get index of row (in filtered data) with given id * @param {Integer} rowId or HTML row object */ -EditableGrid.prototype.getRowIndex = function(rowId) -{ +EditableGrid.prototype.getRowIndex = function (rowId) { rowId = typeof rowId == 'object' ? rowId.rowId : rowId; for (var rowIndex = 0; rowIndex < this.data.length; rowIndex++) if (this.data[rowIndex].id == rowId) return rowIndex; - return -1; + return -1; }; /** @@ -1202,8 +1160,7 @@ EditableGrid.prototype.getRowIndex = function(rowId) * @param {Integer} index of the row * @param {String} name of the attribute */ -EditableGrid.prototype.getRowAttribute = function(rowIndex, attributeName) -{ +EditableGrid.prototype.getRowAttribute = function (rowIndex, attributeName) { if (typeof this.data[rowIndex] == 'undefined') { console.error('Invalid rowindex ' + rowIndex); return null; @@ -1218,8 +1175,7 @@ EditableGrid.prototype.getRowAttribute = function(rowIndex, attributeName) * @param {String} name of the attribute * @param value of the attribute */ -EditableGrid.prototype.setRowAttribute = function(rowIndex, attributeName, attributeValue) -{ +EditableGrid.prototype.setRowAttribute = function (rowIndex, attributeName, attributeValue) { this.data[rowIndex][attributeName] = attributeValue; }; @@ -1227,8 +1183,7 @@ EditableGrid.prototype.setRowAttribute = function(rowIndex, attributeName, attri * Get Id of row in HTML DOM * @private */ -EditableGrid.prototype._getRowDOMId = function(rowId) -{ +EditableGrid.prototype._getRowDOMId = function (rowId) { return this.currentContainerid != null ? this.name + "_" + rowId : rowId; }; @@ -1237,8 +1192,7 @@ EditableGrid.prototype._getRowDOMId = function(rowId) * Deprecated: use remove(rowIndex) instead * @param {Integer} rowId */ -EditableGrid.prototype.removeRow = function(rowId) -{ +EditableGrid.prototype.removeRow = function (rowId) { return this.remove(this.getRowIndex(rowId)); }; @@ -1246,11 +1200,10 @@ EditableGrid.prototype.removeRow = function(rowId) * Remove row at given index * @param {Integer} rowIndex */ -EditableGrid.prototype.remove = function(rowIndex) -{ +EditableGrid.prototype.remove = function (rowIndex) { var rowId = this.data[rowIndex].id; var originalIndex = this.data[rowIndex].originalIndex; - var _data = this.dataUnfiltered == null ? this.data : this.dataUnfiltered; + var _data = this.dataUnfiltered == null ? this.data : this.dataUnfiltered; // delete row from DOM (needed for attach mode) var tr = _$(this._getRowDOMId(rowId)); @@ -1264,7 +1217,7 @@ EditableGrid.prototype.remove = function(rowIndex) if (this.dataUnfiltered != null) for (var r = 0; r < this.dataUnfiltered.length; r++) if (this.dataUnfiltered[r].id == rowId) { this.dataUnfiltered.splice(r, 1); break; } // callback - this.rowRemoved(rowIndex,rowId); + this.rowRemoved(rowIndex, rowId); // refresh grid this.refreshGrid(); @@ -1274,10 +1227,9 @@ EditableGrid.prototype.remove = function(rowIndex) * Return an associative array (column name => value) of values in row with given index * @param {Integer} rowIndex */ -EditableGrid.prototype.getRowValues = function(rowIndex) -{ +EditableGrid.prototype.getRowValues = function (rowIndex) { var rowValues = {}; - for (var columnIndex = 0; columnIndex < this.getColumnCount(); columnIndex++) { + for (var columnIndex = 0; columnIndex < this.getColumnCount(); columnIndex++) { rowValues[this.getColumnName(columnIndex)] = this.getValueAt(rowIndex, columnIndex); } return rowValues; @@ -1289,8 +1241,7 @@ EditableGrid.prototype.getRowValues = function(rowIndex) * @param {Integer} columns * @param {Boolean} dontSort */ -EditableGrid.prototype.append = function(rowId, cellValues, rowAttributes, dontSort) -{ +EditableGrid.prototype.append = function (rowId, cellValues, rowAttributes, dontSort) { return this.insert(this.data.length, rowId, cellValues, rowAttributes, dontSort); }; @@ -1301,8 +1252,7 @@ EditableGrid.prototype.append = function(rowId, cellValues, rowAttributes, dontS * @param {Integer} columns * @param {Boolean} dontSort */ -EditableGrid.prototype.addRow = function(rowId, cellValues, rowAttributes, dontSort) -{ +EditableGrid.prototype.addRow = function (rowId, cellValues, rowAttributes, dontSort) { return this.append(rowId, cellValues, rowAttributes, dontSort); }; @@ -1311,8 +1261,7 @@ EditableGrid.prototype.addRow = function(rowId, cellValues, rowAttributes, dontS * We know rowIndex is valid, unless the table is empty * @private */ -EditableGrid.prototype._insert = function(rowIndex, offset, rowId, cellValues, rowAttributes, dontSort) -{ +EditableGrid.prototype._insert = function (rowIndex, offset, rowId, cellValues, rowAttributes, dontSort) { var originalRowId = null; var originalIndex = 0; var _data = this.dataUnfiltered == null ? this.data : this.dataUnfiltered; @@ -1332,7 +1281,7 @@ EditableGrid.prototype._insert = function(rowIndex, offset, rowId, cellValues, r // build data for new row var rowData = { visible: true, originalIndex: originalIndex, id: rowId }; - if (rowAttributes) for (var attributeName in rowAttributes) rowData[attributeName] = rowAttributes[attributeName]; + if (rowAttributes) for (var attributeName in rowAttributes) rowData[attributeName] = rowAttributes[attributeName]; rowData.columns = []; for (var c = 0; c < this.columns.length; c++) { var cellValue = this.columns[c].name in cellValues ? cellValues[this.columns[c].name] : ""; @@ -1364,8 +1313,7 @@ EditableGrid.prototype._insert = function(rowIndex, offset, rowId, cellValues, r * @param {Integer} columns * @param {Boolean} dontSort */ -EditableGrid.prototype.insert = function(rowIndex, rowId, cellValues, rowAttributes, dontSort) -{ +EditableGrid.prototype.insert = function (rowIndex, rowId, cellValues, rowAttributes, dontSort) { if (rowIndex < 0) rowIndex = 0; if (rowIndex >= this.data.length && this.data.length > 0) return this.insertAfter(this.data.length - 1, rowId, cellValues, rowAttributes, dontSort); return this._insert(rowIndex, 0, rowId, cellValues, rowAttributes, dontSort); @@ -1378,10 +1326,9 @@ EditableGrid.prototype.insert = function(rowIndex, rowId, cellValues, rowAttribu * @param {Integer} columns * @param {Boolean} dontSort */ -EditableGrid.prototype.insertAfter = function(rowIndex, rowId, cellValues, rowAttributes, dontSort) -{ +EditableGrid.prototype.insertAfter = function (rowIndex, rowId, cellValues, rowAttributes, dontSort) { if (rowIndex < 0) return this.insert(0, rowId, cellValues, rowAttributes, dontSort); - if (rowIndex >= this.data.length) rowIndex = Math.max(0, this.data.length - 1); + if (rowIndex >= this.data.length) rowIndex = Math.max(0, this.data.length - 1); return this._insert(rowIndex, 1, rowId, cellValues, rowAttributes, dontSort); }; @@ -1390,8 +1337,7 @@ EditableGrid.prototype.insertAfter = function(rowIndex, rowId, cellValues, rowAt * @param {Object} columnIndexOrName index or name of the column * @param {CellRenderer} cellRenderer */ -EditableGrid.prototype.setHeaderRenderer = function(columnIndexOrName, cellRenderer) -{ +EditableGrid.prototype.setHeaderRenderer = function (columnIndexOrName, cellRenderer) { var columnIndex = this.getColumnIndex(columnIndexOrName); if (columnIndex < 0) console.error("[setHeaderRenderer] Invalid column: " + columnIndexOrName); else { @@ -1415,8 +1361,7 @@ EditableGrid.prototype.setHeaderRenderer = function(columnIndexOrName, cellRende * @param {Object} columnIndexOrName index or name of the column * @param {CellRenderer} cellRenderer */ -EditableGrid.prototype.setCellRenderer = function(columnIndexOrName, cellRenderer) -{ +EditableGrid.prototype.setCellRenderer = function (columnIndexOrName, cellRenderer) { var columnIndex = this.getColumnIndex(columnIndexOrName); if (columnIndex < 0) console.error("[setCellRenderer] Invalid column: " + columnIndexOrName); else { @@ -1436,8 +1381,7 @@ EditableGrid.prototype.setCellRenderer = function(columnIndexOrName, cellRendere * @param {Object} columnIndexOrName index or name of the column * @param {CellEditor} cellEditor */ -EditableGrid.prototype.setCellEditor = function(columnIndexOrName, cellEditor) -{ +EditableGrid.prototype.setCellEditor = function (columnIndexOrName, cellEditor) { var columnIndex = this.getColumnIndex(columnIndexOrName); if (columnIndex < 0) console.error("[setCellEditor] Invalid column: " + columnIndexOrName); else { @@ -1457,8 +1401,7 @@ EditableGrid.prototype.setCellEditor = function(columnIndexOrName, cellEditor) * @param {Object} columnIndexOrName index or name of the column * @param {CellEditor} cellEditor */ -EditableGrid.prototype.setHeaderEditor = function(columnIndexOrName, cellEditor) -{ +EditableGrid.prototype.setHeaderEditor = function (columnIndexOrName, cellEditor) { var columnIndex = this.getColumnIndex(columnIndexOrName); if (columnIndex < 0) console.error("[setHeaderEditor] Invalid column: " + columnIndexOrName); else { @@ -1478,8 +1421,7 @@ EditableGrid.prototype.setHeaderEditor = function(columnIndexOrName, cellEditor) * @param {Object} columnIndexOrName index or name of the column * @param {EnumProvider} enumProvider */ -EditableGrid.prototype.setEnumProvider = function(columnIndexOrName, enumProvider) -{ +EditableGrid.prototype.setEnumProvider = function (columnIndexOrName, enumProvider) { var columnIndex = this.getColumnIndex(columnIndexOrName); if (columnIndex < 0) console.error("[setEnumProvider] Invalid column: " + columnIndexOrName); else { @@ -1500,8 +1442,7 @@ EditableGrid.prototype.setEnumProvider = function(columnIndexOrName, enumProvide * Clear all cell validators for the specified column index * @param {Object} columnIndexOrName index or name of the column */ -EditableGrid.prototype.clearCellValidators = function(columnIndexOrName) -{ +EditableGrid.prototype.clearCellValidators = function (columnIndexOrName) { var columnIndex = this.getColumnIndex(columnIndexOrName); if (columnIndex < 0) console.error("[clearCellValidators] Invalid column: " + columnIndexOrName); else this.columns[columnIndex].cellValidators = []; @@ -1511,8 +1452,7 @@ EditableGrid.prototype.clearCellValidators = function(columnIndexOrName) * Adds default cell validators for the specified column index (according to the column type) * @param {Object} columnIndexOrName index or name of the column */ -EditableGrid.prototype.addDefaultCellValidators = function(columnIndexOrName) -{ +EditableGrid.prototype.addDefaultCellValidators = function (columnIndexOrName) { var columnIndex = this.getColumnIndex(columnIndexOrName); if (columnIndex < 0) console.error("[addDefaultCellValidators] Invalid column: " + columnIndexOrName); return this._addDefaultCellValidators(this.columns[columnIndex]); @@ -1522,8 +1462,7 @@ EditableGrid.prototype.addDefaultCellValidators = function(columnIndexOrName) * Adds default cell validators for the specified column * @private */ -EditableGrid.prototype._addDefaultCellValidators = function(column) -{ +EditableGrid.prototype._addDefaultCellValidators = function (column) { if (column.datatype == "integer" || column.datatype == "double") column.cellValidators.push(new NumberCellValidator(column.datatype)); else if (column.datatype == "email") column.cellValidators.push(new EmailCellValidator()); else if (column.datatype == "website" || column.datatype == "url") column.cellValidators.push(new WebsiteCellValidator()); @@ -1535,8 +1474,7 @@ EditableGrid.prototype._addDefaultCellValidators = function(column) * @param {Object} columnIndexOrName index or name of the column * @param {CellValidator} cellValidator */ -EditableGrid.prototype.addCellValidator = function(columnIndexOrName, cellValidator) -{ +EditableGrid.prototype.addCellValidator = function (columnIndexOrName, cellValidator) { var columnIndex = this.getColumnIndex(columnIndexOrName); if (columnIndex < 0) console.error("[addCellValidator] Invalid column: " + columnIndexOrName); else this.columns[columnIndex].cellValidators.push(cellValidator); @@ -1548,16 +1486,14 @@ EditableGrid.prototype.addCellValidator = function(columnIndexOrName, cellValida * @param caption * @return */ -EditableGrid.prototype.setCaption = function(caption) -{ +EditableGrid.prototype.setCaption = function (caption) { this.caption = caption; }; /** * Get cell element at given row and column */ -EditableGrid.prototype.getCell = function(rowIndex, columnIndex) -{ +EditableGrid.prototype.getCell = function (rowIndex, columnIndex) { var row = this.getRow(rowIndex); if (row == null) { console.error("[getCell] Invalid row index " + rowIndex); return null; } return row.cells[columnIndex]; @@ -1567,13 +1503,12 @@ EditableGrid.prototype.getCell = function(rowIndex, columnIndex) * Get cell X position relative to the first non static offset parent * @private */ -EditableGrid.prototype.getCellX = function(oElement) -{ +EditableGrid.prototype.getCellX = function (oElement) { var iReturnValue = 0; while (oElement != null && this.isStatic(oElement)) try { iReturnValue += oElement.offsetLeft; oElement = oElement.offsetParent; - } catch(err) { oElement = null; } + } catch (err) { oElement = null; } return iReturnValue; }; @@ -1581,13 +1516,12 @@ EditableGrid.prototype.getCellX = function(oElement) * Get cell Y position relative to the first non static offset parent * @private */ -EditableGrid.prototype.getCellY = function(oElement) -{ +EditableGrid.prototype.getCellY = function (oElement) { var iReturnValue = 0; while (oElement != null && this.isStatic(oElement)) try { iReturnValue += oElement.offsetTop; oElement = oElement.offsetParent; - } catch(err) { oElement = null; } + } catch (err) { oElement = null; } return iReturnValue; }; @@ -1595,13 +1529,12 @@ EditableGrid.prototype.getCellY = function(oElement) * Get X scroll offset relative to the first non static offset parent * @private */ -EditableGrid.prototype.getScrollXOffset = function(oElement) -{ +EditableGrid.prototype.getScrollXOffset = function (oElement) { var iReturnValue = 0; while (oElement != null && typeof oElement.scrollLeft != 'undefined' && this.isStatic(oElement) && oElement != document.body) try { iReturnValue += parseInt(oElement.scrollLeft); oElement = oElement.parentNode; - } catch(err) { oElement = null; } + } catch (err) { oElement = null; } return iReturnValue; }; @@ -1609,13 +1542,12 @@ EditableGrid.prototype.getScrollXOffset = function(oElement) * Get Y scroll offset relative to the first non static offset parent * @private */ -EditableGrid.prototype.getScrollYOffset = function(oElement) -{ +EditableGrid.prototype.getScrollYOffset = function (oElement) { var iReturnValue = 0; while (oElement != null && typeof oElement.scrollTop != 'undefined' && this.isStatic(oElement) && oElement != document.body) try { iReturnValue += parseInt(oElement.scrollTop); oElement = oElement.parentNode; - } catch(err) { oElement = null; } + } catch (err) { oElement = null; } return iReturnValue; }; @@ -1626,8 +1558,7 @@ EditableGrid.prototype.getScrollYOffset = function(oElement) * @param tableid * @return */ -EditableGrid.prototype._rendergrid = function(containerid, className, tableid) -{ +EditableGrid.prototype._rendergrid = function (containerid, className, tableid) { with (this) { lastSelectedRowIndex = -1; @@ -1636,7 +1567,7 @@ EditableGrid.prototype._rendergrid = function(containerid, className, tableid) // if we are already attached to an existing table, just update the cell contents if (typeof table != "undefined" && table != null) { - var _data = dataUnfiltered == null ? data : dataUnfiltered; + var _data = dataUnfiltered == null ? data : dataUnfiltered; // render headers _renderHeaders(); @@ -1658,7 +1589,7 @@ EditableGrid.prototype._rendergrid = function(containerid, className, tableid) } else { if (skipped < pageSize * _currentPageIndex) { - skipped++; + skipped++; if (rows[i].style.display != 'none') { rows[i].style.display = 'none'; rows[i].hidden_by_editablegrid = true; @@ -1673,8 +1604,8 @@ EditableGrid.prototype._rendergrid = function(containerid, className, tableid) } rows[i].rowId = getRowId(rowIndex); rows[i].id = _getRowDOMId(rows[i].rowId); - for (var j = 0; j < cols.length && j < columns.length; j++) - if (columns[j].renderable) columns[j].cellRenderer._render(rowIndex, j, cols[j], getValueAt(rowIndex,j)); + for (var j = 0; j < cols.length && j < columns.length; j++) + if (columns[j].renderable) columns[j].cellRenderer._render(rowIndex, j, cols[j], getValueAt(rowIndex, j)); } rowIndex++; } @@ -1682,8 +1613,8 @@ EditableGrid.prototype._rendergrid = function(containerid, className, tableid) // attach handler on click or double click table.editablegrid = this; - if (doubleclick) table.ondblclick = function(e) { this.editablegrid.mouseClicked(e); }; - else table.onclick = function(e) { this.editablegrid.mouseClicked(e); }; + if (doubleclick) table.ondblclick = function (e) { this.editablegrid.mouseClicked(e); }; + else table.onclick = function (e) { this.editablegrid.mouseClicked(e); }; } // we must render a whole new table @@ -1702,12 +1633,12 @@ EditableGrid.prototype._rendergrid = function(containerid, className, tableid) // paginate if required if (pageSize > 0) { startRowIndex = _currentPageIndex * pageSize; - endRowIndex = Math.min(getRowCount(), startRowIndex + pageSize); + endRowIndex = Math.min(getRowCount(), startRowIndex + pageSize); } // create editablegrid table and add it to our container this.table = document.createElement("table"); - table.className = className || "editablegrid"; + table.className = className || "editablegrid"; if (typeof tableid != "undefined") table.id = tableid; while (_$(containerid).hasChildNodes()) _$(containerid).removeChild(_$(containerid).firstChild); _$(containerid).appendChild(table); @@ -1726,6 +1657,7 @@ EditableGrid.prototype._rendergrid = function(containerid, className, tableid) for (var c = 0; c < columnCount; c++) { var headerCell = document.createElement("TH"); var td = trHeader.appendChild(headerCell); + if (columns[c].hidden) { td.style.display = 'none'; } //new columns[c].headerRenderer._render(-1, c, td, columns[c].label); } @@ -1741,14 +1673,15 @@ EditableGrid.prototype._rendergrid = function(containerid, className, tableid) // create cell and render its content var td = tr.insertCell(j); - columns[j].cellRenderer._render(i, j, td, getValueAt(i,j)); + if (columns[j].hidden) { td.style.display = 'none'; } //new + columns[j].cellRenderer._render(i, j, td, getValueAt(i, j)); } } // attach handler on click or double click _$(containerid).editablegrid = this; - if (doubleclick) _$(containerid).ondblclick = function(e) { this.editablegrid.mouseClicked(e); }; - else _$(containerid).onclick = function(e) { this.editablegrid.mouseClicked(e); }; + if (doubleclick) _$(containerid).ondblclick = function (e) { this.editablegrid.mouseClicked(e); }; + else _$(containerid).onclick = function (e) { this.editablegrid.mouseClicked(e); }; } // callback @@ -1768,14 +1701,13 @@ EditableGrid.prototype._rendergrid = function(containerid, className, tableid) * @see EditableGrid#attachToHTMLTable * @see EditableGrid#loadXML */ -EditableGrid.prototype.renderGrid = function(containerid, className, tableid) -{ +EditableGrid.prototype.renderGrid = function (containerid, className, tableid) { // actually render grid this._rendergrid(containerid, className, tableid); // if client side: sort and filter if (!this.serverSide) { - this.sort() ; + this.sort(); this.filter(); } }; @@ -1785,8 +1717,7 @@ EditableGrid.prototype.renderGrid = function(containerid, className, tableid) * Refreshes the grid * @return */ -EditableGrid.prototype.refreshGrid = function() -{ +EditableGrid.prototype.refreshGrid = function () { if (this.currentContainerid != null) this.table = null; // if we are not in "attach mode", clear table to force a full re-render this._rendergrid(this.currentContainerid, this.currentClassName, this.currentTableid); }; @@ -1795,8 +1726,7 @@ EditableGrid.prototype.refreshGrid = function() * Render all column headers * @private */ -EditableGrid.prototype._renderHeaders = function() -{ +EditableGrid.prototype._renderHeaders = function () { with (this) { var rows = tHead.rows; for (var i = 0; i < 1 /*rows.length*/; i++) { @@ -1817,8 +1747,7 @@ EditableGrid.prototype._renderHeaders = function() * @param {Object} e * @private */ -EditableGrid.prototype.mouseClicked = function(e) -{ +EditableGrid.prototype.mouseClicked = function (e) { e = e || window.event; with (this) { @@ -1836,7 +1765,7 @@ EditableGrid.prototype.mouseClicked = function(e) var rowIndex = getRowIndex(target.parentNode); var columnIndex = target.cellIndex; - editCell(rowIndex, columnIndex); + editCell(rowIndex, columnIndex); } }; @@ -1846,8 +1775,7 @@ EditableGrid.prototype.mouseClicked = function(e) * @param columnIndex * @private */ -EditableGrid.prototype.editCell = function(rowIndex, columnIndex) -{ +EditableGrid.prototype.editCell = function (rowIndex, columnIndex) { var target = this.getCell(rowIndex, columnIndex); with (this) { @@ -1856,14 +1784,14 @@ EditableGrid.prototype.editCell = function(rowIndex, columnIndex) // if another row has been selected: callback if (rowIndex > -1) { - rowSelected(lastSelectedRowIndex, rowIndex); + rowSelected(lastSelectedRowIndex, rowIndex); lastSelectedRowIndex = rowIndex; } // edit current cell value if (!column.editable) { readonlyWarning(column); } else { - if (rowIndex < 0) { + if (rowIndex < 0) { if (column.headerEditor && isHeaderEditable(rowIndex, columnIndex)) column.headerEditor.edit(rowIndex, columnIndex, target, column.label); } @@ -1879,8 +1807,7 @@ EditableGrid.prototype.editCell = function(rowIndex, columnIndex) * @param {array[strings]} an array of class names of the headers * returns boolean based on success */ -EditableGrid.prototype.sortColumns = function(headerArray) -{ +EditableGrid.prototype.sortColumns = function (headerArray) { with (this) { newColumns = []; newColumnIndices = []; @@ -1923,19 +1850,18 @@ EditableGrid.prototype.sortColumns = function(headerArray) * @param {Object} columnIndexOrName index or name of the column * @param {Boolean} descending */ -EditableGrid.prototype.sort = function(columnIndexOrName, descending, backOnFirstPage) -{ +EditableGrid.prototype.sort = function (columnIndexOrName, descending, backOnFirstPage) { with (this) { - if (typeof columnIndexOrName == 'undefined' && sortedColumnName === -1) { + if (typeof columnIndexOrName == 'undefined' && sortedColumnName === -1) { // avoid a double render, but still send the expected callback tableSorted(-1, sortDescending); return true; } - if (typeof columnIndexOrName == 'undefined') columnIndexOrName = sortedColumnName; - if (typeof descending == 'undefined') descending = sortDescending; + if (typeof columnIndexOrName == 'undefined') columnIndexOrName = sortedColumnName; + if (typeof descending == 'undefined') descending = sortDescending; localset('sortColumnIndexOrName', columnIndexOrName); localset('sortDescending', descending); @@ -1958,7 +1884,7 @@ EditableGrid.prototype.sort = function(columnIndexOrName, descending, backOnFirs } // work on unfiltered data - var filterActive = dataUnfiltered != null; + var filterActive = dataUnfiltered != null; if (filterActive) data = dataUnfiltered; var type = columnIndex < 0 ? "" : getColumnType(columnIndex); @@ -1997,8 +1923,7 @@ EditableGrid.prototype.sort = function(columnIndexOrName, descending, backOnFirs * @param {String} filterString String string used to filter: all words must be found in the row * @param {Array} cols Columns to sort. If cols is not specified, the filter will be done on all columns */ -EditableGrid.prototype.filter = function(filterString, cols) -{ +EditableGrid.prototype.filter = function (filterString, cols) { with (this) { if (typeof filterString != 'undefined') { @@ -2019,7 +1944,7 @@ EditableGrid.prototype.filter = function(filterString, cols) tableFiltered(); } return; - } + } var words = currentFilter.toLowerCase().split(" "); @@ -2027,18 +1952,18 @@ EditableGrid.prototype.filter = function(filterString, cols) if (dataUnfiltered != null) data = dataUnfiltered; var rowCount = getRowCount(); - var columnCount = typeof cols != 'undefined' ? cols.length : getColumnCount(); + var columnCount = typeof cols != 'undefined' ? cols.length : getColumnCount(); for (var r = 0; r < rowCount; r++) { var row = data[r]; row.visible = true; - var rowContent = ""; + var rowContent = ""; // add column values for (var c = 0; c < columnCount; c++) { if (getColumnType(c) == 'boolean') continue; - var displayValue = getDisplayValueAt(r, typeof cols != 'undefined' ? cols[c] : c); - var value = getValueAt(r, typeof cols != 'undefined' ? cols[c] : c); + var displayValue = getDisplayValueAt(r, typeof cols != 'undefined' ? cols[c] : c); + var value = getValueAt(r, typeof cols != 'undefined' ? cols[c] : c); rowContent += displayValue + " " + (displayValue == value ? "" : value + " "); } @@ -2085,16 +2010,16 @@ EditableGrid.prototype.filter = function(filterString, cols) // a word ending with "!" means that a column must match this word exactly if (!word.endsWith("!")) { if (colindex >= 0) match = (getValueAt(r, colindex) + ' ' + getDisplayValueAt(r, colindex)).trim().toLowerCase().indexOf(word) >= 0; - else if (attributeName !== null) match = (''+getRowAttribute(r, attributeName)).trim().toLowerCase().indexOf(word) >= 0; - else match = rowContent.toLowerCase().indexOf(word) >= 0; + else if (attributeName !== null) match = ('' + getRowAttribute(r, attributeName)).trim().toLowerCase().indexOf(word) >= 0; + else match = rowContent.toLowerCase().indexOf(word) >= 0; } else { word = word.substr(0, word.length - 1); - if (colindex >= 0) match = (''+getDisplayValueAt(r, colindex)).trim().toLowerCase() == word || (''+getValueAt(r, colindex)).trim().toLowerCase() == word; - else if (attributeName !== null) match = (''+getRowAttribute(r, attributeName)).trim().toLowerCase() == word; + if (colindex >= 0) match = ('' + getDisplayValueAt(r, colindex)).trim().toLowerCase() == word || ('' + getValueAt(r, colindex)).trim().toLowerCase() == word; + else if (attributeName !== null) match = ('' + getRowAttribute(r, attributeName)).trim().toLowerCase() == word; else for (var c = 0; c < columnCount; c++) { - if (getColumnType(typeof cols != 'undefined' ? cols[c] : c) == 'boolean') continue; - if ((''+getDisplayValueAt(r, typeof cols != 'undefined' ? cols[c] : c)).trim().toLowerCase() == word || (''+getValueAt(r, typeof cols != 'undefined' ? cols[c] : c)).trim().toLowerCase() == word) match = true; + if (getColumnType(typeof cols != 'undefined' ? cols[c] : c) == 'boolean') continue; + if (('' + getDisplayValueAt(r, typeof cols != 'undefined' ? cols[c] : c)).trim().toLowerCase() == word || ('' + getValueAt(r, typeof cols != 'undefined' ? cols[c] : c)).trim().toLowerCase() == word) match = true; } } @@ -2122,8 +2047,7 @@ EditableGrid.prototype.filter = function(filterString, cols) * Sets the page size(pageSize of 0 means no pagination) * @param {Integer} pageSize Integer page size */ -EditableGrid.prototype.setPageSize = function(pageSize) -{ +EditableGrid.prototype.setPageSize = function (pageSize) { this.pageSize = parseInt(pageSize); if (isNaN(this.pageSize)) this.pageSize = 0; this.currentPageIndex = 0; @@ -2133,8 +2057,7 @@ EditableGrid.prototype.setPageSize = function(pageSize) /** * Returns the number of pages according to the current page size */ -EditableGrid.prototype.getPageCount = function() -{ +EditableGrid.prototype.getPageCount = function () { if (this.getRowCount() == 0) return 0; if (this.pageCount > 0) return this.pageCount; // server side pagination if (this.pageSize <= 0) return 1; // no client side pagination: one page @@ -2144,8 +2067,7 @@ EditableGrid.prototype.getPageCount = function() /** * Returns the number of pages according to the current page size */ -EditableGrid.prototype.getCurrentPageIndex = function() -{ +EditableGrid.prototype.getCurrentPageIndex = function () { // if pagination is handled on the server side, pageSize will (must) be 0 if (this.pageSize <= 0 && !this.serverSide) return 0; @@ -2157,8 +2079,7 @@ EditableGrid.prototype.getCurrentPageIndex = function() * Sets the current page (no effect if pageSize is 0) * @param {Integer} pageIndex Integer page index */ -EditableGrid.prototype.setPageIndex = function(pageIndex) -{ +EditableGrid.prototype.setPageIndex = function (pageIndex) { this.currentPageIndex = pageIndex; this.localset('pageIndex', pageIndex); this.refreshGrid(); @@ -2168,8 +2089,7 @@ EditableGrid.prototype.setPageIndex = function(pageIndex) * Go the previous page if we are not already on the first page * @return */ -EditableGrid.prototype.prevPage = function() -{ +EditableGrid.prototype.prevPage = function () { if (this.canGoBack()) this.setPageIndex(this.getCurrentPageIndex() - 1); }; @@ -2177,8 +2097,7 @@ EditableGrid.prototype.prevPage = function() * Go the first page if we are not already on the first page * @return */ -EditableGrid.prototype.firstPage = function() -{ +EditableGrid.prototype.firstPage = function () { if (this.canGoBack()) this.setPageIndex(0); }; @@ -2186,8 +2105,7 @@ EditableGrid.prototype.firstPage = function() * Go the next page if we are not already on the last page * @return */ -EditableGrid.prototype.nextPage = function() -{ +EditableGrid.prototype.nextPage = function () { if (this.canGoForward()) this.setPageIndex(this.getCurrentPageIndex() + 1); }; @@ -2195,8 +2113,7 @@ EditableGrid.prototype.nextPage = function() * Go the last page if we are not already on the last page * @return */ -EditableGrid.prototype.lastPage = function() -{ +EditableGrid.prototype.lastPage = function () { if (this.canGoForward()) this.setPageIndex(this.getPageCount() - 1); }; @@ -2204,8 +2121,7 @@ EditableGrid.prototype.lastPage = function() * Returns true if we are not already on the first page * @return */ -EditableGrid.prototype.canGoBack = function() -{ +EditableGrid.prototype.canGoBack = function () { return this.getCurrentPageIndex() > 0; }; @@ -2213,8 +2129,7 @@ EditableGrid.prototype.canGoBack = function() * Returns true if we are not already on the last page * @return */ -EditableGrid.prototype.canGoForward = function() -{ +EditableGrid.prototype.canGoForward = function () { return this.getCurrentPageIndex() < this.getPageCount() - 1; }; @@ -2225,14 +2140,13 @@ EditableGrid.prototype.canGoForward = function() * @param slidingWindowSize size of the visible window * @return */ -EditableGrid.prototype.getSlidingPageInterval = function(slidingWindowSize) -{ +EditableGrid.prototype.getSlidingPageInterval = function (slidingWindowSize) { var nbPages = this.getPageCount(); if (nbPages <= 1) return null; var curPageIndex = this.getCurrentPageIndex(); - var startPageIndex = Math.max(0, curPageIndex - Math.floor(slidingWindowSize/2)); - var endPageIndex = Math.min(nbPages - 1, curPageIndex + Math.floor(slidingWindowSize/2)); + var startPageIndex = Math.max(0, curPageIndex - Math.floor(slidingWindowSize / 2)); + var endPageIndex = Math.min(nbPages - 1, curPageIndex + Math.floor(slidingWindowSize / 2)); if (endPageIndex - startPageIndex < slidingWindowSize) { var diff = slidingWindowSize - (endPageIndex - startPageIndex + 1); @@ -2257,8 +2171,7 @@ EditableGrid.prototype.getSlidingPageInterval = function(slidingWindowSize) * * @return */ -EditableGrid.prototype.getPagesInInterval = function(interval, callback) -{ +EditableGrid.prototype.getPagesInInterval = function (interval, callback) { var pages = []; for (var p = interval.startPageIndex; p <= interval.endPageIndex; p++) { pages.push(typeof callback == 'function' ? callback(p, p == this.getCurrentPageIndex()) : p); diff --git a/editablegrid_renderers.js b/editablegrid_renderers.js index b2eadda..ba47574 100644 --- a/editablegrid_renderers.js +++ b/editablegrid_renderers.js @@ -33,9 +33,14 @@ CellRenderer.prototype._render = function(rowIndex, columnIndex, element, value) // apply a css class corresponding to the column name EditableGrid.prototype.addClassName(element, "editablegrid-" + this.column.name); + + // apply a css class corresponding to the cell alignment + if( this.column.vertical_alignment == 'top') EditableGrid.prototype.addClassName(element, "vertical-align-top"); + if( this.column.vertical_alignment == 'center') EditableGrid.prototype.addClassName(element, "vertical-align-center"); + if( this.column.vertical_alignment == 'bottom') EditableGrid.prototype.addClassName(element, "vertical-align-bottom"); // add a data-title attribute used for responsiveness - element.setAttribute('data-title', this.column.label); + element.setAttribute('data-title', this.column.label); // call the specialized render method return this.render(element, typeof value == 'string' && this.column.datatype != "html" ? (value === null ? null : htmlspecialchars(value, 'ENT_NOQUOTES').replace(/ /g, '  ')) : value);