Browse Source

Fixes #1458 Improvements to Dropdown

- Dropdown now allows callback on noSearch Results
- Dropdown now throttles input events
- Dropdown now does not search for active element on show to find scroll position (smoother animations)
- Dropdown getChoiceValue and getChoiceText consolidated across multiple uses internally
pull/1481/head
jlukic 10 years ago
parent
commit
4623bf436f
1 changed files with 83 additions and 75 deletions
  1. 158
      src/definitions/modules/dropdown.js

158
src/definitions/modules/dropdown.js

@ -188,7 +188,7 @@ $.fn.dropdown = function(parameters) {
show: function() { show: function() {
module.debug('Checking if dropdown can show'); module.debug('Checking if dropdown can show');
if( !module.is.active() ) {
if( !module.is.active() && !module.is.allFiltered() ) {
module.animate.show(function() { module.animate.show(function() {
if( module.can.click() ) { if( module.can.click() ) {
module.bind.intent(); module.bind.intent();
@ -326,23 +326,15 @@ $.fn.dropdown = function(parameters) {
$results = $(), $results = $(),
exactRegExp = new RegExp('(?:\s|^)' + searchTerm, 'i'), exactRegExp = new RegExp('(?:\s|^)' + searchTerm, 'i'),
fullTextRegExp = new RegExp(searchTerm, 'i'), fullTextRegExp = new RegExp(searchTerm, 'i'),
allItemsFiltered,
$filteredItems
allItemsFiltered
; ;
module.verbose('Searching for matching values');
$item $item
.each(function(){ .each(function(){
var var
$choice = $(this), $choice = $(this),
text = ( $choice.data(metadata.text) !== undefined )
? $choice.data(metadata.text)
: (settings.preserveHTML)
? $choice.html()
: $choice.text(),
value = ( $choice.data(metadata.value) !== undefined)
? $choice.data(metadata.value)
: (typeof text === 'string')
? text.toLowerCase()
: text
text = module.get.choiceText($choice),
value = module.get.choiceValue($choice, text)
; ;
if( exactRegExp.test( text ) || exactRegExp.test( value ) ) { if( exactRegExp.test( text ) || exactRegExp.test( value ) ) {
$results = $results.add($choice); $results = $results.add($choice);
@ -354,21 +346,25 @@ $.fn.dropdown = function(parameters) {
} }
}) })
; ;
$filteredItems = $item.not($results);
allItemsFiltered = ($filteredItems.size() == $item.size());
module.debug('Setting filter', searchTerm);
module.remove.filteredItem(); module.remove.filteredItem();
module.remove.selectedItem();
$filteredItems
$item
.not($results)
.addClass(className.filtered) .addClass(className.filtered)
; ;
module.verbose('Selecting first non-filtered element');
module.remove.selectedItem();
$item $item
.not('.' + className.filtered) .not('.' + className.filtered)
.eq(0) .eq(0)
.addClass(className.selected) .addClass(className.selected)
; ;
if(allItemsFiltered) {
if( module.is.allFiltered() ) {
module.debug('All items filtered, hiding dropdown', searchTerm);
module.hide(); module.hide();
$.proxy(settings.onNoResults, element)(searchTerm);
} }
}, },
@ -409,15 +405,19 @@ $.fn.dropdown = function(parameters) {
}, },
input: function(event) { input: function(event) {
var var
query = $search.val()
query
; ;
if(module.is.searchSelection()) {
if( module.can.show() ) {
module.show();
clearTimeout(module.timer);
module.timer = setTimeout(function() {
query = $search.val();
if(module.is.searchSelection()) {
module.set.filtered();
module.filter(query);
if( module.can.show() ) {
module.show();
}
} }
module.set.filtered();
}
module.filter(query);
}, settings.delay.search);
}, },
keydown: function(event) { keydown: function(event) {
var var
@ -564,16 +564,8 @@ $.fn.dropdown = function(parameters) {
click: function (event) { click: function (event) {
var var
$choice = $(this), $choice = $(this),
text = ( $choice.data(metadata.text) !== undefined )
? $choice.data(metadata.text)
: (settings.preserveHTML)
? $choice.html()
: $choice.text(),
value = ( $choice.data(metadata.value) !== undefined)
? $choice.data(metadata.value)
: (typeof text === 'string')
? text.toLowerCase()
: text,
text = module.get.choiceText($choice),
value = module.get.choiceValue($choice, text),
callback = function() { callback = function() {
module.remove.searchTerm(); module.remove.searchTerm();
module.remove.filteredItem(); module.remove.filteredItem();
@ -685,6 +677,25 @@ $.fn.dropdown = function(parameters) {
: $module.data(metadata.value) : $module.data(metadata.value)
; ;
}, },
choiceText: function($choice) {
if($choice !== undefined) {
return ($choice.data(metadata.text) !== undefined)
? $choice.data(metadata.text)
: (settings.preserveHTML)
? $choice.html()
: $choice.text()
;
}
},
choiceValue: function($choice, choiceText) {
choiceText = choiceText || module.get.choiceText($text);
return ($choice.data(metadata.value) !== undefined)
? $choice.data(metadata.value)
: (typeof choiceText === 'string')
? choiceText.toLowerCase()
: choiceText
;
},
inputEvent: function() { inputEvent: function() {
var var
input = $search[0] input = $search[0]
@ -725,6 +736,9 @@ $.fn.dropdown = function(parameters) {
module.debug('Retrieved values from select', select); module.debug('Retrieved values from select', select);
return select; return select;
}, },
activeItem: function() {
return $item.filter('.' + className.active);
},
item: function(value, strict) { item: function(value, strict) {
var var
$selectedItem = false $selectedItem = false
@ -744,16 +758,8 @@ $.fn.dropdown = function(parameters) {
.each(function() { .each(function() {
var var
$choice = $(this), $choice = $(this),
optionText = ( $choice.data(metadata.text) !== undefined )
? $choice.data(metadata.text)
: (settings.preserveHTML)
? $choice.html()
: $choice.text(),
optionValue = ( $choice.data(metadata.value) !== undefined )
? $choice.data(metadata.value)
: (typeof optionText === 'string')
? optionText.toLowerCase()
: optionText
optionText = module.get.choiceText($choice),
optionValue = module.get.choiceValue($choice, optionText)
; ;
if(strict) { if(strict) {
module.verbose('Ambiguous dropdown value using strict type check', $choice, value); module.verbose('Ambiguous dropdown value using strict type check', $choice, value);
@ -850,7 +856,7 @@ $.fn.dropdown = function(parameters) {
}, },
scrollPosition: function($item) { scrollPosition: function($item) {
var var
$item = $item || module.get.item(),
$item = $item || module.get.activeItem(),
hasActive = ($item && $item.size() > 0), hasActive = ($item && $item.size() > 0),
edgeTolerance = 5, edgeTolerance = 5,
offset, offset,
@ -930,18 +936,15 @@ $.fn.dropdown = function(parameters) {
; ;
if($selectedItem) { if($selectedItem) {
module.debug('Setting selected menu item to', $selectedItem); module.debug('Setting selected menu item to', $selectedItem);
selectedText = ($selectedItem.data(metadata.text) !== undefined)
? $selectedItem.data(metadata.text)
: (settings.preserveHTML)
? $selectedItem.html()
: $selectedItem.text()
;
module.remove.activeItem(); module.remove.activeItem();
module.remove.selectedItem(); module.remove.selectedItem();
$selectedItem $selectedItem
.addClass(className.active) .addClass(className.active)
.addClass(className.selected) .addClass(className.selected)
; ;
selectedText = module.get.choiceText($selectedItem);
module.set.text(selectedText); module.set.text(selectedText);
$.proxy(settings.onChange, element)(value, selectedText, $selectedItem); $.proxy(settings.onChange, element)(value, selectedText, $selectedItem);
} }
@ -990,6 +993,25 @@ $.fn.dropdown = function(parameters) {
}, },
is: { is: {
active: function() {
return $module.hasClass(className.active);
},
animating: function($subMenu) {
return ($subMenu)
? $subMenu.is(':animated') || $subMenu.transition && $subMenu.transition('is animating')
: $menu.is(':animated') || $menu.transition && $menu.transition('is animating')
;
},
allFiltered: function() {
console.log(($item.filter('.' + className.filtered).size() === $item.size()));
return ($item.filter('.' + className.filtered).size() === $item.size());
},
hidden: function($subMenu) {
return ($subMenu)
? $subMenu.is(':hidden')
: $menu.is(':hidden')
;
},
search: function() { search: function() {
return $module.hasClass(className.search); return $module.hasClass(className.search);
}, },
@ -1002,26 +1024,11 @@ $.fn.dropdown = function(parameters) {
selection: function() { selection: function() {
return $module.hasClass(className.selection); return $module.hasClass(className.selection);
}, },
animating: function($subMenu) {
return ($subMenu)
? $subMenu.is(':animated') || $subMenu.transition && $subMenu.transition('is animating')
: $menu.is(':animated') || $menu.transition && $menu.transition('is animating')
;
},
active: function() {
return $module.hasClass(className.active);
},
visible: function($subMenu) { visible: function($subMenu) {
return ($subMenu) return ($subMenu)
? $subMenu.is(':visible') ? $subMenu.is(':visible')
: $menu.is(':visible') : $menu.is(':visible')
; ;
},
hidden: function($subMenu) {
return ($subMenu)
? $subMenu.is(':hidden')
: $menu.is(':hidden')
;
} }
}, },
@ -1370,7 +1377,7 @@ $.fn.dropdown = function(parameters) {
$.fn.dropdown.settings = { $.fn.dropdown.settings = {
debug : false,
debug : true,
verbose : true, verbose : true,
performance : true, performance : true,
@ -1382,19 +1389,20 @@ $.fn.dropdown.settings = {
preserveHTML : true, preserveHTML : true,
delay : { delay : {
show : 200,
hide : 300,
touch : 50
hide : 300,
show : 200,
search : 100,
touch : 50
}, },
transition : 'slide down', transition : 'slide down',
duration : 250, duration : 250,
/* Callbacks */ /* Callbacks */
onChange : function(value, text){},
onShow : function(){},
onHide : function(){},
onNoResults : function(searchTerm){},
onChange : function(value, text){},
onShow : function(){},
onHide : function(){},
/* Component */ /* Component */

Loading…
Cancel
Save