forked from extern/egroupware
Pretty checkboxed multi-select widget
This commit is contained in:
parent
ea77d9704e
commit
3a865977ff
@ -220,6 +220,7 @@ var et2_customfields_list = et2_baseWidget.extend([et2_IDetachedDOM], {
|
|||||||
if(!this.options.customfields) return;
|
if(!this.options.customfields) return;
|
||||||
for(var field_name in this.options.customfields)
|
for(var field_name in this.options.customfields)
|
||||||
{
|
{
|
||||||
|
// Make sure widget is created, and has the needed function
|
||||||
if(!this.widgets[field_name] || !this.widgets[field_name].set_value) continue;
|
if(!this.widgets[field_name] || !this.widgets[field_name].set_value) continue;
|
||||||
var value = _value[this.prefix + field_name] ? _value[this.prefix + field_name] : null;
|
var value = _value[this.prefix + field_name] ? _value[this.prefix + field_name] : null;
|
||||||
this.widgets[field_name].set_value(value);
|
this.widgets[field_name].set_value(value);
|
||||||
|
@ -561,7 +561,12 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, {
|
|||||||
// Build the popup
|
// Build the popup
|
||||||
if(!this.selectPopup)
|
if(!this.selectPopup)
|
||||||
{
|
{
|
||||||
var select = et2_createWidget("select", {multiple: true, rows: 8}, this);
|
var select = et2_createWidget("select", {
|
||||||
|
multiple: true,
|
||||||
|
rows: 8,
|
||||||
|
empty_label:this.egw().lang("select columns"),
|
||||||
|
selected_first: false
|
||||||
|
}, this);
|
||||||
select.set_select_options(columns);
|
select.set_select_options(columns);
|
||||||
select.set_value(columns_selected);
|
select.set_value(columns_selected);
|
||||||
|
|
||||||
@ -629,9 +634,8 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, {
|
|||||||
self.selectPopup.toggle();
|
self.selectPopup.toggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.selectPopup = jQuery(document.createElement("fieldset"))
|
this.selectPopup = jQuery(document.createElement("div"))
|
||||||
.addClass("colselection ui-dialog")
|
.addClass("colselection ui-dialog ui-widget-content")
|
||||||
.append("<legend>"+this.egw().lang("Select columns")+"</legend>")
|
|
||||||
.append(select.getDOMNode())
|
.append(select.getDOMNode())
|
||||||
.append(okButton.getDOMNode())
|
.append(okButton.getDOMNode())
|
||||||
.append(cancelButton.getDOMNode())
|
.append(cancelButton.getDOMNode())
|
||||||
|
@ -46,6 +46,12 @@ var et2_selectbox = et2_inputWidget.extend({
|
|||||||
"name": "Select options",
|
"name": "Select options",
|
||||||
"default": {},
|
"default": {},
|
||||||
"description": "Internaly used to hold the select options."
|
"description": "Internaly used to hold the select options."
|
||||||
|
},
|
||||||
|
"selected_first": {
|
||||||
|
"name": "Selected options first",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true,
|
||||||
|
"description": "For multi-selects, put the selected options at the top of the list when first loaded"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -54,16 +60,34 @@ var et2_selectbox = et2_inputWidget.extend({
|
|||||||
init: function() {
|
init: function() {
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
|
this.input = null;
|
||||||
|
|
||||||
// Allow no other widgets inside this one
|
// Allow no other widgets inside this one
|
||||||
this.supportedWidgetClasses = [];
|
this.supportedWidgetClasses = [];
|
||||||
|
|
||||||
// Legacy options could have row count or empty label in first slot
|
// Legacy options could have row count or empty label in first slot
|
||||||
if(typeof this.options.rows == "string" && isNaN(this.options.rows)) {
|
if(typeof this.options.rows == "string")
|
||||||
|
{
|
||||||
|
if(isNaN(this.options.rows))
|
||||||
|
{
|
||||||
this.options.empty_label = this.egw().lang(this.options.rows);
|
this.options.empty_label = this.egw().lang(this.options.rows);
|
||||||
this.options.rows = 1;
|
this.options.rows = 1;
|
||||||
}
|
}
|
||||||
if(this.options.rows > 1) this.options.multiple = true;
|
else
|
||||||
|
{
|
||||||
|
this.options.rows = parseInt(this.options.rows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.options.rows > 1)
|
||||||
|
{
|
||||||
|
this.options.multiple = true;
|
||||||
|
this.createMultiSelect();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
this.createInputWidget();
|
this.createInputWidget();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
@ -117,11 +141,19 @@ var et2_selectbox = et2_inputWidget.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an option to regular drop-down select
|
||||||
|
*/
|
||||||
_appendOptionElement: function(_value, _label, _title) {
|
_appendOptionElement: function(_value, _label, _title) {
|
||||||
if(_value == "" && (_label == null || _label == "")) {
|
if(_value == "" && (_label == null || _label == "")) {
|
||||||
_label = this.options.empty_label;
|
_label = this.options.empty_label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.input == null)
|
||||||
|
{
|
||||||
|
return this._appendMultiOption(_value, _label, _title);
|
||||||
|
}
|
||||||
|
|
||||||
var option = $j(document.createElement("option"))
|
var option = $j(document.createElement("option"))
|
||||||
.attr("value", _value)
|
.attr("value", _value)
|
||||||
.text(_label+"");
|
.text(_label+"");
|
||||||
@ -133,6 +165,61 @@ var et2_selectbox = et2_inputWidget.extend({
|
|||||||
option.appendTo(this.input);
|
option.appendTo(this.input);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a value to multi-select
|
||||||
|
*/
|
||||||
|
_appendMultiOption: function(_value, _label, _title) {
|
||||||
|
var option_data = null;
|
||||||
|
if(typeof _label == "object")
|
||||||
|
{
|
||||||
|
option_data = _label;
|
||||||
|
_label = option_data.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Already in header
|
||||||
|
if(_label == this.options.empty_label) return;
|
||||||
|
|
||||||
|
var opt_id = this.id + "_opt_" + _value;
|
||||||
|
var label = jQuery(document.createElement("label"))
|
||||||
|
.attr("for", opt_id)
|
||||||
|
.hover(
|
||||||
|
function() {jQuery(this).addClass("ui-state-hover")},
|
||||||
|
function() {jQuery(this).removeClass("ui-state-hover")}
|
||||||
|
);
|
||||||
|
var option = jQuery(document.createElement("input"))
|
||||||
|
.attr("type", "checkbox")
|
||||||
|
.attr("id",opt_id)
|
||||||
|
.attr("value", _value)
|
||||||
|
.appendTo(label);
|
||||||
|
if(typeof _title !== "undefined")
|
||||||
|
{
|
||||||
|
option.attr("title",_title);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some special stuff for categories
|
||||||
|
if(option_data)
|
||||||
|
{
|
||||||
|
if(option_data.data.icon)
|
||||||
|
{
|
||||||
|
var img = this.egw().image(option_data.data.icon);
|
||||||
|
jQuery(document.createElement("img"))
|
||||||
|
.attr("src", img)
|
||||||
|
.appendTo(label);
|
||||||
|
}
|
||||||
|
if(option_data.data.color)
|
||||||
|
{
|
||||||
|
label.css("background-color",option_data.data.color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label.append(jQuery("<span>"+_label+"</span>"))
|
||||||
|
var li = jQuery(document.createElement("li")).append(label);
|
||||||
|
|
||||||
|
li.appendTo(this.multiOptions);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a regular drop-down select box
|
||||||
|
*/
|
||||||
createInputWidget: function() {
|
createInputWidget: function() {
|
||||||
// Create the base input widget
|
// Create the base input widget
|
||||||
this.input = $j(document.createElement("select"))
|
this.input = $j(document.createElement("select"))
|
||||||
@ -155,6 +242,73 @@ var et2_selectbox = et2_inputWidget.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a list of checkboxes
|
||||||
|
*/
|
||||||
|
createMultiSelect: function() {
|
||||||
|
var node = jQuery(document.createElement("div"))
|
||||||
|
.addClass("et2_selectbox");
|
||||||
|
|
||||||
|
var header = jQuery(document.createElement("div"))
|
||||||
|
.addClass("ui-widget-header ui-helper-clearfix")
|
||||||
|
.appendTo(node);
|
||||||
|
|
||||||
|
if(this.options.empty_label)
|
||||||
|
{
|
||||||
|
jQuery(document.createElement("span"))
|
||||||
|
.text(this.options.empty_label)
|
||||||
|
.addClass("ui-multiselect-header")
|
||||||
|
.appendTo(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up for options to be added later
|
||||||
|
var options = this.multiOptions = jQuery(document.createElement("ul"));
|
||||||
|
this.multiOptions.addClass("ui-multiselect-checkboxes ui-helper-reset")
|
||||||
|
.css("height", 1.9*this.options.rows + "em")
|
||||||
|
.appendTo(node);
|
||||||
|
|
||||||
|
if(this.options.rows >= 5)
|
||||||
|
{
|
||||||
|
// Check / uncheck all
|
||||||
|
var header_controls = {
|
||||||
|
check: {
|
||||||
|
icon_class: 'ui-icon-check',
|
||||||
|
label: 'Check all',
|
||||||
|
click: function(e) {
|
||||||
|
jQuery("input",e.data).attr("checked", true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uncheck: {
|
||||||
|
icon_class: 'ui-icon-closethick',
|
||||||
|
label: 'Uncheck all',
|
||||||
|
click: function(e) {
|
||||||
|
jQuery("input",e.data).attr("checked", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var controls = jQuery(document.createElement("ul"))
|
||||||
|
.addClass('ui-helper-reset')
|
||||||
|
.appendTo(header);
|
||||||
|
for(var key in header_controls)
|
||||||
|
{
|
||||||
|
jQuery(document.createElement("li"))
|
||||||
|
.addClass("et2_clickable")
|
||||||
|
.click(options, header_controls[key].click)
|
||||||
|
.append('<span class="ui-icon ' + header_controls[key].icon_class + '"/>')
|
||||||
|
.append("<span>"+this.egw().lang(header_controls[key].label)+"</span>")
|
||||||
|
.appendTo(controls);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (header[0].childNodes.length == 0)
|
||||||
|
{
|
||||||
|
// Hide header - nothing there but padding
|
||||||
|
header.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setDOMNode(node[0]);
|
||||||
|
},
|
||||||
|
|
||||||
loadFromXML: function(_node) {
|
loadFromXML: function(_node) {
|
||||||
// Read the option-tags
|
// Read the option-tags
|
||||||
var options = et2_directChildrenByTagName(_node, "options");
|
var options = et2_directChildrenByTagName(_node, "options");
|
||||||
@ -169,6 +323,14 @@ var et2_selectbox = et2_inputWidget.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
set_value: function(_value) {
|
set_value: function(_value) {
|
||||||
|
if(typeof _value == "string" && _value.match(/[,0-9]+$/) !== null)
|
||||||
|
{
|
||||||
|
_value = _value.split(',');
|
||||||
|
}
|
||||||
|
if(this.input == null)
|
||||||
|
{
|
||||||
|
return this.set_multi_value(_value);
|
||||||
|
}
|
||||||
jQuery("option",this.input).attr("selected", false);
|
jQuery("option",this.input).attr("selected", false);
|
||||||
this.value = _value;
|
this.value = _value;
|
||||||
if(typeof _value == "array")
|
if(typeof _value == "array")
|
||||||
@ -190,11 +352,41 @@ var et2_selectbox = et2_inputWidget.extend({
|
|||||||
if(jQuery("option[value='"+_value+"']", this.input).attr("selected", true).length == 0)
|
if(jQuery("option[value='"+_value+"']", this.input).attr("selected", true).length == 0)
|
||||||
{
|
{
|
||||||
this.egw().debug("warning", "Tried to set value that isn't an option", this, _value);
|
this.egw().debug("warning", "Tried to set value that isn't an option", this, _value);
|
||||||
//console.trace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
set_multi_value: function(_value) {
|
||||||
|
jQuery("input",this.multiOptions).attr("checked", false);
|
||||||
|
if(typeof _value == "array")
|
||||||
|
{
|
||||||
|
for(var i = 0; i < _value.length; i++)
|
||||||
|
{
|
||||||
|
jQuery("input[value='"+_value[i]+"']", this.multiOptions).attr("checked", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (typeof _value == "object")
|
||||||
|
{
|
||||||
|
for(var i in _value)
|
||||||
|
{
|
||||||
|
jQuery("input[value='"+_value[i]+"']", this.multiOptions).attr("checked", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(jQuery("input[value='"+_value+"']", this.multiOptions).attr("checked", true).length == 0)
|
||||||
|
{
|
||||||
|
this.egw().debug("warning", "Tried to set value that isn't an option", this, _value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort selected to the top
|
||||||
|
if(this.selected_first)
|
||||||
|
{
|
||||||
|
this.multiOptions.find("li:has(input:checked)").prependTo(this.multiOptions);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The set_select_options function is added, as the select options have to be
|
* The set_select_options function is added, as the select options have to be
|
||||||
* added after the "option"-widgets were added to selectbox.
|
* added after the "option"-widgets were added to selectbox.
|
||||||
@ -219,11 +411,20 @@ var et2_selectbox = et2_inputWidget.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (typeof _options[key] === 'object')
|
if (typeof _options[key] === 'object')
|
||||||
|
{
|
||||||
|
if(this.input == null)
|
||||||
|
{
|
||||||
|
// Allow some special extras for objects by passing the whole thing
|
||||||
|
_options[key]["label"] = _options[key]["label"] ? _options[key]["label"] : "";
|
||||||
|
this._appendMultiOption(key, _options[key], _options[key]["title"]);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
this._appendOptionElement(key,
|
this._appendOptionElement(key,
|
||||||
_options[key]["label"] ? _options[key]["label"] : "",
|
_options[key]["label"] ? _options[key]["label"] : "",
|
||||||
_options[key]["title"] ? _options[key]["title"] : "");
|
_options[key]["title"] ? _options[key]["title"] : "");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this._appendOptionElement(key, _options[key]);
|
this._appendOptionElement(key, _options[key]);
|
||||||
@ -231,6 +432,19 @@ var et2_selectbox = et2_inputWidget.extend({
|
|||||||
}
|
}
|
||||||
// Sometimes value gets set before options
|
// Sometimes value gets set before options
|
||||||
if(this.value) this.set_value(this.value);
|
if(this.value) this.set_value(this.value);
|
||||||
|
},
|
||||||
|
|
||||||
|
getValue: function() {
|
||||||
|
if(this.input == null)
|
||||||
|
{
|
||||||
|
var value = [];
|
||||||
|
jQuery("input:checked",this.multiOptions).each(function(){value.push(this.value);});
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return this._super.apply(this, arguments);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -174,6 +174,54 @@ button.et2_button_text:focus {
|
|||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multi-select widget
|
||||||
|
*/
|
||||||
|
.et2_selectbox .ui-widget-header {
|
||||||
|
padding: 2px 6px 0px 6px;
|
||||||
|
}
|
||||||
|
.et2_selectbox .ui-widget-header ul {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.et2_selectbox .ui-widget-header li {
|
||||||
|
float: left;
|
||||||
|
padding: 2px;
|
||||||
|
padding-top: 0px
|
||||||
|
}
|
||||||
|
.et2_selectbox .ui-widget-header li span.ui-icon {
|
||||||
|
float: left;
|
||||||
|
margin-top: -2px;
|
||||||
|
}
|
||||||
|
.et2_selectbox .ui-multiselect-checkboxes {
|
||||||
|
overflow-y: scroll;
|
||||||
|
position: relative;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.et2_selectbox .ui-multiselect-checkboxes li {
|
||||||
|
margin: 0px;
|
||||||
|
clear: both;
|
||||||
|
padding-left: 26px;
|
||||||
|
padding-right: 3px;
|
||||||
|
text-decoration: none;
|
||||||
|
list-style-image: none;
|
||||||
|
list-style-type: none;
|
||||||
|
text-indent: -26px;
|
||||||
|
}
|
||||||
|
.et2_selectbox .ui-multiselect-checkboxes label {
|
||||||
|
display: block;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
.et2_selectbox input[type="checkbox"] {
|
||||||
|
margin: 3px;
|
||||||
|
}
|
||||||
|
.et2_selectbox .ui-multiselect-checkboxes img {
|
||||||
|
float: right;
|
||||||
|
height: 1.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date / Time widgets
|
||||||
|
*/
|
||||||
span.et2_date {
|
span.et2_date {
|
||||||
min-width: 130px;
|
min-width: 130px;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user