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("")
- .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("")
+ .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