diff --git a/etemplate/inc/class.etemplate_widget_nextmatch.inc.php b/etemplate/inc/class.etemplate_widget_nextmatch.inc.php index c99c5324a0..950869b63b 100644 --- a/etemplate/inc/class.etemplate_widget_nextmatch.inc.php +++ b/etemplate/inc/class.etemplate_widget_nextmatch.inc.php @@ -559,5 +559,43 @@ class etemplate_widget_nextmatch extends etemplate_widget } return $cat_actions; } + + /** + * Validate input + * + * Following attributes get checked: + * - needed: value must NOT be empty + * - min, max: int and float widget only + * - maxlength: maximum length of string (longer strings get truncated to allowed size) + * - preg: perl regular expression incl. delimiters (set by default for int, float and colorpicker) + * - int and float get casted to their type + * + * @param string $cname current namespace + * @param array $content + * @param array &$validated=array() validated content + */ + public function validate($cname, array $content, &$validated=array()) + { + $form_name = self::form_name($cname, $this->id); + $value = self::get_array($content, $form_name); +error_log("nextmatch value: " . array2string($value)); + + // Save current column settings as default (admins only) + if($value['as_default']) + { + unset($value['as_default']); + if($GLOBALS['egw_info']['user']['apps']['admin']) + { + list($app) = explode('.',$this->template); + $pref_name = 'nextmatch-' . (isset($this->columnselection_pref) ? $this->columnselection_pref : $this->template); + // Columns already saved to user's preferences + $cols = $GLOBALS['egw']->preferences->read(); + $cols = $cols[$pref_name]; + $GLOBALS['egw']->preferences->add($app,$pref_name,is_array($cols) ? implode(',',$cols) : $cols,'default'); + $GLOBALS['egw']->preferences->save_repository(false,'default'); + } + } + $validated = $value; + } } diff --git a/etemplate/js/et2_dataview_view_gridContainer.js b/etemplate/js/et2_dataview_view_gridContainer.js index 23527a1259..daa6882e2e 100644 --- a/etemplate/js/et2_dataview_view_gridContainer.js +++ b/etemplate/js/et2_dataview_view_gridContainer.js @@ -43,6 +43,8 @@ var et2_dataview_gridContainer = Class.extend({ * Hooks to allow parent to keep up to date if things change */ onUpdateColumns: false, + selectColumnsClick: false, + /** * Constructor for the grid container @@ -179,8 +181,10 @@ var et2_dataview_gridContainer = Class.extend({ /** * Recalculates the stylesheets which determine the column visibility and * width. + * + * @param setDefault boolean Allow admins to save current settings as default for all users */ - updateColumns: function() { + updateColumns: function(setDefault) { if (this.columnMgr) { this._updateColumns(); @@ -189,7 +193,7 @@ var et2_dataview_gridContainer = Class.extend({ // Ability to notify parent / someone else if (this.onUpdateColumns) { - this.onUpdateColumns(); + this.onUpdateColumns(setDefault); } }, @@ -396,71 +400,15 @@ var et2_dataview_gridContainer = Class.extend({ // Build the "select columns" icon this.selectColIcon = $j(document.createElement("span")) .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")) .addClass("optcol") .append(this.selectColIcon) + // Toggle display of option popup + .click(this, function(e) {if(e.data.selectColumnsClick) e.data.selectColumnsClick(e)}) .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 07119d8f6c..34be96540e 100644 --- a/etemplate/js/et2_extension_nextmatch.js +++ b/etemplate/js/et2_extension_nextmatch.js @@ -349,8 +349,10 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, { /** * Take current column display settings and store them in egw.preferences * for next time + * + * @param setDefault boolean From checkbox, for admins to set default settings */ - _updateUserPreferences: function() { + _updateUserPreferences: function(setDefault) { var colMgr = this.dataviewContainer.getColumnMgr() if(!this.options.settings.columnselection_pref) { this.options.settings.columnselection_pref = this.options.template; @@ -383,6 +385,13 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, { // Save adjusted column sizes egw.set_preference(app, "nextmatch-"+this.options.settings.columnselection_pref+"-size", colSize); + // Save as default, if set + if(setDefault) + { + this.getInstanceManager().submit(); + return false; + } + // Update query value, so data source can use visible columns to exclude expensive sub-queries var oldCols = this.activeFilters.selectcols ? this.activeFilters.selectcols : []; this.activeFilters.selectcols = colDisplay; @@ -432,9 +441,12 @@ 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();}; + // Register handler to update preferences when column properties are changed + this.dataviewContainer.onUpdateColumns = function(setDefault) { self._updateUserPreferences(setDefault);}; + + // Register handler for column selection popup + this.dataviewContainer.selectColumnsClick = function(event) { self._selectColumnsClick(event);}; }, _parseDataRow: function(_row, _colData) { @@ -473,6 +485,93 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, { } }, + _selectColumnsClick: function(e) { + if(!this.selectPopup) + { + // Build the popup + var self = this; + var columnMgr = this.dataviewContainer.columnMgr; + var columns = {}; + var columns_selected = []; + for (var i = 0; i < columnMgr.columns.length; i++) + { + var col = 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}, this); + select.set_select_options(columns); + select.set_value(columns_selected); + + var defaultCheck = et2_createWidget("checkbox", {}, this); + defaultCheck.set_id('as_default'); + defaultCheck.set_label(egw.lang("As default")); + + var okButton = et2_createWidget("buttononly", {}, this); + okButton.set_label(egw.lang("ok")); + okButton.onclick = function() { + // Update visibility + var visibility = {}; + for (var i = 0; i < columnMgr.columns.length; i++) + { + var col = 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; + } + columnMgr.setColumnVisibilitySet(visibility); + self.selectPopup.toggle(); + + self.dataviewContainer.updateColumns(); + + // Set default? + if(defaultCheck.get_value() == "true") + { + self.getInstanceManager().submit(); + } + }; + + var cancelButton = et2_createWidget("buttononly", {}, this); + cancelButton.set_label(egw.lang("cancel")); + cancelButton.onclick = function() { + self.selectPopup.toggle(); + } + + this.selectPopup = jQuery(document.createElement("fieldset")) + .addClass("colselection ui-dialog") + .append(""+egw.lang("Select columns")+"") + .append(select.getDOMNode()) + .append(okButton.getDOMNode()) + .append(cancelButton.getDOMNode()) + .appendTo(this.div); + + // Add default checkbox for admins + var apps = egw.user('apps'); + if(apps['admin']) + { + this.selectPopup.append(defaultCheck.getDOMNode()) + } + } + else + { + this.selectPopup.toggle(); + } + var t_position = jQuery(e.target).position(); + var s_position = this.div.position(); + this.selectPopup.css("top", t_position.top) + .css("left", s_position.left + this.div.width() - this.selectPopup.width()); + }, + /** * When the template attribute is set, the nextmatch widget tries to load * that template and to fetch the grid which is inside of it. It then calls @@ -735,6 +834,7 @@ var et2_nextmatch_header_bar = Class.extend(et2_INextmatchHeader, { } }, + /** * Build the selectbox filters in the header bar * Sets value, options, labels, and change handlers