From 5513680a9f1e8ce9eebb9e5d140d6111af17bbd6 Mon Sep 17 00:00:00 2001 From: jlukic Date: Fri, 20 Mar 2015 18:15:55 -0400 Subject: [PATCH] Iteration on multiselect --- src/definitions/modules/dropdown.js | 80 ++++++++++++++++--- src/definitions/modules/dropdown.less | 29 ++++--- src/themes/default/modules/dropdown.variables | 16 ++-- 3 files changed, 95 insertions(+), 30 deletions(-) diff --git a/src/definitions/modules/dropdown.js b/src/definitions/modules/dropdown.js index 24c62d724..c96d9d20d 100644 --- a/src/definitions/modules/dropdown.js +++ b/src/definitions/modules/dropdown.js @@ -278,6 +278,9 @@ $.fn.dropdown = function(parameters) { } if( module.can.show() && !module.is.active() ) { module.debug('Showing dropdown'); + if(module.is.multiple()) { + module.filterActive(); + } module.animate.show(function() { if( module.can.click() ) { module.bind.intent(); @@ -357,6 +360,11 @@ $.fn.dropdown = function(parameters) { .on('blur' + eventNamespace, selector.search, module.event.searchBlur) .on('click' + eventNamespace, selector.text, module.event.searchTextFocus) ; + if(module.is.multiple()) { + $module + .on('click' + eventNamespace, module.event.click) + ; + } } else { if(settings.on == 'click') { @@ -450,6 +458,9 @@ $.fn.dropdown = function(parameters) { .not($results) .addClass(className.filtered) ; + if(module.is.multiple()) { + module.filterActive(); + } module.verbose('Selecting first non-filtered element'); module.remove.selectedItem(); $item @@ -466,6 +477,12 @@ $.fn.dropdown = function(parameters) { } }, + filterActive: function() { + $item.filter('.' + className.active) + .addClass(className.filtered) + ; + }, + focusSearch: function() { if( module.is.search() ) { $search @@ -483,7 +500,7 @@ $.fn.dropdown = function(parameters) { : $activeItem, hasSelected = ($selectedItem.size() > 0) ; - if(hasSelected) { + if(hasSelected && !module.is.multiple()) { module.event.item.click.call($selectedItem); module.remove.filteredItem(); } @@ -493,6 +510,12 @@ $.fn.dropdown = function(parameters) { }, event: { + click: function(event) { + // focus search + if($(event.target).is($module) && !(document.activeElement === $search[0])) { + $search.focus(); + } + }, // prevents focus callback from occuring on mousedown mousedown: function() { activated = true; @@ -1243,12 +1266,16 @@ $.fn.dropdown = function(parameters) { selected: function(value) { var $selectedItem = module.get.item(value), + isMultiple = module.is.multiple(), + shouldAnimate = (isMultiple && $selectedItem.length == 1), selectedText, selectedValue ; if($selectedItem && !$selectedItem.hasClass(className.active) ) { module.debug('Setting selected menu item to', $selectedItem); - module.remove.activeItem(); + if(!module.is.multiple()) { + module.remove.activeItem(); + } module.remove.selectedItem(); $selectedItem .addClass(className.active) @@ -1259,8 +1286,8 @@ $.fn.dropdown = function(parameters) { ; selectedText = module.get.choiceText($selected); selectedValue = module.get.choiceValue($selected, selectedText); - if(module.is.multiple()) { - module.add.label(selectedValue, selectedText); + if(isMultiple) { + module.add.label(selectedValue, selectedText, shouldAnimate); } else { module.set.text(selectedText); @@ -1274,18 +1301,30 @@ $.fn.dropdown = function(parameters) { }, add: { - label: function(value, text) { + label: function(value, text, shouldAnimate) { var $label = $('') .addClass(className.label) - .data('value', value) + .attr('data-value', value) .html(text + '') ; if(settings.label.variation) { $label.addClass(settings.label.variation); } - module.debug('Adding selection label', $label); - $label.insertBefore($search); + if(shouldAnimate) { + module.debug('Animating in label', $label); + $label + .addClass(className.hidden) + .insertBefore($search) + .transition(settings.label.transition, settings.label.duration) + ; + } + else { + module.debug('Adding selection label', $label); + $label + .insertBefore($search) + ; + } } }, @@ -1308,6 +1347,15 @@ $.fn.dropdown = function(parameters) { selectedItem: function() { $item.removeClass(className.selected); }, + label: function(value) { + $module + .find(selector.label) + .filter('[data-value="' + value +'"]') + .transition(settings.label.transition, settings.label.duration, function() { + $(this).remove(); + }) + ; + }, tabbable: function() { if( module.has.search() ) { module.debug('Searchable dropdown initialized'); @@ -1424,7 +1472,9 @@ $.fn.dropdown = function(parameters) { ? callback : function(){} ; - module.set.scrollPosition(module.get.activeItem(), true); + if(!module.is.multiple()) { + module.set.scrollPosition(module.get.activeItem(), true); + } module.verbose('Doing menu show animation', $currentMenu); if( module.is.hidden($currentMenu) || module.is.animating($currentMenu) ) { @@ -1786,7 +1836,9 @@ $.fn.dropdown.settings = { sortSelect : false, label: { - variation: false + transition : 'horizontal flip', + duration : 250, + variation : false }, allowCategorySelection : false, @@ -1798,10 +1850,10 @@ $.fn.dropdown.settings = { touch : 50 }, - forceSelection: true, + forceSelection : true, - transition : 'auto', - duration : 250, + transition : 'auto', + duration : 250, /* Callbacks */ onNoResults : function(searchTerm){}, @@ -1833,6 +1885,7 @@ $.fn.dropdown.settings = { dropdown : '.ui.dropdown', input : '> input[type="hidden"], > select', item : '.item', + label : '> .label', menu : '.menu', menuIcon : '.dropdown.icon', search : 'input.search, .menu > .search > input', @@ -1845,6 +1898,7 @@ $.fn.dropdown.settings = { disabled : 'disabled', dropdown : 'ui dropdown', filtered : 'filtered', + hidden : 'hidden transition', label : 'ui label', loading : 'loading', menu : 'menu', diff --git a/src/definitions/modules/dropdown.less b/src/definitions/modules/dropdown.less index 37508d037..ae3aa1778 100755 --- a/src/definitions/modules/dropdown.less +++ b/src/definitions/modules/dropdown.less @@ -590,18 +590,28 @@ select.ui.dropdown { Multiple ---------------*/ -/* Multiple Search Selection */ +/* Multiple Selection */ .ui.multiple.dropdown { - cursor: auto; padding: @multipleSelectionTopPadding @multipleSelectionRightPadding @multipleSelectionBottomPadding @multipleSelectionLeftPadding; } +.ui.multiple.dropdown .menu { + cursor: auto; +} + +/* Multiple Search Selection */ +.ui.multiple.search.dropdown { + cursor: text; +} /* Selection Label */ .ui.multiple.dropdown > .label { display: inline-block; vertical-align: middle; padding: @labelPadding; - margin: 0em @labelSpacing @labelSpacing 0em; + margin: (@labelVerticalSpacing / 2) @labelHorizontalSpacing (@labelVerticalSpacing / 2) 0em; +} +.ui.multiple.dropdown > .label .delete { + opacity: 0.4; } /* Prompt Text */ @@ -616,19 +626,14 @@ select.ui.dropdown { .ui.multiple.selection.dropdown > input.search { position: static; padding: 0; - width: auto; - margin-top: @searchSelectionLineHeightOffset; - padding-top: @labelVerticalPadding; -} -.ui.multiple.selection.dropdown > .label + input.search { - margin-left: 0.5em; + width: 5em; + margin: @multipleSelectionSearchMargin; } - /* Dropdown Icon */ .ui.multiple.selection.dropdown .dropdown.icon { - padding: 0em; - margin: 0em; + margin: 0em -@labelHorizontalPadding 0em 0em; + padding: @labelPadding; } diff --git a/src/themes/default/modules/dropdown.variables b/src/themes/default/modules/dropdown.variables index dc86555d8..d9ac5bc74 100644 --- a/src/themes/default/modules/dropdown.variables +++ b/src/themes/default/modules/dropdown.variables @@ -114,7 +114,7 @@ @selectionMinWidth: 180px; @selectionBackground: @white; @selectionDisplay: inline-block; -@selectionItemDivider: 1px solid @borderColor; +@selectionItemDivider: 1px solid rgba(0, 0, 0, 0.05); @selectionVerticalPadding: 0.8em; @selectionHorizontalPadding: 1.1em; @selectionIconDistance: 2em; @@ -205,15 +205,21 @@ /* Multiple */ @labelVerticalPadding: 0.4285em; +@labelSize: @relativeSmall; @labelHorizontalPadding: @relativeMini; @labelPadding: @labelVerticalPadding @labelHorizontalPadding; -@labelSpacing: 0.21428em; -@multipleSelectionTopPadding: (@selectionVerticalPadding - @labelVerticalPadding); +@labelHorizontalSpacing: 0.5em; +@labelVerticalSpacing: 0.5em; + + +/* This is calculated from @selectionPadding - @labelSize * labelPadding */ +@multipleSelectionTopPadding: 0.2857em; @multipleSelectionRightPadding: @selectionIconDistance; -@multipleSelectionBottomPadding: @selectionTopPadding - @labelSpacing; +@multipleSelectionBottomPadding: @multipleSelectionTopPadding; @multipleSelectionLeftPadding: (@selectionHorizontalPadding - @labelHorizontalPadding); -@multipleSearchOffset: (@labelVerticalPadding - @searchSelectionLineHeightOffset); + +@multipleSelectionSearchMargin: 0.4em 0em 0.4em 0.5em; /* Inline */ @inlineIconMargin: 0em 0.5em 0em 0.25em;