Improve UI of multi-row selectbox

- Only check button, no x (check toggles all/none), aligned with checkboxes
- Header with buttons hides when not hovering over checkbox, saving space
- Account select now has quick-select in header
This commit is contained in:
Nathan Gray 2013-06-05 22:45:19 +00:00
parent d25d2d1b98
commit 6852d0807d
3 changed files with 80 additions and 23 deletions

View File

@ -71,19 +71,31 @@ var et2_selectAccount = et2_selectbox.extend(
this.egw().debug("warn", "Invalid account_type: %s Valid options:",_attrs['account_type'], this.account_types); this.egw().debug("warn", "Invalid account_type: %s Valid options:",_attrs['account_type'], this.account_types);
} }
this._super.apply(this, arguments);
// Holder for search jQuery nodes // Holder for search jQuery nodes
this.search = null; this.search = null;
// Reference to object with dialog // Reference to object with dialog
this.dialog = null; this.dialog = null;
this._super.apply(this, arguments);
}, },
destroy: function() { destroy: function() {
this._super.apply(this, arguments); this._super.apply(this, arguments);
}, },
/**
* Tell et2 widget framework where to go
*/
getDOMNode: function(_sender) {
if(_sender == this.search_widget)
{
return this.search != null ? this.search[0] : this.search_widget._parent.getDOMNode();
}
return this._super.apply(this, arguments);
},
/** /**
* Single selection - override to add search button * Single selection - override to add search button
*/ */
@ -141,18 +153,38 @@ var et2_selectAccount = et2_selectbox.extend(
var type = this.egw().preference('account_selection', 'common'); var type = this.egw().preference('account_selection', 'common');
if(type == 'primary_group') if(type == 'primary_group')
{ {
// Allow search 'inside' this widget
this.supportedWidgetClasses = [et2_link_entry];
// Add quick search - turn off multiple to get normal result list
this.options.multiple = false;
this._create_search();
// Clear search box after select
var old_select = this.search_widget.select;
this.search_widget.select = function() {
old_select.apply(this, arguments);
this.search.val('');
};
// Put search results as a DOM sibling of the options, for proper display
this.search_widget.search.on("autocompleteopen", jQuery.proxy(function() {
this.search_widget.search.data("autocomplete").menu.element.appendTo(this.node);
},this));
this.search = jQuery(document.createElement("li"))
.appendTo(this.multiOptions.prev().find('ul'));
this.options.multiple = true;
// Add search button // Add search button
var button = jQuery(document.createElement("li")) var button = jQuery(document.createElement("li"))
.addClass("et2_clickable") .addClass("et2_clickable")
.click(this, this._open_multi_search) .click(this, this._open_multi_search)
.append('<span class="ui-icon ui-icon-search"/>') .append('<span class="ui-icon ui-icon-search"/>')
.append("<span>"+this.egw().lang('search')+"</span>");
var type = this.egw().preference('account_selection', 'common'); var type = this.egw().preference('account_selection', 'common');
// Put it first so check/uncheck don't move around // Put it last so check/uncheck doesn't move around
this.multiOptions.prev().show().find('ul') this.multiOptions.prev().find('ul')
.prepend(button); .append(button);
} }
else if (type == 'popup') else if (type == 'popup')
{ {
@ -490,7 +522,6 @@ var et2_selectAccount = et2_selectbox.extend(
.addClass("et2_clickable") .addClass("et2_clickable")
.click(selected, function(e) {jQuery("li",e.data).remove();}) .click(selected, function(e) {jQuery("li",e.data).remove();})
.append('<span class="ui-icon ui-icon-closethick"/>') .append('<span class="ui-icon ui-icon-closethick"/>')
.append("<span>"+this.egw().lang('Remove all')+"</span>")
.appendTo(controls); .appendTo(controls);
// Add in currently selected // Add in currently selected
@ -513,7 +544,7 @@ var et2_selectAccount = et2_selectbox.extend(
var option = jQuery(document.createElement('li')) var option = jQuery(document.createElement('li'))
.attr("id",'sel_'+value) .attr("id",'sel_'+value)
.appendTo(list); .appendTo(list);
jQuery('<span class="ui-icon ui-icon-close et2_clickable"/>') jQuery('<div class="ui-icon ui-icon-close et2_clickable"/>')
.css("float", "right") .css("float", "right")
.appendTo(option) .appendTo(option)
.click(function() { .click(function() {

View File

@ -374,16 +374,10 @@ var et2_selectbox = et2_inputWidget.extend(
icon_class: 'ui-icon-check', icon_class: 'ui-icon-check',
label: 'Check all', label: 'Check all',
click: function(e) { click: function(e) {
jQuery("input",e.data).attr("checked", true); var all_set = jQuery("input[type='checkbox']",e.data).prop("checked");
jQuery("input[type='checkbox']",e.data).prop("checked", !all_set);
} }
}, },
uncheck: {
icon_class: 'ui-icon-closethick',
label: 'Uncheck all',
click: function(e) {
jQuery("input",e.data).attr("checked", false);
}
}
}; };
for(var key in header_controls) for(var key in header_controls)
{ {
@ -391,15 +385,27 @@ var et2_selectbox = et2_inputWidget.extend(
.addClass("et2_clickable") .addClass("et2_clickable")
.click(options, header_controls[key].click) .click(options, header_controls[key].click)
.append('<span class="ui-icon ' + header_controls[key].icon_class + '"/>') .append('<span class="ui-icon ' + header_controls[key].icon_class + '"/>')
.append("<span>"+this.egw().lang(header_controls[key].label)+"</span>")
.appendTo(controls); .appendTo(controls);
} }
} }
else if (header[0].childNodes.length == 0)
// Hide the header, only show it on hover / focus, but show it out of flow, above
// the list of options so it doesn't reflow the page
var hide_header = !this.options.empty_label && !this.options.label;
if(hide_header)
{ {
// Hide header - nothing there but padding // Hide header
header.hide(); header.hide();
// Show / hide again
node.on('mouseenter focusin', function() {
header.show();
header.css("width", header.css("width"));
header.css("position", "absolute");
header.css("top", options.position().top - header.outerHeight());
});
node.on('mouseleave focusout', function() {if(hide_header) header.hide();});
} }
this.setDOMNode(node[0]); this.setDOMNode(node[0]);

View File

@ -251,20 +251,31 @@ button.et2_button_text:focus, input[type=button]:focus {
* Multi-select widget * Multi-select widget
*/ */
.et2_selectbox .ui-widget-header { .et2_selectbox .ui-widget-header {
padding: 2px 6px 0px 6px; padding: 0px 6px 0px 6px;
text-align: center;
} }
.et2_selectbox .ui-widget-header ul { .et2_selectbox .ui-widget-header ul {
float: right; float: left;
margin-left: -5px;
text-align: left;
} }
.et2_selectbox .ui-widget-header li { .et2_selectbox .ui-widget-header li {
float: left; float: left;
padding: 2px;
padding-top: 0px padding-top: 0px
} }
.et2_selectbox .ui-widget-header li span.ui-icon { .et2_selectbox .ui-widget-header li>span.ui-icon {
float: left; float: left;
margin-top: -2px; margin-top: -2px;
} }
.et2_selectbox .ui-widget-header li>div.et2_link_entry {
/* Shrink search box to same size as header */
margin-top: -2px;
margin-bottom: -2px;
margin-right: 1ex;
}
.et2_selectbox .ui-widget-header li>div.et2_link_entry input {
height: 14px;
}
.et2_selectbox .ui-multiselect-checkboxes { .et2_selectbox .ui-multiselect-checkboxes {
overflow-y: scroll; overflow-y: scroll;
position: relative; position: relative;
@ -304,6 +315,14 @@ button.et2_button_text:focus, input[type=button]:focus {
height: 1.8em; height: 1.8em;
} }
.et2_selectbox .ui-multiselect-checkboxes div.ui-icon-close {
visibility: hidden;
padding: 0px;
}
.et2_selectbox .ui-multiselect-checkboxes li:hover div.ui-icon-close {
visibility: visible;
}
/* Read-only multi-select */ /* Read-only multi-select */
ul.et2_selectbox { ul.et2_selectbox {
margin: 0px; margin: 0px;
@ -493,6 +512,7 @@ div.et2_link_entry input.ui-autocomplete-input {
top: 3px; top: 3px;
left: -18px; left: -18px;
cursor: pointer; cursor: pointer;
margin-top: -3px;
} }
/* Link to */ /* Link to */