Give taglist special behaviour when it's too small to show everything - it uses ellipsis & hover

This commit is contained in:
Nathan Gray 2016-03-07 22:39:11 +00:00
parent bfdec69428
commit 190457bef8
8 changed files with 331 additions and 89 deletions

View File

@ -24,7 +24,7 @@
* @see http://nicolasbize.github.io/magicsuggest/ * @see http://nicolasbize.github.io/magicsuggest/
* @augments et2_selectbox * @augments et2_selectbox
*/ */
var et2_taglist = (function(){ "use strict"; return et2_selectbox.extend( var et2_taglist = (function(){ "use strict"; return et2_selectbox.extend([et2_IResizeable],
{ {
attributes: { attributes: {
"empty_label": { "empty_label": {
@ -144,6 +144,10 @@ var et2_taglist = (function(){ "use strict"; return et2_selectbox.extend(
{ {
// Undo the plugin // Undo the plugin
} }
if(this._hide_timeout)
{
window.clearTimeout(this._hide_timeout);
}
this._super.apply(this, arguments); this._super.apply(this, arguments);
}, },
@ -203,6 +207,8 @@ var et2_taglist = (function(){ "use strict"; return et2_selectbox.extend(
useCommaKey: this.options.useCommaKey, useCommaKey: this.options.useCommaKey,
disabled: this.options.disabled || this.options.readonly, disabled: this.options.disabled || this.options.readonly,
editable: !(this.options.disabled || this.options.readonly), editable: !(this.options.disabled || this.options.readonly),
// If there are select options, enable toggle on click so user can see them
toggleOnClick: !jQuery.isEmptyObject(this.options.select_options),
selectionRenderer: jQuery.proxy(this.options.tagRenderer || this.selectionRenderer,this), selectionRenderer: jQuery.proxy(this.options.tagRenderer || this.selectionRenderer,this),
renderer: jQuery.proxy(this.options.listRenderer || this.selectionRenderer,this), renderer: jQuery.proxy(this.options.listRenderer || this.selectionRenderer,this),
maxSelection: this.options.multiple ? this.options.maxSelection : 1, maxSelection: this.options.multiple ? this.options.maxSelection : 1,
@ -217,6 +223,12 @@ var et2_taglist = (function(){ "use strict"; return et2_selectbox.extend(
this.taglist_options.maxDropHeight = parseInt(this.options.height); this.taglist_options.maxDropHeight = parseInt(this.options.height);
} }
// If only one, do not require minimum chars or the box won't drop down
if(this.options.multiple !== true)
{
this.taglist_options.minChars = 0;
}
this.taglist = this.taglist.magicSuggest(this.taglist_options); this.taglist = this.taglist.magicSuggest(this.taglist_options);
this.$taglist = $j(this.taglist); this.$taglist = $j(this.taglist);
if(this.options.value) if(this.options.value)
@ -242,7 +254,39 @@ var et2_taglist = (function(){ "use strict"; return et2_selectbox.extend(
// Keep focus when selecting from the list // Keep focus when selecting from the list
.on("selectionchange", function() { $j('input',this.container).focus();}) .on("selectionchange", function() { $j('input',this.container).focus();})
// Bind keyup so we can start ajax search when we like // Bind keyup so we can start ajax search when we like
.on('keyup.start_search', jQuery.proxy(this._keyup, this)); .on('keyup.start_search', jQuery.proxy(this._keyup, this))
.on('blur', jQuery.proxy(this.resize, this))
// Hide tooltip when you're editing, it can get annoying otherwise
.on('focus', function() {
$j('.egw_tooltip').hide();
})
// Position absolute to break out of containers
.on('expand', jQuery.proxy(function(c) {
var taglist = this.taglist;
var background = this.taglist.combobox.css('background');
var wrapper = jQuery(document.createElement('div'))
// Keep any additional classes
.addClass(this.div.attr('class'))
.css('position','absolute')
.appendTo('body')
.position({my: 'left top', at: 'left bottom', of: this.taglist.container})
this.taglist.combobox
.width(this.taglist.container.innerWidth())
.appendTo(wrapper)
.css('background', background);
// Close dropdown if click elsewhere, but wait until after or it
// will close immediately
window.setTimeout(function() {
$j('body').one('click',function() {
taglist.collapse();
})},1
);
this.$taglist.one('collapse', function() {
wrapper.remove();
})
},this));
// Unbind change handler of widget's ancestor to stop it from bubbling // Unbind change handler of widget's ancestor to stop it from bubbling
// taglist has its own onchange // taglist has its own onchange
@ -273,6 +317,10 @@ var et2_taglist = (function(){ "use strict"; return et2_selectbox.extend(
widget.onfocus.call(widget.taglist, e, widget); widget.onfocus.call(widget.taglist, e, widget);
}); });
} }
// Do size limit checks
this.resize();
return true; return true;
}, },
@ -455,13 +503,76 @@ var et2_taglist = (function(){ "use strict"; return et2_selectbox.extend(
_set_multiple: function(multiple) { _set_multiple: function(multiple) {
this._multiple = multiple === true ? true : false; this._multiple = multiple === true ? true : false;
this.div.toggleClass('et2_taglist_single', !this._multiple); this.div.toggleClass('et2_taglist_single', !this._multiple)
this.div.toggleClass('et2_taglist_toggle', this.options.multiple === 'toggle'); .toggleClass('et2_taglist_toggle', this.options.multiple === 'toggle')
.removeClass('ui-state-hover');
this.taglist.setMaxSelection(this._multiple ? this.options.maxSelection : 1); this.taglist.setMaxSelection(this._multiple ? this.options.maxSelection : 1);
if(!this._multiple && this.taglist.getValue().length > 1) if(!this._multiple && this.taglist.getValue().length > 1)
{ {
this.set_value(this.taglist.getValue()[0]); this.set_value(this.taglist.getValue()[0]);
} }
// This changes sizes, so
this.resize();
},
/**
* Set up this widget as size-restricted, so it cannot be as large as needed.
* Therefore, we hide some things if the user is not interacting.
*/
_setup_small: function() {
this.div.addClass('et2_taglist_small');
var value_count = this.taglist.getValue().length;
if(value_count)
{
this.div.attr('data-content', value_count > 1 ? egw.lang('%1 selected',value_count) : '...');
}
else
{
this.div.attr('data-content','');
}
this.div.css('height','')
// Listen to hover on size restricted taglists
.on('mouseenter.small_size', jQuery.proxy(function() {
this.div.addClass('ui-state-hover');
if(this._hide_timeout)
{
window.clearTimeout(this._hide_timeout);
}
$j('.egw_tooltip').hide();
},this))
.on('mouseleave.small_size', jQuery.proxy(function(event) {
// Ignore tooltip
if(event.toElement && $j(event.toElement).hasClass('egw_tooltip')) return;
if(this._hide_timeout)
{
window.clearTimeout(this._hide_timeout);
}
this._hide_timeout = window.setTimeout(
jQuery.proxy(function() {
this.div.removeClass('ui-state-hover');
// Re-enable tooltip
this.set_statustext(this.options.statustext);
this._hide_timeout = null;
},this), 500);
},this)
);
this.$taglist
.on('blur.small_size', jQuery.proxy(function() {
this.div.removeClass('ui-state-active');
this.div.trigger('mouseleave');
},this))
.on('focus.small_size', jQuery.proxy(function() {
this.div.addClass('ui-state-active');
if(this._hide_timeout)
{
window.clearTimeout(this._hide_timeout);
}
},this))
}, },
/** /**
@ -535,6 +646,36 @@ var et2_taglist = (function(){ "use strict"; return et2_selectbox.extend(
// trigger blur on taglist to not loose just typed value // trigger blur on taglist to not loose just typed value
jQuery(this.taglist.container).trigger('blur'); jQuery(this.taglist.container).trigger('blur');
return this.taglist.getValue(); return this.taglist.getValue();
},
/**
* Resize lets us toggle the 'small' handling
*/
resize: function() {
this.div.off('.small_size');
this.div.removeClass('et2_taglist_small');
// How much space is needed for first one?
var min_width = $j('.ms-sel-item',this.div ).first().outerWidth() || this.div.children().first().width();
// Not ready yet
if(min_width === null) return;
min_width += (this.options.multiple === 'toggle' ? $j('.toggle',this.div).outerWidth() : 0);
// Not enough for one
if(min_width > this.div.width() ||
this.taglist.container.width() > this.div.width() || this.taglist.container.height() > this.div.height()
)
{
this._setup_small();
}
else
{
console.log("not small");
}
} }
});}).call(this); });}).call(this);
et2_register_widget(et2_taglist, ["taglist"]); et2_register_widget(et2_taglist, ["taglist"]);

38
etemplate/js/etemplate2.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -908,6 +908,84 @@ ul.et2_link_string {
/** /**
* Tag list * Tag list
*/ */
.ms-ctn,
.ms-res-ctn {
/* It doesn't really work smaller than this */
min-width: 150px;
border: solid 1px #bbbbbb;
}
.ms-ctn .loading {
position: relative;
margin: 0px auto -16px auto;
top: 5px;
}
.et2_taglist div.ms-sel-ctn .ms-close-btn {
width: 10px;
height: 10px;
background-position-y: -10px;
background-size: cover;
background-repeat: no-repeat;
margin: 2px -16px 0 10px;
}
.et2_taglist .ms-res-ctn {
position:absolute;
background: #FFF;
overflow-y: auto;
z-index: 9999;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
border: 1px solid #CCC;
left: -1px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
border-top: 0;
border-top-left-radius: 0;
border-top-right-radius: 0;
padding: 1px 0px;
}
.et2_taglist div.ms-sel-ctn {
padding-right: 0px;
overflow-x: hidden;
}
.et2_taglist div.ms-sel-ctn .ms-sel-item {
margin: 0px 5px 3px 0px;
padding: 3px 20px 3px 5px;
border: 1px solid #aaa;
border-radius: 3px;
background-color: #e4e4e4;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-clip: padding-box;
box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
color: #333;
line-height: 13px;
font-size: 11px;
cursor: default;
word-break: break-all;
}
.et2_taglist.ui-state-hover,
.et2_taglist.ui-state-active {
font-weight: inherit;
}
.et2_taglist div.ms-ctn {
background-color: white;
}
.et2_taglist div.ms-ctn input {
padding: 3px 5px;
}
.et2_taglist div.ms-ctn input:focus {
min-width: 10em;
}
.et2_taglist .ms-res-ctn .ms-res-item {
line-height: 13px;
padding: 3px 6px;
}
.et2_taglist_ro ul { .et2_taglist_ro ul {
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
@ -921,8 +999,8 @@ ul.et2_link_string {
font-weight: bold; font-weight: bold;
} }
/* min-height to fix calculations done while hidden */ /* min-height to fix calculations done while hidden */
.et2_taglist > div { .et2_taglist > div:first-child {
min-height: 2em; min-height: 23px;
} }
/* Toggle single / multiple */ /* Toggle single / multiple */
.et2_taglist_toggle { .et2_taglist_toggle {
@ -936,7 +1014,7 @@ ul.et2_link_string {
.et2_taglist_toggle.et2_taglist_single > div.ms-ctn { .et2_taglist_toggle.et2_taglist_single > div.ms-ctn {
padding-right: 7px padding-right: 7px
} }
.et2_taglist_toggle > div:last-child { .et2_taglist_toggle > div.toggle {
margin-left: -1px; margin-left: -1px;
float: right; float: right;
@ -949,7 +1027,7 @@ ul.et2_link_string {
background-position: center center; background-position: center center;
background-image: url("../../../phpgwapi/templates/default/images/foldertree_nolines_minus.gif"); background-image: url("../../../phpgwapi/templates/default/images/foldertree_nolines_minus.gif");
} }
.et2_taglist_toggle.et2_taglist_single > div:last-child { .et2_taglist_toggle.et2_taglist_single > div.toggle {
background-image: url("../../../phpgwapi/templates/default/images/foldertree_nolines_plus.gif"); background-image: url("../../../phpgwapi/templates/default/images/foldertree_nolines_plus.gif");
} }
.et2_taglist_toggle:not(.et2_taglist_single) .ms-trigger { .et2_taglist_toggle:not(.et2_taglist_single) .ms-trigger {
@ -958,6 +1036,7 @@ ul.et2_link_string {
/* Single select */ /* Single select */
.et2_taglist_single .ms-ctn { .et2_taglist_single .ms-ctn {
padding: 0px 7px; padding: 0px 7px;
min-width: 50px;
} }
.et2_taglist_single div.ms-ctn .ms-sel-item + input { .et2_taglist_single div.ms-ctn .ms-sel-item + input {
display: none; display: none;
@ -971,6 +1050,62 @@ div .et2_taglist_single div.ms-sel-ctn div.ms-sel-item {
width: calc(100% - 43px); width: calc(100% - 43px);
margin-bottom: 0px; margin-bottom: 0px;
padding-bottom: 6px; padding-bottom: 6px;
white-space: nowrap;
overflow: hidden;
}
/* Taglist that is limited in size - does not grow */
.et2_taglist.et2_taglist_small .ms-ctn,
.et2_taglist.et2_taglist_small .ms-res-ctn {
min-width: auto;
}
.et2_taglist_small {
position: relative;
max-height: 3em;
overflow: hidden;
}
.et2_taglist_small::before {
content: attr(data-content) '';
text-align: right;
position: absolute;
z-index: 1;
top: 1px;
bottom: 0px;
right: 0;
padding-top: 1em;
padding-bottom: 3px;
padding-right: 1em;
padding-left: 2em;
min-height: 1.2em;
min-width: 25%;
background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 25%);
}
.et2_taglist_toggle.et2_taglist_small::before {
right: 25px;
}
.et2_taglist_small.ui-state-hover,
.et2_taglist_small.ui-state-active {
position: absolute;
max-height: none;
max-width: 25em;
min-width: 15em;
background: white;
z-index: 5;
margin-top: -14px;
transition-duration: 0s;
font-weight: normal;
overflow: visible;
}
.et2_taglist_small.ui-state-hover::before,
.et2_taglist_small.ui-state-active::before {
display: none;
}
.et2_taglist_small div.ms-sel-item {
white-space: nowrap;
overflow: hidden;
}
.et2_taglist_toggle.et2_taglist_small.et2_taglist_single::before {
right: 51px;
} }
/* Taglist category */ /* Taglist category */
@ -1619,79 +1754,6 @@ div.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button {
height: inherit; height: inherit;
} }
/** /**
* et2_taglist
*/
.ms-ctn,
.ms-res-ctn {
/* It doesn't really work smaller than this */
min-width: 150px;
border: solid 1px #bbbbbb;
}
.ms-ctn .loading {
position: relative;
margin: 0px auto -16px auto;
top: 5px;
}
.et2_taglist div.ms-sel-ctn .ms-close-btn {
width: 10px;
height: 10px;
background-position-y: -10px;
background-size: cover;
background-repeat: no-repeat;
margin: 2px -16px 0 10px;
}
.et2_taglist .ms-res-ctn {
position:absolute;
background: #FFF;
overflow-y: auto;
z-index: 9999;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
border: 1px solid #CCC;
left: -1px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
border-top: 0;
border-top-left-radius: 0;
border-top-right-radius: 0;
padding: 1px 0px;
}
.et2_taglist div.ms-sel-ctn {
padding-right: 0px;
}
.et2_taglist div.ms-sel-ctn .ms-sel-item {
margin: 0px 5px 3px 0px;
padding: 3px 20px 3px 5px;
border: 1px solid #aaa;
border-radius: 3px;
background-color: #e4e4e4;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-clip: padding-box;
box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
color: #333;
line-height: 13px;
font-size: 11px;
cursor: default;
word-break: break-all;
}
.et2_taglist div.ms-ctn input {
padding: 3px 5px;
}
.et2_taglist div.ms-ctn input:focus {
min-width: 10em;
}
.et2_taglist .ms-res-ctn .ms-res-item {
line-height: 13px;
padding: 3px 6px;
}
/**
* et2_toolbar * et2_toolbar
*/ */
.et2_toolbar { .et2_toolbar {

View File

@ -996,11 +996,11 @@
/** /**
* et2_taglist * et2_taglist
*/ */
.et2_taglist_toggle > div:last-child { .et2_taglist_toggle > div.toggle {
background-image: url("../images/minus.svg"); background-image: url("../images/minus.svg");
background-size: 50%; background-size: 50%;
} }
.et2_taglist_toggle.et2_taglist_single > div:last-child { .et2_taglist_toggle.et2_taglist_single > div.toggle {
background-image: url("../images/plus.svg"); background-image: url("../images/plus.svg");
background-size: 50%; background-size: 50%;
} }

View File

@ -985,11 +985,11 @@
/** /**
* et2_taglist * et2_taglist
*/ */
.et2_taglist_toggle > div:last-child { .et2_taglist_toggle > div.toggle {
background-image: url("../images/minus.svg"); background-image: url("../images/minus.svg");
background-size: 50%; background-size: 50%;
} }
.et2_taglist_toggle.et2_taglist_single > div:last-child { .et2_taglist_toggle.et2_taglist_single > div.toggle {
background-image: url("../images/plus.svg"); background-image: url("../images/plus.svg");
background-size: 50%; background-size: 50%;
} }

View File

@ -924,11 +924,11 @@ textarea.description {
/** /**
* et2_taglist * et2_taglist
*/ */
.et2_taglist_toggle > div:last-child { .et2_taglist_toggle > div.toggle {
background-image: url("../images/minus.svg"); background-image: url("../images/minus.svg");
background-size: 50%; background-size: 50%;
} }
.et2_taglist_toggle.et2_taglist_single > div:last-child { .et2_taglist_toggle.et2_taglist_single > div.toggle {
background-image: url("../images/plus.svg"); background-image: url("../images/plus.svg");
background-size: 50%; background-size: 50%;
} }

View File

@ -1007,11 +1007,11 @@
/** /**
* et2_taglist * et2_taglist
*/ */
.et2_taglist_toggle > div:last-child { .et2_taglist_toggle > div.toggle {
background-image: url("../images/minus.svg"); background-image: url("../images/minus.svg");
background-size: 50%; background-size: 50%;
} }
.et2_taglist_toggle.et2_taglist_single > div:last-child { .et2_taglist_toggle.et2_taglist_single > div.toggle {
background-image: url("../images/plus.svg"); background-image: url("../images/plus.svg");
background-size: 50%; background-size: 50%;
} }