From c956d6571babda6022802cc667b2fd63a9763f26 Mon Sep 17 00:00:00 2001 From: Nathan Gray Date: Thu, 29 Sep 2011 19:35:20 +0000 Subject: [PATCH] Column selection using default or preference --- .../js/et2_dataview_view_gridContainer.js | 71 +++++++++++++- etemplate/js/et2_extension_nextmatch.js | 97 ++++++++++++++++++- 2 files changed, 166 insertions(+), 2 deletions(-) diff --git a/etemplate/js/et2_dataview_view_gridContainer.js b/etemplate/js/et2_dataview_view_gridContainer.js index 5d2aef7b0a..5b2c8fa4a5 100644 --- a/etemplate/js/et2_dataview_view_gridContainer.js +++ b/etemplate/js/et2_dataview_view_gridContainer.js @@ -38,6 +38,11 @@ var et2_dataview_gridContainer = Class.extend({ headerBorderWidth: false, columnBorderWidth: false, + /** + * Hooks to allow parent to keep up to date if things change + */ + onUpdateColumns: false, + /** * Constructor for the grid container * @param object _parentNode is the DOM-Node into which the grid view will be inserted @@ -179,6 +184,12 @@ var et2_dataview_gridContainer = Class.extend({ { this._updateColumns(); } + + // Ability to notify parent / someone else + if (this.onUpdateColumns) + { + this.onUpdateColumns(); + } }, @@ -369,7 +380,9 @@ var et2_dataview_gridContainer = Class.extend({ _buildSelectCol: function() { // Build the "select columns" icon this.selectColIcon = $j(document.createElement("span")) - .addClass("selectcols"); + .addClass("selectcols") + // Toggle display of option popup + .click(this, function(e) {e.data.selectPopup.toggle();}); // Build the option column this.selectCol = $j(document.createElement("th")) @@ -377,6 +390,62 @@ var et2_dataview_gridContainer = Class.extend({ .append(this.selectColIcon) .appendTo(this.headTr); + // Build the popup + var self = this; + var columns = {}; + var columns_selected = []; + for (var i = 0; i < this.columnMgr.columns.length; i++) + { + var col = this.columnMgr.columns[i]; + if(col.caption && col.visibility != ET2_COL_VISIBILITY_ALWAYS_NOSELECT) + { + columns[col.id] = col.caption; + if(col.visibility == ET2_COL_VISIBILITY_VISIBLE) columns_selected.push(col.id); + } + } + + var select = et2_createWidget("select", {multiple: true, rows: 8}); + select.set_select_options(columns); + select.set_value(columns_selected); + + var okButton = et2_createWidget("buttononly", {label: egw.lang("ok")}); + okButton.set_label(egw.lang("ok")); + okButton.onclick = function() { + // Update visibility + var visibility = {}; + for (var i = 0; i < self.columnMgr.columns.length; i++) + { + var col = self.columnMgr.columns[i]; + if(col.caption && col.visibility != ET2_COL_VISIBILITY_ALWAYS_NOSELECT ) + { + visibility[col.id] = {visible: false}; + } + } + var value = select.getValue(); + for(var i = 0; i < value.length; i++) + { + visibility[value[i]].visible = true; + } + self.columnMgr.setColumnVisibilitySet(visibility); + self.selectPopup.toggle(); + self.updateColumns(); + }; + + var cancelButton = et2_createWidget("buttononly"); + cancelButton.set_label(egw.lang("cancel")); + cancelButton.onclick = function() { + self.selectPopup.toggle(); + } + + var popup = this.selectPopup = $j(document.createElement("fieldset")) + .addClass("colselection") + .css("display", "none") + .append(""+egw.lang("Select columns")+"") + .append(select.getDOMNode()) + .append(okButton.getDOMNode()) + .append(cancelButton.getDOMNode()) + .appendTo(this.selectCol); + this.selectCol.css("width", this.scrollbarWidth - this.selectCol.outerWidth() + this.selectCol.width() + 1); }, diff --git a/etemplate/js/et2_extension_nextmatch.js b/etemplate/js/et2_extension_nextmatch.js index d4b5fc3f09..9d2cdb539a 100644 --- a/etemplate/js/et2_extension_nextmatch.js +++ b/etemplate/js/et2_extension_nextmatch.js @@ -255,7 +255,7 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, { }, /** - * Generates the column name for the given column widget + * Generates the column caption for the given column widget */ _genColumnCaption: function(_widget) { var result = null; @@ -274,7 +274,98 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, { return result; }, + /** + * Generates the column name (internal) for the given column widget + * Used in preferences to refer to the columns by name instead of position + * + * See _getColumnCaption() for human fiendly captions + */ + _getColumnName: function(_widget) { + var name = _widget.id; + var child_names = []; + var children = _widget.getChildren(); + for(var i = 0; i < children.length; i++) { + if(children[i].id) child_names.push(children[i].id); + } + return name + (name != "" && child_names.length > 0 ? "_" : "") + child_names.join("_"); + }, + + + /** + * Apply stored user preferences to discovered columns + */ + _applyUserPreferences: function(_row, _colData) { + // Read preference or default for column visibility + var negated = this.options.settings.default_cols[0] == "!"; + var columnPreference = negated ? this.options.settings.default_cols.substring(1) : this.options.settings.default_cols; + if(this.options.settings.columnselection_pref) { + var list = et2_csvSplit(this.options.settings.columnselection_pref, 2, "."); + // 'nextmatch-' prefix is there in preference name, but not in setting, so add it in + var pref = egw.preference("nextmatch-"+this.options.settings.columnselection_pref, list[0]); + if(pref) + { + negated = (pref[0] == "!"); + columnPreference = negated ? pref.substring(1) : pref; + } + } + var columnDisplay = et2_csvSplit(columnPreference,null,","); + + // Add in display preferences + if(columnDisplay && columnDisplay.length > 0) + { + RowLoop: + for(var i = 0; i < _row.length; i++) + { + var colName = this._getColumnName(_row[i].widget); + if(!colName) continue; + _colData[i].preferenceName = colName; + for(var j = 0; j < columnDisplay.length; j++) { + if(columnDisplay[j] == colName) + { + _colData[i].disabled = negated; + continue RowLoop; + } + } + _colData[i].disabled = !negated; + } + } + // TODO: Adjusted column sizes + }, + + /** + * Take current column display settings and store them in egw.preferences + * for next time + */ + _updateUserPreferences: function() { + var colMgr = this.dataviewContainer.getColumnMgr() + if(this.options.settings.columnselection_pref) { + var visibility = colMgr.getColumnVisibilitySet(); + var colDisplay = []; + var colSize = []; + + // visibility is indexed by internal ID, widget is referenced by position, preference needs name + for(var i = 0; i < colMgr.columns.length; i++) + { + var widget = this.columns[i].widget; + var colName = this._getColumnName(widget); + if(visibility[colMgr.columns[i].id].visible) colDisplay.push(colName); + } + + var list = et2_csvSplit(this.options.settings.columnselection_pref, 2, "."); + var app = list[0]; + + // Save visible columns + // 'nextmatch-' prefix is there in preference name, but not in setting, so add it in + egw.set_preference(app, "nextmatch-"+this.options.settings.columnselection_pref, colDisplay.join(",")); + + // TODO: Save adjusted column sizes + } + }, + _parseHeaderRow: function(_row, _colData) { + // Get column display preference + this._applyUserPreferences(_row, _colData); + // Go over the header row and create the column entries this.columns = new Array(_row.length); var columnData = new Array(_row.length); @@ -284,6 +375,7 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, { "widget": _row[x].widget }; + columnData[x] = { "id": "col_" + x, "caption": this._genColumnCaption(_row[x].widget), @@ -299,6 +391,9 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, { // Create the column manager and update the grid container this.dataviewContainer.setColumns(columnData); + // Register handler to update preferences when column properties are changed + var self = this; + this.dataviewContainer.onUpdateColumns = function() { self._updateUserPreferences();}; }, _parseDataRow: function(_row, _colData) {