semantic-ui-dropdown
Advanced tools
Comparing version 1.0.0 to 1.9.0
{ | ||
"name": "semantic-ui-dropdown", | ||
"description": "Dropdown - Semantic UI", | ||
"homepage": "http://beta.semantic-ui.com", | ||
"homepage": "http://www.semantic-ui.com", | ||
"author": { | ||
@@ -9,9 +9,22 @@ "name": "Jack Lukic", | ||
}, | ||
"ignore": ["docs", "node", "server", "spec", "src", "test"], | ||
"keywords": ["semantic", "ui", "css3", "framework"], | ||
"license": ["http://semantic-ui.mit-license.org/"], | ||
"main": ["dropdown.js", "dropdown.css"], | ||
"dependencies": { | ||
"jquery": ">=1.8" | ||
} | ||
"ignore": [ | ||
"docs", | ||
"node", | ||
"server", | ||
"spec", | ||
"src", | ||
"test" | ||
], | ||
"keywords": [ | ||
"semantic", | ||
"ui", | ||
"css3", | ||
"framework" | ||
], | ||
"license": [ | ||
"http://semantic-ui.mit-license.org/" | ||
], | ||
"main": [ | ||
"dropdown.css" | ||
] | ||
} |
@@ -11,9 +11,10 @@ { | ||
}], | ||
"keywords": ["semantic", "ui", "css", "framework"], | ||
"keywords": [ | ||
"semantic", | ||
"ui", | ||
"css", | ||
"framework" | ||
], | ||
"license": "MIT", | ||
"dependencies": { | ||
"jquery": "x.x.x" | ||
}, | ||
"main": "dropdown.js", | ||
"version": "1.0.0" | ||
"version": "1.9.0" | ||
} |
964
dropdown.js
@@ -54,3 +54,3 @@ /* | ||
$combo = ($module.prev().find(selector.text).size() > 0) | ||
$combo = ($module.prev().find(selector.text).length > 0) | ||
? $module.prev().find(selector.text) | ||
@@ -64,5 +64,7 @@ : $module.prev(), | ||
itemActivated = false, | ||
element = this, | ||
instance = $module.data(moduleNamespace), | ||
elementNamespace, | ||
id, | ||
observer, | ||
@@ -76,6 +78,15 @@ module | ||
module.debug('Initializing dropdown', settings); | ||
module.setup.layout(); | ||
if( module.is.alreadySetup() ) { | ||
module.error(error.alreadySetup); | ||
} | ||
else { | ||
module.setup.layout(); | ||
} | ||
module.save.defaults(); | ||
module.set.selected(); | ||
module.create.id(); | ||
if(hasTouch) { | ||
@@ -101,2 +112,3 @@ module.bind.touchEvents(); | ||
module.verbose('Destroying previous dropdown for', $module); | ||
module.remove.tabbable(); | ||
$module | ||
@@ -106,9 +118,21 @@ .off(eventNamespace) | ||
; | ||
$menu | ||
.off(eventNamespace) | ||
; | ||
$document | ||
.off(elementNamespace) | ||
; | ||
}, | ||
observeChanges: function() { | ||
if(MutationObserver !== undefined) { | ||
if('MutationObserver' in window) { | ||
observer = new MutationObserver(function(mutations) { | ||
module.debug('DOM tree modified, updating selector cache'); | ||
module.refresh(); | ||
if( module.is.selectMutation(mutations) ) { | ||
module.debug('<select> modified, recreating menu'); | ||
module.setup.select(); | ||
} | ||
else { | ||
module.debug('DOM tree modified, updating selector cache'); | ||
module.refresh(); | ||
} | ||
}); | ||
@@ -123,2 +147,23 @@ observer.observe(element, { | ||
create: { | ||
id: function() { | ||
module.verbose('Creating unique id for element'); | ||
id = module.get.uniqueID(); | ||
elementNamespace = '.' + id; | ||
} | ||
}, | ||
search: function() { | ||
var | ||
query | ||
; | ||
query = $search.val(); | ||
module.verbose('Searching for query', query); | ||
module.filter(query); | ||
if(module.is.searchSelection() && module.can.show() ) { | ||
module.show(); | ||
} | ||
}, | ||
setup: { | ||
@@ -137,23 +182,3 @@ | ||
if(settings.allowTab) { | ||
if( module.is.searchable() ) { | ||
module.debug('Searchable dropdown initialized'); | ||
$search | ||
.val('') | ||
.attr('tabindex', 0) | ||
; | ||
$menu | ||
.attr('tabindex', '-1') | ||
; | ||
} | ||
else { | ||
module.debug('Simple selection dropdown initialized'); | ||
if(!$module.attr('tabindex') ) { | ||
$module | ||
.attr('tabindex', 0) | ||
; | ||
$menu | ||
.attr('tabindex', '-1') | ||
; | ||
} | ||
} | ||
module.set.tabbable(); | ||
} | ||
@@ -163,20 +188,23 @@ }, | ||
var | ||
selectValues = module.get.selectValues() | ||
selectValues = module.get.selectValues() | ||
; | ||
module.debug('Dropdown initialized on a select', selectValues); | ||
// see if select exists inside a dropdown | ||
$input = $module; | ||
if($input.parents(selector.dropdown).size() > 0) { | ||
module.debug('Creating dropdown menu only from template'); | ||
if( $module.is('select') ) { | ||
$input = $module; | ||
} | ||
// see if select is placed correctly already | ||
if($input.parent(selector.dropdown).length > 0) { | ||
module.debug('UI dropdown already exists. Creating dropdown menu only'); | ||
$module = $input.closest(selector.dropdown); | ||
if($module.find('.' + className.dropdown).size() === 0) { | ||
$('<div />') | ||
$menu = $module.children(selector.menu); | ||
if($menu.length === 0) { | ||
$menu = $('<div />') | ||
.addClass(className.menu) | ||
.html( settings.templates.menu( selectValues )) | ||
.appendTo($module) | ||
; | ||
} | ||
$menu.html( settings.templates.menu( selectValues )); | ||
} | ||
else { | ||
module.debug('Creating entire dropdown from template'); | ||
module.debug('Creating entire dropdown from select'); | ||
$module = $('<div />') | ||
@@ -199,5 +227,10 @@ .attr('class', $input.attr('class') ) | ||
refresh: function() { | ||
module.verbose('Refreshing selector cache'); | ||
$text = $module.find(selector.text); | ||
$search = $module.find(selector.search); | ||
$input = $module.find(selector.input); | ||
$combo = ($module.prev().find(selector.text).length > 0) | ||
? $module.prev().find(selector.text) | ||
: $module.prev() | ||
; | ||
$menu = $module.children(selector.menu); | ||
@@ -217,5 +250,12 @@ $item = $menu.find(selector.item); | ||
show: function() { | ||
module.debug('Checking if dropdown can show'); | ||
if( !module.is.active() ) { | ||
show: function(callback) { | ||
callback = $.isFunction(callback) | ||
? callback | ||
: function(){} | ||
; | ||
if( module.is.searchSelection() && module.is.allFiltered() ) { | ||
return; | ||
} | ||
if( module.can.show() && !module.is.active() ) { | ||
module.debug('Showing dropdown'); | ||
module.animate.show(function() { | ||
@@ -226,15 +266,20 @@ if( module.can.click() ) { | ||
module.set.visible(); | ||
callback.call(element); | ||
}); | ||
$.proxy(settings.onShow, element)(); | ||
settings.onShow.call(element); | ||
} | ||
}, | ||
hide: function() { | ||
hide: function(callback) { | ||
callback = $.isFunction(callback) | ||
? callback | ||
: function(){} | ||
; | ||
if( module.is.active() ) { | ||
module.debug('Hiding dropdown'); | ||
module.animate.hide(function() { | ||
module.remove.filteredItem(); | ||
module.remove.visible(); | ||
callback.call(element); | ||
}); | ||
$.proxy(settings.onHide, element)(); | ||
settings.onHide.call(element); | ||
} | ||
@@ -254,10 +299,5 @@ }, | ||
var | ||
$subMenus = $menu.find(selector.menu), | ||
$activeSubMenu = $subMenus.has(selector.item + '.' + className.active) | ||
$subMenus = $menu.find(selector.menu) | ||
; | ||
$subMenus | ||
.not($activeSubMenu) | ||
.removeClass(className.visible) | ||
.removeAttr('style') | ||
; | ||
$subMenus.transition('hide'); | ||
}, | ||
@@ -278,4 +318,7 @@ | ||
touchEvents: function() { | ||
module.debug('Touch device detected binding touch events'); | ||
if( !module.is.searchSelection() ) { | ||
module.debug('Touch device detected binding additional touch events'); | ||
if( module.is.searchSelection() ) { | ||
// do nothing special yet | ||
} | ||
else { | ||
$module | ||
@@ -285,5 +328,4 @@ .on('touchstart' + eventNamespace, module.event.test.toggle) | ||
} | ||
$module | ||
$menu | ||
.on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter) | ||
.on('touchstart' + eventNamespace, selector.item, module.event.item.click) | ||
; | ||
@@ -295,4 +337,8 @@ }, | ||
$module | ||
.on('focus' + eventNamespace, selector.search, module.event.searchFocus) | ||
.on('blur' + eventNamespace, selector.search, module.event.searchBlur) | ||
.on('mousedown' + eventNamespace, selector.menu, module.event.menu.activate) | ||
.on('mouseup' + eventNamespace, selector.menu, module.event.menu.deactivate) | ||
.on('click' + eventNamespace, selector.search, module.show) | ||
.on('focus' + eventNamespace, selector.search, module.event.searchFocus) | ||
.on('blur' + eventNamespace, selector.search, module.event.searchBlur) | ||
.on('click' + eventNamespace, selector.text, module.event.searchTextFocus) | ||
; | ||
@@ -318,11 +364,9 @@ } | ||
$module | ||
.on('mousedown', module.event.mousedown) | ||
.on('mouseup', module.event.mouseup) | ||
.on('focus' + eventNamespace, module.event.focus) | ||
.on('blur' + eventNamespace, module.event.blur) | ||
.on('mousedown' + eventNamespace, module.event.mousedown) | ||
.on('mouseup' + eventNamespace, module.event.mouseup) | ||
.on('focus' + eventNamespace, module.event.focus) | ||
.on('blur' + eventNamespace, module.event.blur) | ||
; | ||
} | ||
$module | ||
.on('mousedown' + eventNamespace, selector.item, module.event.item.mousedown) | ||
.on('mouseup' + eventNamespace, selector.item, module.event.item.mouseup) | ||
$menu | ||
.on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter) | ||
@@ -337,8 +381,8 @@ .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave) | ||
$document | ||
.on('touchstart' + eventNamespace, module.event.test.touch) | ||
.on('touchmove' + eventNamespace, module.event.test.touch) | ||
.on('touchstart' + elementNamespace, module.event.test.touch) | ||
.on('touchmove' + elementNamespace, module.event.test.touch) | ||
; | ||
} | ||
$document | ||
.on('click' + eventNamespace, module.event.test.hide) | ||
.on('click' + elementNamespace, module.event.test.hide) | ||
; | ||
@@ -353,8 +397,8 @@ } | ||
$document | ||
.off('touchstart' + eventNamespace) | ||
.off('touchmove' + eventNamespace) | ||
.off('touchstart' + elementNamespace) | ||
.off('touchmove' + elementNamespace) | ||
; | ||
} | ||
$document | ||
.off('click' + eventNamespace) | ||
.off('click' + elementNamespace) | ||
; | ||
@@ -367,6 +411,8 @@ } | ||
$results = $(), | ||
exactRegExp = new RegExp('(?:\s|^)' + searchTerm, 'i'), | ||
fullTextRegExp = new RegExp(searchTerm, 'i'), | ||
$filteredItems | ||
escapedTerm = module.escape.regExp(searchTerm), | ||
exactRegExp = new RegExp('^' + escapedTerm, 'igm'), | ||
fullTextRegExp = new RegExp(escapedTerm, 'ig'), | ||
allItemsFiltered | ||
; | ||
module.verbose('Searching for matching values'); | ||
$item | ||
@@ -376,18 +422,10 @@ .each(function(){ | ||
$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 = String(module.get.choiceText($choice, false)), | ||
value = String(module.get.choiceValue($choice, text)) | ||
; | ||
if( exactRegExp.test( text ) || exactRegExp.test( value ) ) { | ||
if( text.match(exactRegExp) || value.match(exactRegExp) ) { | ||
$results = $results.add($choice); | ||
} | ||
else if(settings.fullTextSearch) { | ||
if( fullTextRegExp.test( text ) || fullTextRegExp.test( value ) ) { | ||
if( text.match(fullTextRegExp) || value.match(fullTextRegExp) ) { | ||
$results = $results.add($choice); | ||
@@ -398,8 +436,12 @@ } | ||
; | ||
$filteredItems = $item.not($results); | ||
module.debug('Setting filter', searchTerm); | ||
module.remove.filteredItem(); | ||
module.remove.selectedItem(); | ||
$filteredItems | ||
$item | ||
.not($results) | ||
.addClass(className.filtered) | ||
; | ||
module.verbose('Selecting first non-filtered element'); | ||
module.remove.selectedItem(); | ||
$item | ||
@@ -410,4 +452,33 @@ .not('.' + className.filtered) | ||
; | ||
if( module.is.allFiltered() ) { | ||
module.debug('All items filtered, hiding dropdown', searchTerm); | ||
if(module.is.searchSelection()) { | ||
module.hide(); | ||
} | ||
settings.onNoResults.call(element, searchTerm); | ||
} | ||
}, | ||
focusSearch: function() { | ||
if( module.is.search() ) { | ||
$search | ||
.focus() | ||
; | ||
} | ||
}, | ||
forceSelection: function() { | ||
var | ||
$currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0), | ||
$activeItem = $item.filter('.' + className.active).eq(0), | ||
$selectedItem = ($currentlySelected.length > 0) | ||
? $currentlySelected | ||
: $activeItem, | ||
hasSelected = ($selectedItem.size() > 0) | ||
; | ||
if(hasSelected) { | ||
module.event.item.click.call($selectedItem); | ||
} | ||
}, | ||
event: { | ||
@@ -422,3 +493,3 @@ // prevents focus callback from occuring on mousedown | ||
focus: function() { | ||
if(!activated) { | ||
if(!activated && module.is.hidden()) { | ||
module.show(); | ||
@@ -428,3 +499,6 @@ } | ||
blur: function(event) { | ||
if(!activated) { | ||
var | ||
pageLostFocus = (document.activeElement === this) | ||
; | ||
if(!activated && !pageLostFocus) { | ||
module.hide(); | ||
@@ -438,69 +512,114 @@ } | ||
searchBlur: function(event) { | ||
if(!itemActivated) { | ||
module.hide(); | ||
var | ||
pageLostFocus = (document.activeElement === this) | ||
; | ||
if(!itemActivated && !pageLostFocus) { | ||
if(settings.forceSelection) { | ||
module.forceSelection(); | ||
} | ||
else { | ||
module.hide(); | ||
} | ||
} | ||
}, | ||
searchTextFocus: function(event) { | ||
activated = true; | ||
$search.focus(); | ||
}, | ||
input: function(event) { | ||
var | ||
query = $search.val() | ||
; | ||
if(module.is.searchSelection()) { | ||
$text.addClass(className.filtered); | ||
module.set.filtered(); | ||
} | ||
module.filter(query); | ||
clearTimeout(module.timer); | ||
module.timer = setTimeout(module.search, settings.delay.search); | ||
}, | ||
keydown: function(event) { | ||
var | ||
$selectedItem = $item.not(className.filtered).filter('.' + className.selected).eq(0), | ||
$visibleItems = $item.not('.' + className.filtered), | ||
$currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0), | ||
$activeItem = $menu.children('.' + className.active).eq(0), | ||
$selectedItem = ($currentlySelected.length > 0) | ||
? $currentlySelected | ||
: $activeItem, | ||
$visibleItems = ($selectedItem.length > 0) | ||
? $selectedItem.siblings(':not(.' + className.filtered +')').andSelf() | ||
: $menu.children(':not(.' + className.filtered +')'), | ||
$subMenu = $selectedItem.children(selector.menu), | ||
$parentMenu = $selectedItem.closest(selector.menu), | ||
isSubMenuItem = $parentMenu[0] !== $menu[0], | ||
inVisibleMenu = $parentMenu.is(':visible'), | ||
pressedKey = event.which, | ||
keys = { | ||
enter : 13, | ||
escape : 27, | ||
upArrow : 38, | ||
downArrow : 40 | ||
enter : 13, | ||
escape : 27, | ||
leftArrow : 37, | ||
upArrow : 38, | ||
rightArrow : 39, | ||
downArrow : 40 | ||
}, | ||
selectedClass = className.selected, | ||
currentIndex = $visibleItems.index( $selectedItem ), | ||
hasSelectedItem = ($selectedItem.size() > 0), | ||
hasSubMenu = ($subMenu.length> 0), | ||
hasSelectedItem = ($selectedItem.length > 0), | ||
lastVisibleIndex = ($visibleItems.size() - 1), | ||
$nextItem, | ||
newIndex | ||
; | ||
// default to activated choice if no selection present | ||
if(!hasSelectedItem) { | ||
$selectedItem = $item.filter('.' + className.active).eq(0); | ||
hasSelectedItem = ($selectedItem.size() > 0); | ||
} | ||
// close shortcuts | ||
if(pressedKey == keys.escape) { | ||
module.verbose('Escape key pressed, closing dropdown'); | ||
$search.blur(); | ||
module.hide(); | ||
} | ||
// result shortcuts | ||
// visible menu keyboard shortcuts | ||
if(module.is.visible()) { | ||
// enter (select or sub-menu) | ||
if(pressedKey == keys.enter && hasSelectedItem) { | ||
module.verbose('Enter key pressed, choosing selected item'); | ||
if(module.is.searchable()) { | ||
module.verbose('Removing focus from search input'); | ||
$search.blur(); | ||
if(hasSubMenu && !settings.allowCategorySelection) { | ||
module.verbose('Pressed enter on unselectable category, opening sub menu'); | ||
pressedKey = keys.rightArrow; | ||
} | ||
$.proxy(module.event.item.click, $selectedItem)(event); | ||
else { | ||
module.verbose('Enter key pressed, choosing selected item'); | ||
module.event.item.click.call($selectedItem, event); | ||
} | ||
} | ||
// left arrow (hide sub-menu) | ||
if(pressedKey == keys.leftArrow) { | ||
if(isSubMenuItem) { | ||
module.verbose('Left key pressed, closing sub-menu'); | ||
module.animate.hide(false, $parentMenu); | ||
$selectedItem | ||
.removeClass(className.selected) | ||
; | ||
$parentMenu | ||
.closest(selector.item) | ||
.addClass(className.selected) | ||
; | ||
} | ||
event.preventDefault(); | ||
return false; | ||
} | ||
else if(pressedKey == keys.upArrow) { | ||
if(!hasSelectedItem) { | ||
$nextItem = $visibleItems.eq(0); | ||
// right arrow (show sub-menu) | ||
if(pressedKey == keys.rightArrow) { | ||
if(hasSubMenu) { | ||
module.verbose('Right key pressed, opening sub-menu'); | ||
module.animate.show(false, $subMenu); | ||
$selectedItem | ||
.removeClass(className.selected) | ||
; | ||
$subMenu | ||
.find(selector.item).eq(0) | ||
.addClass(className.selected) | ||
; | ||
} | ||
event.preventDefault(); | ||
} | ||
// up arrow (traverse menu up) | ||
if(pressedKey == keys.upArrow) { | ||
$nextItem = (hasSelectedItem && inVisibleMenu) | ||
? $selectedItem.prevAll(selector.item + ':not(.' + className.filtered + ')').eq(0) | ||
: $item.eq(0) | ||
; | ||
if($visibleItems.index( $nextItem ) < 0) { | ||
module.verbose('Up key pressed but reached top of current menu'); | ||
return; | ||
} | ||
else { | ||
$nextItem = $selectedItem.prevAll(selector.item + ':not(.' + className.filtered + ')').eq(0); | ||
} | ||
if(currentIndex !== 0) { | ||
module.verbose('Up key pressed, changing active item'); | ||
$item | ||
.removeClass(selectedClass) | ||
$selectedItem | ||
.removeClass(className.selected) | ||
; | ||
$nextItem | ||
.addClass(selectedClass) | ||
.addClass(className.selected) | ||
; | ||
@@ -511,16 +630,19 @@ module.set.scrollPosition($nextItem); | ||
} | ||
else if(pressedKey == keys.downArrow) { | ||
if(!hasSelectedItem) { | ||
$nextItem = $visibleItems.eq(0); | ||
// down arrow (traverse menu down) | ||
if(pressedKey == keys.downArrow) { | ||
$nextItem = (hasSelectedItem && inVisibleMenu) | ||
? $nextItem = $selectedItem.nextAll(selector.item + ':not(.' + className.filtered + ')').eq(0) | ||
: $item.eq(0) | ||
; | ||
if($nextItem.length === 0) { | ||
module.verbose('Down key pressed but reached bottom of current menu'); | ||
return; | ||
} | ||
else { | ||
$nextItem = $selectedItem.nextAll(selector.item + ':not(.' + className.filtered + ')').eq(0); | ||
} | ||
if(currentIndex + 1 < $visibleItems.size() ) { | ||
module.verbose('Down key pressed, changing active item'); | ||
$item | ||
.removeClass(selectedClass) | ||
.removeClass(className.selected) | ||
; | ||
$nextItem | ||
.addClass(selectedClass) | ||
.addClass(className.selected) | ||
; | ||
@@ -533,5 +655,17 @@ module.set.scrollPosition($nextItem); | ||
else { | ||
// enter (open menu) | ||
if(pressedKey == keys.enter) { | ||
module.verbose('Enter key pressed, showing dropdown'); | ||
module.show(); | ||
} | ||
// escape (close menu) | ||
if(pressedKey == keys.escape) { | ||
module.verbose('Escape key pressed, closing dropdown'); | ||
module.hide(); | ||
} | ||
// down arrow (open menu) | ||
if(pressedKey == keys.downArrow) { | ||
module.verbose('Down key pressed, showing dropdown'); | ||
module.show(); | ||
} | ||
} | ||
@@ -561,75 +695,64 @@ }, | ||
item: { | ||
mousedown: function() { | ||
menu: { | ||
activate: function() { | ||
itemActivated = true; | ||
}, | ||
mouseup: function() { | ||
deactivate: function() { | ||
itemActivated = false; | ||
}, | ||
} | ||
}, | ||
item: { | ||
mouseenter: function(event) { | ||
var | ||
$currentMenu = $(this).find(selector.menu), | ||
$otherMenus = $(this).siblings(selector.item).children(selector.menu) | ||
$subMenu = $(this).children(selector.menu), | ||
$otherMenus = $(this).siblings(selector.item).children(selector.menu) | ||
; | ||
if( $currentMenu.size() > 0 ) { | ||
if( $subMenu.length > 0 ) { | ||
clearTimeout(module.itemTimer); | ||
module.itemTimer = setTimeout(function() { | ||
module.animate.hide(false, $otherMenus); | ||
module.verbose('Showing sub-menu', $currentMenu); | ||
module.animate.show(false, $currentMenu); | ||
}, settings.delay.show * 2); | ||
module.verbose('Showing sub-menu', $subMenu); | ||
$.each($otherMenus, function() { | ||
module.animate.hide(false, $(this)); | ||
}); | ||
module.animate.show(false, $subMenu); | ||
}, settings.delay.show); | ||
event.preventDefault(); | ||
} | ||
}, | ||
mouseleave: function(event) { | ||
var | ||
$currentMenu = $(this).find(selector.menu) | ||
$subMenu = $(this).children(selector.menu) | ||
; | ||
if($currentMenu.size() > 0) { | ||
if($subMenu.length > 0) { | ||
clearTimeout(module.itemTimer); | ||
module.itemTimer = setTimeout(function() { | ||
module.verbose('Hiding sub-menu', $currentMenu); | ||
module.animate.hide(false, $currentMenu); | ||
module.verbose('Hiding sub-menu', $subMenu); | ||
module.animate.hide(false, $subMenu); | ||
}, settings.delay.hide); | ||
} | ||
}, | ||
click: function (event) { | ||
var | ||
$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, | ||
$choice = $(this), | ||
$target = (event) | ||
? $(event.target) | ||
: $(''), | ||
$subMenu = $choice.find(selector.menu), | ||
text = module.get.choiceText($choice), | ||
value = module.get.choiceValue($choice, text), | ||
callback = function() { | ||
$search.val(''); | ||
module.remove.searchTerm(); | ||
module.determine.selectAction(text, value); | ||
$.proxy(settings.onChange, element)(value, text, $choice); | ||
}, | ||
openingSubMenu = ($choice.find(selector.menu).size() > 0) | ||
hasSubMenu = ($subMenu.length > 0), | ||
isBubbledEvent = ($subMenu.find($target).length > 0) | ||
; | ||
if( !openingSubMenu ) { | ||
if(event.type == 'touchstart') { | ||
$choice.one('click', callback); | ||
} | ||
else { | ||
callback(); | ||
} | ||
if(!isBubbledEvent && (!hasSubMenu || settings.allowCategorySelection)) { | ||
callback(); | ||
} | ||
} | ||
}, | ||
resetStyle: function() { | ||
$(this).removeAttr('style'); | ||
} | ||
}, | ||
@@ -653,4 +776,7 @@ | ||
eventInModule: function(event, callback) { | ||
callback = callback || function(){}; | ||
if( $(event.target).closest($module).size() === 0 ) { | ||
callback = $.isFunction(callback) | ||
? callback | ||
: function(){} | ||
; | ||
if( $(event.target).closest($module).length === 0 ) { | ||
module.verbose('Triggering event', callback); | ||
@@ -666,4 +792,7 @@ callback(); | ||
eventInMenu: function(event, callback) { | ||
callback = callback || function(){}; | ||
if( $(event.target).closest($menu).size() === 0 ) { | ||
callback = $.isFunction(callback) | ||
? callback | ||
: function(){} | ||
; | ||
if( $(event.target).closest($menu).length === 0 ) { | ||
module.verbose('Triggering event', callback); | ||
@@ -684,7 +813,3 @@ callback(); | ||
hide: function() { | ||
module.hide(); | ||
}, | ||
select: function(text, value) { | ||
activate: function(text, value) { | ||
value = (value !== undefined) | ||
@@ -695,7 +820,8 @@ ? value | ||
module.set.selected(value); | ||
module.set.value(value); | ||
module.hide(); | ||
module.hide(function() { | ||
module.remove.filteredItem(); | ||
}); | ||
}, | ||
activate: function(text, value) { | ||
select: function(text, value) { | ||
value = (value !== undefined) | ||
@@ -706,4 +832,5 @@ ? value | ||
module.set.selected(value); | ||
module.set.value(value); | ||
module.hide(); | ||
module.hide(function() { | ||
module.remove.filteredItem(); | ||
}); | ||
}, | ||
@@ -717,4 +844,11 @@ | ||
module.set.selected(value); | ||
module.set.value(value); | ||
module.hide(); | ||
module.hide(function() { | ||
module.remove.filteredItem(); | ||
}); | ||
}, | ||
hide: function() { | ||
module.hide(function() { | ||
module.remove.filteredItem(); | ||
}); | ||
} | ||
@@ -729,3 +863,3 @@ | ||
value: function() { | ||
return ($input.size() > 0) | ||
return ($input.length > 0) | ||
? $input.val() | ||
@@ -735,2 +869,31 @@ : $module.data(metadata.value) | ||
}, | ||
choiceText: function($choice, preserveHTML) { | ||
preserveHTML = (preserveHTML !== undefined) | ||
? preserveHTML | ||
: settings.preserveHTML | ||
; | ||
if($choice !== undefined) { | ||
if($choice.find(selector.menu).length > 0) { | ||
module.verbose('Retreiving text of element with sub-menu'); | ||
$choice = $choice.clone(); | ||
$choice.find(selector.menu).remove(); | ||
$choice.find(selector.menuIcon).remove(); | ||
} | ||
return ($choice.data(metadata.text) !== undefined) | ||
? $choice.data(metadata.text) | ||
: (preserveHTML) | ||
? $choice.html().trim() | ||
: $choice.text().trim() | ||
; | ||
} | ||
}, | ||
choiceValue: function($choice, choiceText) { | ||
choiceText = choiceText || module.get.choiceText($choice); | ||
return ($choice.data(metadata.value) !== undefined) | ||
? $choice.data(metadata.value) | ||
: (typeof choiceText === 'string') | ||
? choiceText.toLowerCase().trim() | ||
: choiceText.trim() | ||
; | ||
}, | ||
inputEvent: function() { | ||
@@ -752,6 +915,8 @@ var | ||
var | ||
select = { | ||
values : {} | ||
} | ||
select = {} | ||
; | ||
select.values = (settings.sortSelect) | ||
? {} // properties will be sorted in object when re-accessed | ||
: [] // properties will keep original order in array | ||
; | ||
$module | ||
@@ -770,9 +935,28 @@ .find('option') | ||
else { | ||
select.values[value] = name; | ||
if(settings.sortSelect) { | ||
select.values[value] = { | ||
name : name, | ||
value : value | ||
}; | ||
} | ||
else { | ||
select.values.push({ | ||
name: name, | ||
value: value | ||
}); | ||
} | ||
} | ||
}) | ||
; | ||
module.debug('Retrieved values from select', select); | ||
if(settings.sortSelect) { | ||
module.debug('Retrieved and sorted values from select', select); | ||
} | ||
else { | ||
module.debug('Retreived values from select', select); | ||
} | ||
return select; | ||
}, | ||
activeItem: function() { | ||
return $item.filter('.' + className.active); | ||
}, | ||
item: function(value, strict) { | ||
@@ -797,15 +981,7 @@ var | ||
$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) { | ||
module.debug('Ambiguous dropdown value using strict type check', value); | ||
module.verbose('Ambiguous dropdown value using strict type check', $choice, value); | ||
if( optionValue === value ) { | ||
@@ -835,2 +1011,5 @@ $selectedItem = $(this); | ||
return $selectedItem || false; | ||
}, | ||
uniqueID: function() { | ||
return (Math.random().toString(16) + '000000000').substr(2,8); | ||
} | ||
@@ -850,2 +1029,3 @@ }, | ||
module.set.text(defaultText); | ||
$text.addClass(className.placeholder); | ||
}, | ||
@@ -858,4 +1038,9 @@ defaultValue: function() { | ||
module.debug('Restoring default value', defaultValue); | ||
module.set.selected(defaultValue); | ||
module.set.value(defaultValue); | ||
if(defaultValue.length) { | ||
module.set.selected(defaultValue); | ||
} | ||
else { | ||
module.remove.activeItem(); | ||
module.remove.selectedItem(); | ||
} | ||
} | ||
@@ -868,2 +1053,3 @@ } | ||
module.save.defaultText(); | ||
module.save.placeholderText(); | ||
module.save.defaultValue(); | ||
@@ -876,11 +1062,61 @@ }, | ||
$module.data(metadata.defaultText, $text.text() ); | ||
}, | ||
placeholderText: function() { | ||
if($text.hasClass(className.placeholder)) { | ||
$module.data(metadata.placeholderText, $text.text()); | ||
} | ||
} | ||
}, | ||
clear: function() { | ||
var | ||
placeholderText = $module.data(metadata.placeholderText) | ||
; | ||
module.set.text(placeholderText); | ||
module.set.value(''); | ||
module.remove.activeItem(); | ||
module.remove.selectedItem(); | ||
$text.addClass(className.placeholder); | ||
}, | ||
set: { | ||
scrollPosition: function($item) { | ||
filtered: function() { | ||
var | ||
$item = $item || module.get.item(), | ||
hasActive = ($item && $item.size() > 0), | ||
searchValue = $search.val(), | ||
hasSearchValue = (typeof searchValue === 'string' && searchValue.length > 0) | ||
; | ||
if(hasSearchValue) { | ||
$text.addClass(className.filtered); | ||
} | ||
else { | ||
$text.removeClass(className.filtered); | ||
} | ||
}, | ||
tabbable: function() { | ||
if( module.is.searchable() ) { | ||
module.debug('Searchable dropdown initialized'); | ||
$search | ||
.val('') | ||
.attr('tabindex', 0) | ||
; | ||
$menu | ||
.attr('tabindex', '-1') | ||
; | ||
} | ||
else { | ||
module.debug('Simple selection dropdown initialized'); | ||
if(!$module.attr('tabindex') ) { | ||
$module | ||
.attr('tabindex', 0) | ||
; | ||
$menu | ||
.attr('tabindex', '-1') | ||
; | ||
} | ||
} | ||
}, | ||
scrollPosition: function($item, forceScroll) { | ||
var | ||
edgeTolerance = 5, | ||
hasActive, | ||
offset, | ||
@@ -895,3 +1131,16 @@ itemHeight, | ||
; | ||
$item = $item || module.get.activeItem(); | ||
hasActive = ($item && $item.length > 0); | ||
forceScroll = (forceScroll !== undefined) | ||
? forceScroll | ||
: false | ||
; | ||
if($item && hasActive) { | ||
if(!$menu.hasClass(className.visible)) { | ||
$menu.addClass(className.loading); | ||
} | ||
menuHeight = $menu.height(); | ||
@@ -905,6 +1154,7 @@ itemHeight = $item.height(); | ||
abovePage = ((offset - edgeTolerance) < menuScroll); | ||
if(abovePage || belowPage) { | ||
module.debug('Scrolling to active item'); | ||
module.debug('Scrolling to active item', offset); | ||
if(abovePage || belowPage || forceScroll) { | ||
$menu | ||
.scrollTop(offset) | ||
.removeClass(className.loading) | ||
; | ||
@@ -940,3 +1190,3 @@ } | ||
module.debug('Adding selected value to hidden input', value, $input); | ||
if($input.size() > 0) { | ||
if($input.length > 0) { | ||
$input | ||
@@ -962,12 +1212,7 @@ .val(value) | ||
$selectedItem = module.get.item(value), | ||
selectedText | ||
selectedText, | ||
selectedValue | ||
; | ||
if($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(); | ||
@@ -979,3 +1224,7 @@ module.remove.selectedItem(); | ||
; | ||
selectedText = module.get.choiceText($selectedItem); | ||
selectedValue = module.get.choiceValue($selectedItem, selectedText); | ||
module.set.text(selectedText); | ||
module.set.value(selectedValue); | ||
settings.onChange.call(element, value, selectedText, $selectedItem); | ||
} | ||
@@ -998,4 +1247,27 @@ } | ||
}, | ||
searchTerm: function() { | ||
$search.val(''); | ||
}, | ||
selectedItem: function() { | ||
$item.removeClass(className.selected); | ||
}, | ||
tabbable: function() { | ||
if( module.is.searchable() ) { | ||
module.debug('Searchable dropdown initialized'); | ||
$search | ||
.attr('tabindex', '-1') | ||
; | ||
$menu | ||
.attr('tabindex', '-1') | ||
; | ||
} | ||
else { | ||
module.debug('Simple selection dropdown initialized'); | ||
$module | ||
.attr('tabindex', '-1') | ||
; | ||
$menu | ||
.attr('tabindex', '-1') | ||
; | ||
} | ||
} | ||
@@ -1005,2 +1277,35 @@ }, | ||
is: { | ||
active: function() { | ||
return $module.hasClass(className.active); | ||
}, | ||
alreadySetup: function() { | ||
return ($module.is('select') && $module.parent(selector.dropdown).length > 0); | ||
}, | ||
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() { | ||
return ($item.filter('.' + className.filtered).length === $item.length); | ||
}, | ||
hidden: function($subMenu) { | ||
return ($subMenu) | ||
? $subMenu.is(':hidden') | ||
: $menu.is(':hidden') | ||
; | ||
}, | ||
selectMutation: function(mutations) { | ||
var | ||
selectChanged = false | ||
; | ||
$.each(mutations, function(index, mutation) { | ||
if(mutation.target && $(mutation.target).is('select')) { | ||
selectChanged = true; | ||
return true; | ||
} | ||
}); | ||
return selectChanged; | ||
}, | ||
search: function() { | ||
@@ -1010,3 +1315,3 @@ return $module.hasClass(className.search); | ||
searchable: function() { | ||
return ($search.size() > 0); | ||
return ($search.length > 0); | ||
}, | ||
@@ -1019,11 +1324,5 @@ searchSelection: function() { | ||
}, | ||
animated: function($subMenu) { | ||
return ($subMenu) | ||
? $subMenu.is(':animated') || $subMenu.transition && $subMenu.transition('is animating') | ||
: $menu.is(':animated') || $menu.transition && $menu.transition('is animating') | ||
; | ||
upward: function() { | ||
return $module.hasClass(className.upward); | ||
}, | ||
active: function() { | ||
return $module.hasClass(className.active); | ||
}, | ||
visible: function($subMenu) { | ||
@@ -1034,8 +1333,2 @@ return ($subMenu) | ||
; | ||
}, | ||
hidden: function($subMenu) { | ||
return ($subMenu) | ||
? $subMenu.is(':hidden') | ||
: $menu.is(':hidden') | ||
; | ||
} | ||
@@ -1060,12 +1353,24 @@ }, | ||
: function() { | ||
module.hideSubMenus(); | ||
module.hideOthers(); | ||
module.set.active(); | ||
module.set.scrollPosition(); | ||
} | ||
; | ||
callback = callback || function(){}; | ||
callback = $.isFunction(callback) | ||
? callback | ||
: function(){} | ||
; | ||
module.set.scrollPosition(module.get.activeItem(), true); | ||
module.verbose('Doing menu show animation', $currentMenu); | ||
if( module.is.hidden($currentMenu) ) { | ||
if( module.is.hidden($currentMenu) || module.is.animating($currentMenu) ) { | ||
if(settings.transition == 'auto') { | ||
settings.transition = module.is.upward() | ||
? 'slide up' | ||
: 'slide down' | ||
; | ||
module.verbose('Automatically determining animation based on animation direction', settings.transition); | ||
} | ||
if(settings.transition == 'none') { | ||
$.proxy(callback, element)(); | ||
callback.call(element); | ||
} | ||
@@ -1075,8 +1380,10 @@ else if($.fn.transition !== undefined && $module.transition('is supported')) { | ||
.transition({ | ||
animation : settings.transition + ' in', | ||
duration : settings.duration, | ||
queue : true, | ||
start : start, | ||
complete : function() { | ||
$.proxy(callback, element)(); | ||
animation : settings.transition + ' in', | ||
debug : settings.debug, | ||
verbose : settings.verbose, | ||
duration : settings.duration, | ||
queue : true, | ||
onStart : start, | ||
onComplete : function() { | ||
callback.call(element); | ||
} | ||
@@ -1100,4 +1407,4 @@ }) | ||
.slideDown(100, 'easeOutQuad', function() { | ||
$.proxy(module.event.resetStyle, this)(); | ||
$.proxy(callback, element)(); | ||
module.event.resetStyle.call(this); | ||
callback.call(element); | ||
}) | ||
@@ -1112,4 +1419,4 @@ ; | ||
.fadeIn(settings.duration, function() { | ||
$.proxy(module.event.resetStyle, this)(); | ||
$.proxy(callback, element)(); | ||
module.event.resetStyle.call(this); | ||
callback.call(element); | ||
}) | ||
@@ -1126,2 +1433,5 @@ ; | ||
$currentMenu = $subMenu || $menu, | ||
duration = ($subMenu) | ||
? (settings.duration * 0.9) | ||
: settings.duration, | ||
start = ($subMenu) | ||
@@ -1133,12 +1443,24 @@ ? function() {} | ||
} | ||
module.hideSubMenus(); | ||
module.focusSearch(); | ||
module.remove.active(); | ||
} | ||
; | ||
callback = callback || function(){}; | ||
if( module.is.visible($currentMenu) ) { | ||
callback = $.isFunction(callback) | ||
? callback | ||
: function(){} | ||
; | ||
if( module.is.visible($currentMenu) || module.is.animating($currentMenu) ) { | ||
module.verbose('Doing menu hide animation', $currentMenu); | ||
if(settings.transition == 'auto') { | ||
settings.transition = module.is.upward() | ||
? 'slide up' | ||
: 'slide down' | ||
; | ||
} | ||
$input.trigger('blur'); | ||
if(settings.transition == 'none') { | ||
$.proxy(callback, element)(); | ||
callback.call(element); | ||
} | ||
@@ -1148,8 +1470,10 @@ else if($.fn.transition !== undefined && $module.transition('is supported')) { | ||
.transition({ | ||
animation : settings.transition + ' out', | ||
duration : settings.duration, | ||
queue : true, | ||
start : start, | ||
complete : function() { | ||
$.proxy(callback, element)(); | ||
animation : settings.transition + ' out', | ||
duration : settings.duration, | ||
debug : settings.debug, | ||
verbose : settings.verbose, | ||
queue : true, | ||
onStart : start, | ||
onComplete : function() { | ||
callback.call(element); | ||
} | ||
@@ -1173,4 +1497,4 @@ }) | ||
.slideUp(100, 'easeOutQuad', function() { | ||
$.proxy(module.event.resetStyle, this)(); | ||
$.proxy(callback, element)(); | ||
module.event.resetStyle.call(this); | ||
callback.call(element); | ||
}) | ||
@@ -1185,4 +1509,4 @@ ; | ||
.fadeOut(150, function() { | ||
$.proxy(module.event.resetStyle, this)(); | ||
$.proxy(callback, element)(); | ||
module.event.resetStyle.call(this); | ||
callback.call(element); | ||
}) | ||
@@ -1211,2 +1535,9 @@ ; | ||
escape: { | ||
regExp: function(text) { | ||
text = String(text); | ||
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); | ||
} | ||
}, | ||
setting: function(name, value) { | ||
@@ -1376,3 +1707,3 @@ module.debug('Changing setting', name, value); | ||
if(instance !== undefined) { | ||
module.destroy(); | ||
instance.invoke('destroy'); | ||
} | ||
@@ -1392,28 +1723,34 @@ module.initialize(); | ||
debug : false, | ||
verbose : true, | ||
performance : true, | ||
debug : false, | ||
verbose : true, | ||
performance : true, | ||
on : 'click', | ||
action : 'activate', | ||
on : 'click', | ||
action : 'activate', | ||
allowTab : true, | ||
fullTextSearch : true, | ||
preserveHTML : true, | ||
allowTab : true, | ||
fullTextSearch : false, | ||
preserveHTML : true, | ||
sortSelect : false, | ||
delay : { | ||
show : 200, | ||
hide : 300, | ||
touch : 50 | ||
allowCategorySelection : false, | ||
delay : { | ||
hide : 300, | ||
show : 200, | ||
search : 50, | ||
touch : 50 | ||
}, | ||
transition : 'slide down', | ||
forceSelection: true, | ||
transition : 'auto', | ||
duration : 250, | ||
/* Callbacks */ | ||
onNoResults : function(searchTerm){}, | ||
onChange : function(value, text){}, | ||
onShow : function(){}, | ||
onHide : function(){}, | ||
onChange : function(value, text){}, | ||
onShow : function(){}, | ||
onHide : function(){}, | ||
/* Component */ | ||
@@ -1425,12 +1762,14 @@ | ||
error : { | ||
action : 'You called a dropdown action that was not defined', | ||
method : 'The method you called is not defined.', | ||
transition : 'The requested transition was not found' | ||
action : 'You called a dropdown action that was not defined', | ||
alreadySetup : 'Once a select has been initialized behaviors must be called on the created ui dropdown', | ||
method : 'The method you called is not defined.', | ||
transition : 'The requested transition was not found' | ||
}, | ||
metadata: { | ||
defaultText : 'defaultText', | ||
defaultValue : 'defaultValue', | ||
text : 'text', | ||
value : 'value' | ||
defaultText : 'defaultText', | ||
defaultValue : 'defaultValue', | ||
placeholderText : 'placeholderText', | ||
text : 'text', | ||
value : 'value' | ||
}, | ||
@@ -1440,7 +1779,8 @@ | ||
dropdown : '.ui.dropdown', | ||
text : '> .text:not(.icon)', | ||
input : '> input[type="hidden"], > select', | ||
search : '> .search, .menu > .search > input, .menu > input.search', | ||
item : '.item', | ||
menu : '.menu', | ||
item : '.item' | ||
menuIcon : '.dropdown.icon', | ||
search : '> input.search, .menu > .search > input, .menu > input.search', | ||
text : '> .text:not(.icon)' | ||
}, | ||
@@ -1454,2 +1794,3 @@ | ||
filtered : 'filtered', | ||
loading : 'loading', | ||
menu : 'menu', | ||
@@ -1460,2 +1801,3 @@ placeholder : 'default', | ||
selection : 'selection', | ||
upward : 'upward', | ||
visible : 'visible' | ||
@@ -1474,9 +1816,4 @@ } | ||
; | ||
$.each(select.values, function(value, name) { | ||
if(value === name) { | ||
html += '<div class="item">' + name + '</div>'; | ||
} | ||
else { | ||
html += '<div class="item" data-value="' + value + '">' + name + '</div>'; | ||
} | ||
$.each(select.values, function(index, option) { | ||
html += '<div class="item" data-value="' + option.value + '">' + option.name + '</div>'; | ||
}); | ||
@@ -1499,9 +1836,4 @@ return html; | ||
html += '<div class="menu">'; | ||
$.each(select.values, function(value, name) { | ||
if(value === name) { | ||
html += '<div class="item">' + name + '</div>'; | ||
} | ||
else { | ||
html += '<div class="item" data-value="' + value + '">' + name + '</div>'; | ||
} | ||
$.each(select.values, function(index, option) { | ||
html += '<div class="item" data-value="' + option.value + '">' + option.name + '</div>'; | ||
}); | ||
@@ -1522,2 +1854,2 @@ html += '</div>'; | ||
})( jQuery, window , document ); | ||
})( jQuery, window , document ); |
/* | ||
* # Semantic UI | ||
* # Semantic UI - 1.9.0 | ||
* https://github.com/Semantic-Org/Semantic-UI | ||
* http://beta.semantic-ui.com/ | ||
* http://www.semantic-ui.com/ | ||
* | ||
@@ -11,2 +11,2 @@ * Copyright 2014 Contributors | ||
*/ | ||
!function(e,t,n,i){"use strict";e.fn.dropdown=function(t){var o,s=e(this),a=e(n),r=s.selector||"",u="ontouchstart"in n.documentElement,c=(new Date).getTime(),d=[],l=arguments[0],v="string"==typeof l,f=[].slice.call(arguments,1);return s.each(function(){var n,m,h=e.isPlainObject(t)?e.extend(!0,{},e.fn.dropdown.settings,t):e.extend({},e.fn.dropdown.settings),p=h.className,g=h.metadata,b=h.namespace,w=h.selector,y=h.error,x="."+b,T="module-"+b,C=e(this),k=C.find(w.text),S=C.find(w.search),z=C.find(w.input),E=C.prev().find(w.text).size()>0?C.prev().find(w.text):C.prev(),D=C.children(w.menu),M=D.find(w.item),A=!1,O=!1,I=this,Q=C.data(T);m={initialize:function(){m.debug("Initializing dropdown",h),m.setup.layout(),m.save.defaults(),m.set.selected(),u&&m.bind.touchEvents(),m.bind.mouseEvents(),m.bind.keyboardEvents(),m.observeChanges(),m.instantiate()},instantiate:function(){m.verbose("Storing instance of dropdown",m),Q=m,C.data(T,m)},destroy:function(){m.verbose("Destroying previous dropdown for",C),C.off(x).removeData(T)},observeChanges:function(){MutationObserver!==i&&(n=new MutationObserver(function(){m.debug("DOM tree modified, updating selector cache"),m.refresh()}),n.observe(I,{childList:!0,subtree:!0}),m.debug("Setting up mutation observer",n))},setup:{layout:function(){C.is("select")&&m.setup.select(),m.is.search()&&!m.is.searchable()&&(S=e("<input />").addClass(p.search).insertBefore(k)),h.allowTab&&(m.is.searchable()?(m.debug("Searchable dropdown initialized"),S.val("").attr("tabindex",0),D.attr("tabindex","-1")):(m.debug("Simple selection dropdown initialized"),C.attr("tabindex")||(C.attr("tabindex",0),D.attr("tabindex","-1"))))},select:function(){var t=m.get.selectValues();m.debug("Dropdown initialized on a select",t),z=C,z.parents(w.dropdown).size()>0?(m.debug("Creating dropdown menu only from template"),C=z.closest(w.dropdown),0===C.find("."+p.dropdown).size()&&e("<div />").addClass(p.menu).html(h.templates.menu(t)).appendTo(C)):(m.debug("Creating entire dropdown from template"),C=e("<div />").attr("class",z.attr("class")).addClass(p.selection).addClass(p.dropdown).html(h.templates.dropdown(t)).insertBefore(z),z.removeAttr("class").prependTo(C)),m.refresh()}},refresh:function(){k=C.find(w.text),S=C.find(w.search),z=C.find(w.input),D=C.children(w.menu),M=D.find(w.item)},toggle:function(){m.verbose("Toggling menu visibility"),m.is.active()?m.hide():m.show()},show:function(){m.debug("Checking if dropdown can show"),m.is.active()||(m.animate.show(function(){m.can.click()&&m.bind.intent(),m.set.visible()}),e.proxy(h.onShow,I)())},hide:function(){m.is.active()&&(m.debug("Hiding dropdown"),m.animate.hide(function(){m.remove.filteredItem(),m.remove.visible()}),e.proxy(h.onHide,I)())},hideOthers:function(){m.verbose("Finding other dropdowns to hide"),s.not(C).has(w.menu+":visible:not(."+p.animating+")").dropdown("hide")},hideSubMenus:function(){var e=D.find(w.menu),t=e.has(w.item+"."+p.active);e.not(t).removeClass(p.visible).removeAttr("style")},bind:{keyboardEvents:function(){m.debug("Binding keyboard events"),C.on("keydown"+x,m.event.keydown),m.is.searchable()&&C.on(m.get.inputEvent(),w.search,m.event.input)},touchEvents:function(){m.debug("Touch device detected binding touch events"),m.is.searchSelection()||C.on("touchstart"+x,m.event.test.toggle),C.on("touchstart"+x,w.item,m.event.item.mouseenter).on("touchstart"+x,w.item,m.event.item.click)},mouseEvents:function(){m.verbose("Mouse detected binding mouse events"),m.is.searchSelection()?C.on("focus"+x,w.search,m.event.searchFocus).on("blur"+x,w.search,m.event.searchBlur):("click"==h.on?C.on("click"+x,m.event.test.toggle):"hover"==h.on?C.on("mouseenter"+x,m.delay.show).on("mouseleave"+x,m.delay.hide):C.on(h.on+x,m.toggle),C.on("mousedown",m.event.mousedown).on("mouseup",m.event.mouseup).on("focus"+x,m.event.focus).on("blur"+x,m.event.blur)),C.on("mousedown"+x,w.item,m.event.item.mousedown).on("mouseup"+x,w.item,m.event.item.mouseup).on("mouseenter"+x,w.item,m.event.item.mouseenter).on("mouseleave"+x,w.item,m.event.item.mouseleave).on("click"+x,w.item,m.event.item.click)},intent:function(){m.verbose("Binding hide intent event to document"),u&&a.on("touchstart"+x,m.event.test.touch).on("touchmove"+x,m.event.test.touch),a.on("click"+x,m.event.test.hide)}},unbind:{intent:function(){m.verbose("Removing hide intent event from document"),u&&a.off("touchstart"+x).off("touchmove"+x),a.off("click"+x)}},filter:function(t){var n,o=e(),s=new RegExp("(?:s|^)"+t,"i"),a=new RegExp(t,"i");M.each(function(){var t=e(this),n=t.data(g.text)!==i?t.data(g.text):h.preserveHTML?t.html():t.text(),r=t.data(g.value)!==i?t.data(g.value):"string"==typeof n?n.toLowerCase():n;s.test(n)||s.test(r)?o=o.add(t):h.fullTextSearch&&(a.test(n)||a.test(r))&&(o=o.add(t))}),n=M.not(o),m.remove.filteredItem(),m.remove.selectedItem(),n.addClass(p.filtered),M.not("."+p.filtered).eq(0).addClass(p.selected)},event:{mousedown:function(){A=!0},mouseup:function(){A=!1},focus:function(){A||m.show()},blur:function(){A||m.hide()},searchFocus:function(){A=!0,m.show()},searchBlur:function(){O||m.hide()},input:function(){var e=S.val();m.is.searchSelection()&&k.addClass(p.filtered),m.filter(e)},keydown:function(t){var n,i=M.not(p.filtered).filter("."+p.selected).eq(0),o=M.not("."+p.filtered),s=t.which,a={enter:13,escape:27,upArrow:38,downArrow:40},r=p.selected,u=o.index(i),c=i.size()>0;if(c||(i=M.filter("."+p.active).eq(0),c=i.size()>0),s==a.escape&&(m.verbose("Escape key pressed, closing dropdown"),S.blur(),m.hide()),m.is.visible()){if(s==a.enter&&c)return m.verbose("Enter key pressed, choosing selected item"),m.is.searchable()&&(m.verbose("Removing focus from search input"),S.blur()),e.proxy(m.event.item.click,i)(t),t.preventDefault(),!1;s==a.upArrow?(n=c?i.prevAll(w.item+":not(."+p.filtered+")").eq(0):o.eq(0),0!==u&&(m.verbose("Up key pressed, changing active item"),M.removeClass(r),n.addClass(r),m.set.scrollPosition(n)),t.preventDefault()):s==a.downArrow&&(n=c?i.nextAll(w.item+":not(."+p.filtered+")").eq(0):o.eq(0),u+1<o.size()&&(m.verbose("Down key pressed, changing active item"),M.removeClass(r),n.addClass(r),m.set.scrollPosition(n)),t.preventDefault())}else s==a.enter&&m.show()},test:{toggle:function(e){m.determine.eventInMenu(e,m.toggle)&&e.preventDefault()},touch:function(e){m.determine.eventInMenu(e,function(){"touchstart"==e.type?m.timer=setTimeout(m.hide,h.delay.touch):"touchmove"==e.type&&clearTimeout(m.timer)}),e.stopPropagation()},hide:function(e){m.determine.eventInModule(e,m.hide)}},item:{mousedown:function(){O=!0},mouseup:function(){O=!1},mouseenter:function(t){var n=e(this).find(w.menu),i=e(this).siblings(w.item).children(w.menu);n.size()>0&&(clearTimeout(m.itemTimer),m.itemTimer=setTimeout(function(){m.animate.hide(!1,i),m.verbose("Showing sub-menu",n),m.animate.show(!1,n)},2*h.delay.show),t.preventDefault())},mouseleave:function(){var t=e(this).find(w.menu);t.size()>0&&(clearTimeout(m.itemTimer),m.itemTimer=setTimeout(function(){m.verbose("Hiding sub-menu",t),m.animate.hide(!1,t)},h.delay.hide))},click:function(t){var n=e(this),o=n.data(g.text)!==i?n.data(g.text):h.preserveHTML?n.html():n.text(),s=n.data(g.value)!==i?n.data(g.value):"string"==typeof o?o.toLowerCase():o,a=function(){S.val(""),m.determine.selectAction(o,s),e.proxy(h.onChange,I)(s,o,n)},r=n.find(w.menu).size()>0;r||("touchstart"==t.type?n.one("click",a):a())}},resetStyle:function(){e(this).removeAttr("style")}},determine:{selectAction:function(t,n){m.verbose("Determining action",h.action),e.isFunction(m.action[h.action])?(m.verbose("Triggering preset action",h.action,t,n),m.action[h.action](t,n)):e.isFunction(h.action)?(m.verbose("Triggering user action",h.action,t,n),h.action(t,n)):m.error(y.action,h.action)},eventInModule:function(t,n){return n=n||function(){},0===e(t.target).closest(C).size()?(m.verbose("Triggering event",n),n(),!0):(m.verbose("Event occurred in dropdown, canceling callback"),!1)},eventInMenu:function(t,n){return n=n||function(){},0===e(t.target).closest(D).size()?(m.verbose("Triggering event",n),n(),!0):(m.verbose("Event occurred in dropdown menu, canceling callback"),!1)}},action:{nothing:function(){},hide:function(){m.hide()},select:function(e,t){t=t!==i?t:e,m.set.selected(t),m.set.value(t),m.hide()},activate:function(e,t){t=t!==i?t:e,m.set.selected(t),m.set.value(t),m.hide()},combo:function(e,t){t=t!==i?t:e,m.set.selected(t),m.set.value(t),m.hide()}},get:{text:function(){return k.text()},value:function(){return z.size()>0?z.val():C.data(g.value)},inputEvent:function(){var e=S[0];return e?e.oninput!==i?"input":e.onpropertychange!==i?"propertychange":"keyup":!1},selectValues:function(){var t={values:{}};return C.find("option").each(function(){var n=e(this).html(),o=e(this).attr("value")!==i?e(this).attr("value"):n;""===o?t.placeholder=n:t.values[o]=n}),m.debug("Retrieved values from select",t),t},item:function(t,n){var o=!1;return t=t!==i?t:m.get.value()!==i?m.get.value():m.get.text(),n=""===t||0===t?!0:n||!1,t!==i?M.each(function(){var s=e(this),a=s.data(g.text)!==i?s.data(g.text):h.preserveHTML?s.html():s.text(),r=s.data(g.value)!==i?s.data(g.value):"string"==typeof a?a.toLowerCase():a;n?(m.debug("Ambiguous dropdown value using strict type check",t),r===t?o=e(this):o||a!==t||(o=e(this))):r==t?(m.verbose("Found select item by value",r,t),o=e(this)):o||a!=t||(m.verbose("Found select item by text",a,t),o=e(this))}):t=m.get.text(),o||!1}},restore:{defaults:function(){m.restore.defaultText(),m.restore.defaultValue()},defaultText:function(){var e=C.data(g.defaultText);m.debug("Restoring default text",e),m.set.text(e)},defaultValue:function(){var e=C.data(g.defaultValue);e!==i&&(m.debug("Restoring default value",e),m.set.selected(e),m.set.value(e))}},save:{defaults:function(){m.save.defaultText(),m.save.defaultValue()},defaultValue:function(){C.data(g.defaultValue,m.get.value())},defaultText:function(){C.data(g.defaultText,k.text())}},set:{scrollPosition:function(e){var t,n,i,o,s,a,r,u,e=e||m.get.item(),c=e&&e.size()>0,d=5;e&&c&&(a=D.height(),n=e.height(),s=D.scrollTop(),o=D.offset().top,i=e.offset().top,t=s-o+i,u=t+d>s+a,r=s>t-d,(r||u)&&(m.debug("Scrolling to active item"),D.scrollTop(t)))},text:function(e){"combo"==h.action?(m.debug("Changing combo button text",e,E),h.preserveHTML?E.html(e):E.text(e)):"select"!==h.action&&(m.debug("Changing text",e,k),k.removeClass(p.filtered).removeClass(p.placeholder),h.preserveHTML?k.html(e):k.text(e))},value:function(e){m.debug("Adding selected value to hidden input",e,z),z.size()>0?z.val(e).trigger("change"):C.data(g.value,e)},active:function(){C.addClass(p.active)},visible:function(){C.addClass(p.visible)},selected:function(e){var t,n=m.get.item(e);n&&(m.debug("Setting selected menu item to",n),t=n.data(g.text)!==i?n.data(g.text):h.preserveHTML?n.html():n.text(),m.remove.activeItem(),m.remove.selectedItem(),n.addClass(p.active).addClass(p.selected),m.set.text(t))}},remove:{active:function(){C.removeClass(p.active)},visible:function(){C.removeClass(p.visible)},activeItem:function(){M.removeClass(p.active)},filteredItem:function(){M.removeClass(p.filtered)},selectedItem:function(){M.removeClass(p.selected)}},is:{search:function(){return C.hasClass(p.search)},searchable:function(){return S.size()>0},searchSelection:function(){return m.is.searchable()&&S.parent().is(C)},selection:function(){return C.hasClass(p.selection)},animated:function(e){return e?e.is(":animated")||e.transition&&e.transition("is animating"):D.is(":animated")||D.transition&&D.transition("is animating")},active:function(){return C.hasClass(p.active)},visible:function(e){return e?e.is(":visible"):D.is(":visible")},hidden:function(e){return e?e.is(":hidden"):D.is(":hidden")}},can:{click:function(){return u||"click"==h.on},show:function(){return!C.hasClass(p.disabled)}},animate:{show:function(t,n){var o=n||D,s=n?function(){}:function(){m.hideOthers(),m.set.active(),m.set.scrollPosition()};t=t||function(){},m.verbose("Doing menu show animation",o),m.is.hidden(o)&&("none"==h.transition?e.proxy(t,I)():e.fn.transition!==i&&C.transition("is supported")?o.transition({animation:h.transition+" in",duration:h.duration,queue:!0,start:s,complete:function(){e.proxy(t,I)()}}):"slide down"==h.transition?(s(),o.hide().clearQueue().children().clearQueue().css("opacity",0).delay(50).animate({opacity:1},h.duration,"easeOutQuad",m.event.resetStyle).end().slideDown(100,"easeOutQuad",function(){e.proxy(m.event.resetStyle,this)(),e.proxy(t,I)()})):"fade"==h.transition?(s(),o.hide().clearQueue().fadeIn(h.duration,function(){e.proxy(m.event.resetStyle,this)(),e.proxy(t,I)()})):m.error(y.transition,h.transition))},hide:function(t,n){var o=n||D,s=n?function(){}:function(){m.can.click()&&m.unbind.intent(),m.hideSubMenus(),m.remove.active()};t=t||function(){},m.is.visible(o)&&(m.verbose("Doing menu hide animation",o),"none"==h.transition?e.proxy(t,I)():e.fn.transition!==i&&C.transition("is supported")?o.transition({animation:h.transition+" out",duration:h.duration,queue:!0,start:s,complete:function(){e.proxy(t,I)()}}):"slide down"==h.transition?(s(),o.show().clearQueue().children().clearQueue().css("opacity",1).animate({opacity:0},100,"easeOutQuad",m.event.resetStyle).end().delay(50).slideUp(100,"easeOutQuad",function(){e.proxy(m.event.resetStyle,this)(),e.proxy(t,I)()})):"fade"==h.transition?(s(),o.show().clearQueue().fadeOut(150,function(){e.proxy(m.event.resetStyle,this)(),e.proxy(t,I)()})):m.error(y.transition))}},delay:{show:function(){m.verbose("Delaying show event to ensure user intent"),clearTimeout(m.timer),m.timer=setTimeout(m.show,h.delay.show)},hide:function(){m.verbose("Delaying hide event to ensure user intent"),clearTimeout(m.timer),m.timer=setTimeout(m.hide,h.delay.hide)}},setting:function(t,n){if(m.debug("Changing setting",t,n),e.isPlainObject(t))e.extend(!0,h,t);else{if(n===i)return h[t];h[t]=n}},internal:function(t,n){if(e.isPlainObject(t))e.extend(!0,m,t);else{if(n===i)return m[t];m[t]=n}},debug:function(){h.debug&&(h.performance?m.performance.log(arguments):(m.debug=Function.prototype.bind.call(console.info,console,h.name+":"),m.debug.apply(console,arguments)))},verbose:function(){h.verbose&&h.debug&&(h.performance?m.performance.log(arguments):(m.verbose=Function.prototype.bind.call(console.info,console,h.name+":"),m.verbose.apply(console,arguments)))},error:function(){m.error=Function.prototype.bind.call(console.error,console,h.name+":"),m.error.apply(console,arguments)},performance:{log:function(e){var t,n,i;h.performance&&(t=(new Date).getTime(),i=c||t,n=t-i,c=t,d.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:I,"Execution Time":n})),clearTimeout(m.performance.timer),m.performance.timer=setTimeout(m.performance.display,100)},display:function(){var t=h.name+":",n=0;c=!1,clearTimeout(m.performance.timer),e.each(d,function(e,t){n+=t["Execution Time"]}),t+=" "+n+"ms",r&&(t+=" '"+r+"'"),(console.group!==i||console.table!==i)&&d.length>0&&(console.groupCollapsed(t),console.table?console.table(d):e.each(d,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),d=[]}},invoke:function(t,n,s){var a,r,u,c=Q;return n=n||f,s=I||s,"string"==typeof t&&c!==i&&(t=t.split(/[\. ]/),a=t.length-1,e.each(t,function(n,o){var s=n!=a?o+t[n+1].charAt(0).toUpperCase()+t[n+1].slice(1):t;if(e.isPlainObject(c[s])&&n!=a)c=c[s];else{if(c[s]!==i)return r=c[s],!1;if(!e.isPlainObject(c[o])||n==a)return c[o]!==i?(r=c[o],!1):(m.error(y.method,t),!1);c=c[o]}})),e.isFunction(r)?u=r.apply(s,n):r!==i&&(u=r),e.isArray(o)?o.push(u):o!==i?o=[o,u]:u!==i&&(o=u),r}},v?(Q===i&&m.initialize(),m.invoke(l)):(Q!==i&&m.destroy(),m.initialize())}),o!==i?o:this},e.fn.dropdown.settings={debug:!1,verbose:!0,performance:!0,on:"click",action:"activate",allowTab:!0,fullTextSearch:!0,preserveHTML:!0,delay:{show:200,hide:300,touch:50},transition:"slide down",duration:250,onChange:function(){},onShow:function(){},onHide:function(){},name:"Dropdown",namespace:"dropdown",error:{action:"You called a dropdown action that was not defined",method:"The method you called is not defined.",transition:"The requested transition was not found"},metadata:{defaultText:"defaultText",defaultValue:"defaultValue",text:"text",value:"value"},selector:{dropdown:".ui.dropdown",text:"> .text:not(.icon)",input:'> input[type="hidden"], > select',search:"> .search, .menu > .search > input, .menu > input.search",menu:".menu",item:".item"},className:{active:"active",animating:"animating",disabled:"disabled",dropdown:"ui dropdown",filtered:"filtered",menu:"menu",placeholder:"default",search:"search",selected:"selected",selection:"selection",visible:"visible"}},e.fn.dropdown.settings.templates={menu:function(t){var n=(t.placeholder||!1,t.values||{},"");return e.each(t.values,function(e,t){n+=e===t?'<div class="item">'+t+"</div>":'<div class="item" data-value="'+e+'">'+t+"</div>"}),n},dropdown:function(t){var n=t.placeholder||!1,i=(t.values||{},"");return i+='<i class="dropdown icon"></i>',i+=t.placeholder?'<div class="default text">'+n+"</div>":'<div class="text"></div>',i+='<div class="menu">',e.each(t.values,function(e,t){i+=e===t?'<div class="item">'+t+"</div>":'<div class="item" data-value="'+e+'">'+t+"</div>"}),i+="</div>"}},e.extend(e.easing,{easeOutQuad:function(e,t,n,i,o){return-i*(t/=o)*(t-2)+n}})}(jQuery,window,document); | ||
!function(e,t,n,i){"use strict";e.fn.dropdown=function(o){var a,r=e(this),s=e(n),c=r.selector||"",l="ontouchstart"in n.documentElement,u=(new Date).getTime(),d=[],f=arguments[0],v="string"==typeof f,h=[].slice.call(arguments,1);return r.each(function(){var m,g,p,b,w=e.isPlainObject(o)?e.extend(!0,{},e.fn.dropdown.settings,o):e.extend({},e.fn.dropdown.settings),y=w.className,x=w.metadata,T=w.namespace,S=w.selector,C=w.error,k="."+T,I="module-"+T,E=e(this),D=E.find(S.text),A=E.find(S.search),F=E.find(S.input),M=E.prev().find(S.text).length>0?E.prev().find(S.text):E.prev(),q=E.children(S.menu),O=q.find(S.item),V=!1,z=!1,Q=this,R=E.data(I);b={initialize:function(){b.debug("Initializing dropdown",w),b.is.alreadySetup()?b.error(C.alreadySetup):b.setup.layout(),b.save.defaults(),b.set.selected(),b.create.id(),l&&b.bind.touchEvents(),b.bind.mouseEvents(),b.bind.keyboardEvents(),b.observeChanges(),b.instantiate()},instantiate:function(){b.verbose("Storing instance of dropdown",b),R=b,E.data(I,b)},destroy:function(){b.verbose("Destroying previous dropdown for",E),b.remove.tabbable(),E.off(k).removeData(I),q.off(k),s.off(m)},observeChanges:function(){"MutationObserver"in t&&(p=new MutationObserver(function(e){b.is.selectMutation(e)?(b.debug("<select> modified, recreating menu"),b.setup.select()):(b.debug("DOM tree modified, updating selector cache"),b.refresh())}),p.observe(Q,{childList:!0,subtree:!0}),b.debug("Setting up mutation observer",p))},create:{id:function(){b.verbose("Creating unique id for element"),g=b.get.uniqueID(),m="."+g}},search:function(){var e;e=A.val(),b.verbose("Searching for query",e),b.filter(e),b.is.searchSelection()&&b.can.show()&&b.show()},setup:{layout:function(){E.is("select")&&b.setup.select(),b.is.search()&&!b.is.searchable()&&(A=e("<input />").addClass(y.search).insertBefore(D)),w.allowTab&&b.set.tabbable()},select:function(){var t=b.get.selectValues();b.debug("Dropdown initialized on a select",t),E.is("select")&&(F=E),F.parent(S.dropdown).length>0?(b.debug("UI dropdown already exists. Creating dropdown menu only"),E=F.closest(S.dropdown),q=E.children(S.menu),0===q.length&&(q=e("<div />").addClass(y.menu).appendTo(E)),q.html(w.templates.menu(t))):(b.debug("Creating entire dropdown from select"),E=e("<div />").attr("class",F.attr("class")).addClass(y.selection).addClass(y.dropdown).html(w.templates.dropdown(t)).insertBefore(F),F.removeAttr("class").prependTo(E)),b.refresh()}},refresh:function(){b.verbose("Refreshing selector cache"),D=E.find(S.text),A=E.find(S.search),F=E.find(S.input),M=E.prev().find(S.text).length>0?E.prev().find(S.text):E.prev(),q=E.children(S.menu),O=q.find(S.item)},toggle:function(){b.verbose("Toggling menu visibility"),b.is.active()?b.hide():b.show()},show:function(t){t=e.isFunction(t)?t:function(){},b.is.searchSelection()&&b.is.allFiltered()||b.can.show()&&!b.is.active()&&(b.debug("Showing dropdown"),b.animate.show(function(){b.can.click()&&b.bind.intent(),b.set.visible(),t.call(Q)}),w.onShow.call(Q))},hide:function(t){t=e.isFunction(t)?t:function(){},b.is.active()&&(b.debug("Hiding dropdown"),b.animate.hide(function(){b.remove.visible(),t.call(Q)}),w.onHide.call(Q))},hideOthers:function(){b.verbose("Finding other dropdowns to hide"),r.not(E).has(S.menu+":visible:not(."+y.animating+")").dropdown("hide")},hideSubMenus:function(){var e=q.find(S.menu);e.transition("hide")},bind:{keyboardEvents:function(){b.debug("Binding keyboard events"),E.on("keydown"+k,b.event.keydown),b.is.searchable()&&E.on(b.get.inputEvent(),S.search,b.event.input)},touchEvents:function(){b.debug("Touch device detected binding additional touch events"),b.is.searchSelection()||E.on("touchstart"+k,b.event.test.toggle),q.on("touchstart"+k,S.item,b.event.item.mouseenter)},mouseEvents:function(){b.verbose("Mouse detected binding mouse events"),b.is.searchSelection()?E.on("mousedown"+k,S.menu,b.event.menu.activate).on("mouseup"+k,S.menu,b.event.menu.deactivate).on("click"+k,S.search,b.show).on("focus"+k,S.search,b.event.searchFocus).on("blur"+k,S.search,b.event.searchBlur).on("click"+k,S.text,b.event.searchTextFocus):("click"==w.on?E.on("click"+k,b.event.test.toggle):"hover"==w.on?E.on("mouseenter"+k,b.delay.show).on("mouseleave"+k,b.delay.hide):E.on(w.on+k,b.toggle),E.on("mousedown"+k,b.event.mousedown).on("mouseup"+k,b.event.mouseup).on("focus"+k,b.event.focus).on("blur"+k,b.event.blur)),q.on("mouseenter"+k,S.item,b.event.item.mouseenter).on("mouseleave"+k,S.item,b.event.item.mouseleave).on("click"+k,S.item,b.event.item.click)},intent:function(){b.verbose("Binding hide intent event to document"),l&&s.on("touchstart"+m,b.event.test.touch).on("touchmove"+m,b.event.test.touch),s.on("click"+m,b.event.test.hide)}},unbind:{intent:function(){b.verbose("Removing hide intent event from document"),l&&s.off("touchstart"+m).off("touchmove"+m),s.off("click"+m)}},filter:function(t){var n=e(),i=b.escape.regExp(t),o=new RegExp("^"+i,"igm"),a=new RegExp(i,"ig");b.verbose("Searching for matching values"),O.each(function(){var t=e(this),i=String(b.get.choiceText(t,!1)),r=String(b.get.choiceValue(t,i));i.match(o)||r.match(o)?n=n.add(t):w.fullTextSearch&&(i.match(a)||r.match(a))&&(n=n.add(t))}),b.debug("Setting filter",t),b.remove.filteredItem(),O.not(n).addClass(y.filtered),b.verbose("Selecting first non-filtered element"),b.remove.selectedItem(),O.not("."+y.filtered).eq(0).addClass(y.selected),b.is.allFiltered()&&(b.debug("All items filtered, hiding dropdown",t),b.is.searchSelection()&&b.hide(),w.onNoResults.call(Q,t))},focusSearch:function(){b.is.search()&&A.focus()},forceSelection:function(){var e=O.not(y.filtered).filter("."+y.selected).eq(0),t=O.filter("."+y.active).eq(0),n=e.length>0?e:t,i=n.size()>0;i&&b.event.item.click.call(n)},event:{mousedown:function(){V=!0},mouseup:function(){V=!1},focus:function(){!V&&b.is.hidden()&&b.show()},blur:function(){var e=n.activeElement===this;V||e||b.hide()},searchFocus:function(){V=!0,b.show()},searchBlur:function(){var e=n.activeElement===this;z||e||(w.forceSelection?b.forceSelection():b.hide())},searchTextFocus:function(){V=!0,A.focus()},input:function(){b.is.searchSelection()&&b.set.filtered(),clearTimeout(b.timer),b.timer=setTimeout(b.search,w.delay.search)},keydown:function(e){{var t,n=O.not(y.filtered).filter("."+y.selected).eq(0),i=q.children("."+y.active).eq(0),o=n.length>0?n:i,a=o.length>0?o.siblings(":not(."+y.filtered+")").andSelf():q.children(":not(."+y.filtered+")"),r=o.children(S.menu),s=o.closest(S.menu),c=s[0]!==q[0],l=s.is(":visible"),u=e.which,d={enter:13,escape:27,leftArrow:37,upArrow:38,rightArrow:39,downArrow:40},f=r.length>0,v=o.length>0;a.size()-1}if(b.is.visible()){if(u==d.enter&&v&&(f&&!w.allowCategorySelection?(b.verbose("Pressed enter on unselectable category, opening sub menu"),u=d.rightArrow):(b.verbose("Enter key pressed, choosing selected item"),b.event.item.click.call(o,e))),u==d.leftArrow&&(c&&(b.verbose("Left key pressed, closing sub-menu"),b.animate.hide(!1,s),o.removeClass(y.selected),s.closest(S.item).addClass(y.selected)),e.preventDefault()),u==d.rightArrow&&(f&&(b.verbose("Right key pressed, opening sub-menu"),b.animate.show(!1,r),o.removeClass(y.selected),r.find(S.item).eq(0).addClass(y.selected)),e.preventDefault()),u==d.upArrow){if(t=v&&l?o.prevAll(S.item+":not(."+y.filtered+")").eq(0):O.eq(0),a.index(t)<0)return void b.verbose("Up key pressed but reached top of current menu");b.verbose("Up key pressed, changing active item"),o.removeClass(y.selected),t.addClass(y.selected),b.set.scrollPosition(t),e.preventDefault()}if(u==d.downArrow){if(t=v&&l?t=o.nextAll(S.item+":not(."+y.filtered+")").eq(0):O.eq(0),0===t.length)return void b.verbose("Down key pressed but reached bottom of current menu");b.verbose("Down key pressed, changing active item"),O.removeClass(y.selected),t.addClass(y.selected),b.set.scrollPosition(t),e.preventDefault()}}else u==d.enter&&(b.verbose("Enter key pressed, showing dropdown"),b.show()),u==d.escape&&(b.verbose("Escape key pressed, closing dropdown"),b.hide()),u==d.downArrow&&(b.verbose("Down key pressed, showing dropdown"),b.show())},test:{toggle:function(e){b.determine.eventInMenu(e,b.toggle)&&e.preventDefault()},touch:function(e){b.determine.eventInMenu(e,function(){"touchstart"==e.type?b.timer=setTimeout(b.hide,w.delay.touch):"touchmove"==e.type&&clearTimeout(b.timer)}),e.stopPropagation()},hide:function(e){b.determine.eventInModule(e,b.hide)}},menu:{activate:function(){z=!0},deactivate:function(){z=!1}},item:{mouseenter:function(t){var n=e(this).children(S.menu),i=e(this).siblings(S.item).children(S.menu);n.length>0&&(clearTimeout(b.itemTimer),b.itemTimer=setTimeout(function(){b.verbose("Showing sub-menu",n),e.each(i,function(){b.animate.hide(!1,e(this))}),b.animate.show(!1,n)},w.delay.show),t.preventDefault())},mouseleave:function(){var t=e(this).children(S.menu);t.length>0&&(clearTimeout(b.itemTimer),b.itemTimer=setTimeout(function(){b.verbose("Hiding sub-menu",t),b.animate.hide(!1,t)},w.delay.hide))},click:function(t){var n=e(this),i=e(t?t.target:""),o=n.find(S.menu),a=b.get.choiceText(n),r=b.get.choiceValue(n,a),s=function(){b.remove.searchTerm(),b.determine.selectAction(a,r)},c=o.length>0,l=o.find(i).length>0;l||c&&!w.allowCategorySelection||s()}},resetStyle:function(){e(this).removeAttr("style")}},determine:{selectAction:function(t,n){b.verbose("Determining action",w.action),e.isFunction(b.action[w.action])?(b.verbose("Triggering preset action",w.action,t,n),b.action[w.action](t,n)):e.isFunction(w.action)?(b.verbose("Triggering user action",w.action,t,n),w.action(t,n)):b.error(C.action,w.action)},eventInModule:function(t,n){return n=e.isFunction(n)?n:function(){},0===e(t.target).closest(E).length?(b.verbose("Triggering event",n),n(),!0):(b.verbose("Event occurred in dropdown, canceling callback"),!1)},eventInMenu:function(t,n){return n=e.isFunction(n)?n:function(){},0===e(t.target).closest(q).length?(b.verbose("Triggering event",n),n(),!0):(b.verbose("Event occurred in dropdown menu, canceling callback"),!1)}},action:{nothing:function(){},activate:function(e,t){t=t!==i?t:e,b.set.selected(t),b.hide(function(){b.remove.filteredItem()})},select:function(e,t){t=t!==i?t:e,b.set.selected(t),b.hide(function(){b.remove.filteredItem()})},combo:function(e,t){t=t!==i?t:e,b.set.selected(t),b.hide(function(){b.remove.filteredItem()})},hide:function(){b.hide(function(){b.remove.filteredItem()})}},get:{text:function(){return D.text()},value:function(){return F.length>0?F.val():E.data(x.value)},choiceText:function(e,t){return t=t!==i?t:w.preserveHTML,e!==i?(e.find(S.menu).length>0&&(b.verbose("Retreiving text of element with sub-menu"),e=e.clone(),e.find(S.menu).remove(),e.find(S.menuIcon).remove()),e.data(x.text)!==i?e.data(x.text):t?e.html().trim():e.text().trim()):void 0},choiceValue:function(e,t){return t=t||b.get.choiceText(e),e.data(x.value)!==i?e.data(x.value):"string"==typeof t?t.toLowerCase().trim():t.trim()},inputEvent:function(){var e=A[0];return e?e.oninput!==i?"input":e.onpropertychange!==i?"propertychange":"keyup":!1},selectValues:function(){var t={};return t.values=w.sortSelect?{}:[],E.find("option").each(function(){var n=e(this).html(),o=e(this).attr("value")!==i?e(this).attr("value"):n;""===o?t.placeholder=n:w.sortSelect?t.values[o]={name:n,value:o}:t.values.push({name:n,value:o})}),w.sortSelect?b.debug("Retrieved and sorted values from select",t):b.debug("Retreived values from select",t),t},activeItem:function(){return O.filter("."+y.active)},item:function(t,n){var o=!1;return t=t!==i?t:b.get.value()!==i?b.get.value():b.get.text(),n=""===t||0===t?!0:n||!1,t!==i?O.each(function(){var i=e(this),a=b.get.choiceText(i),r=b.get.choiceValue(i,a);n?(b.verbose("Ambiguous dropdown value using strict type check",i,t),r===t?o=e(this):o||a!==t||(o=e(this))):r==t?(b.verbose("Found select item by value",r,t),o=e(this)):o||a!=t||(b.verbose("Found select item by text",a,t),o=e(this))}):t=b.get.text(),o||!1},uniqueID:function(){return(Math.random().toString(16)+"000000000").substr(2,8)}},restore:{defaults:function(){b.restore.defaultText(),b.restore.defaultValue()},defaultText:function(){var e=E.data(x.defaultText);b.debug("Restoring default text",e),b.set.text(e),D.addClass(y.placeholder)},defaultValue:function(){var e=E.data(x.defaultValue);e!==i&&(b.debug("Restoring default value",e),e.length?b.set.selected(e):(b.remove.activeItem(),b.remove.selectedItem()))}},save:{defaults:function(){b.save.defaultText(),b.save.placeholderText(),b.save.defaultValue()},defaultValue:function(){E.data(x.defaultValue,b.get.value())},defaultText:function(){E.data(x.defaultText,D.text())},placeholderText:function(){D.hasClass(y.placeholder)&&E.data(x.placeholderText,D.text())}},clear:function(){var e=E.data(x.placeholderText);b.set.text(e),b.set.value(""),b.remove.activeItem(),b.remove.selectedItem(),D.addClass(y.placeholder)},set:{filtered:function(){var e=A.val(),t="string"==typeof e&&e.length>0;t?D.addClass(y.filtered):D.removeClass(y.filtered)},tabbable:function(){b.is.searchable()?(b.debug("Searchable dropdown initialized"),A.val("").attr("tabindex",0),q.attr("tabindex","-1")):(b.debug("Simple selection dropdown initialized"),E.attr("tabindex")||(E.attr("tabindex",0),q.attr("tabindex","-1")))},scrollPosition:function(e,t){var n,o,a,r,s,c,l,u,d,f=5;e=e||b.get.activeItem(),n=e&&e.length>0,t=t!==i?t:!1,e&&n&&(q.hasClass(y.visible)||q.addClass(y.loading),l=q.height(),a=e.height(),c=q.scrollTop(),s=q.offset().top,r=e.offset().top,o=c-s+r,d=o+f>c+l,u=c>o-f,b.debug("Scrolling to active item",o),(u||d||t)&&q.scrollTop(o).removeClass(y.loading))},text:function(e){"combo"==w.action?(b.debug("Changing combo button text",e,M),w.preserveHTML?M.html(e):M.text(e)):"select"!==w.action&&(b.debug("Changing text",e,D),D.removeClass(y.filtered).removeClass(y.placeholder),w.preserveHTML?D.html(e):D.text(e))},value:function(e){b.debug("Adding selected value to hidden input",e,F),F.length>0?F.val(e).trigger("change"):E.data(x.value,e)},active:function(){E.addClass(y.active)},visible:function(){E.addClass(y.visible)},selected:function(e){var t,n,i=b.get.item(e);i&&(b.debug("Setting selected menu item to",i),b.remove.activeItem(),b.remove.selectedItem(),i.addClass(y.active).addClass(y.selected),t=b.get.choiceText(i),n=b.get.choiceValue(i,t),b.set.text(t),b.set.value(n),w.onChange.call(Q,e,t,i))}},remove:{active:function(){E.removeClass(y.active)},visible:function(){E.removeClass(y.visible)},activeItem:function(){O.removeClass(y.active)},filteredItem:function(){O.removeClass(y.filtered)},searchTerm:function(){A.val("")},selectedItem:function(){O.removeClass(y.selected)},tabbable:function(){b.is.searchable()?(b.debug("Searchable dropdown initialized"),A.attr("tabindex","-1"),q.attr("tabindex","-1")):(b.debug("Simple selection dropdown initialized"),E.attr("tabindex","-1"),q.attr("tabindex","-1"))}},is:{active:function(){return E.hasClass(y.active)},alreadySetup:function(){return E.is("select")&&E.parent(S.dropdown).length>0},animating:function(e){return e?e.is(":animated")||e.transition&&e.transition("is animating"):q.is(":animated")||q.transition&&q.transition("is animating")},allFiltered:function(){return O.filter("."+y.filtered).length===O.length},hidden:function(e){return e?e.is(":hidden"):q.is(":hidden")},selectMutation:function(t){var n=!1;return e.each(t,function(t,i){return i.target&&e(i.target).is("select")?(n=!0,!0):void 0}),n},search:function(){return E.hasClass(y.search)},searchable:function(){return A.length>0},searchSelection:function(){return b.is.searchable()&&A.parent().is(E)},selection:function(){return E.hasClass(y.selection)},upward:function(){return E.hasClass(y.upward)},visible:function(e){return e?e.is(":visible"):q.is(":visible")}},can:{click:function(){return l||"click"==w.on},show:function(){return!E.hasClass(y.disabled)}},animate:{show:function(t,n){var o=n||q,a=n?function(){}:function(){b.hideSubMenus(),b.hideOthers(),b.set.active()};t=e.isFunction(t)?t:function(){},b.set.scrollPosition(b.get.activeItem(),!0),b.verbose("Doing menu show animation",o),(b.is.hidden(o)||b.is.animating(o))&&("auto"==w.transition&&(w.transition=b.is.upward()?"slide up":"slide down",b.verbose("Automatically determining animation based on animation direction",w.transition)),"none"==w.transition?t.call(Q):e.fn.transition!==i&&E.transition("is supported")?o.transition({animation:w.transition+" in",debug:w.debug,verbose:w.verbose,duration:w.duration,queue:!0,onStart:a,onComplete:function(){t.call(Q)}}):"slide down"==w.transition?(a(),o.hide().clearQueue().children().clearQueue().css("opacity",0).delay(50).animate({opacity:1},w.duration,"easeOutQuad",b.event.resetStyle).end().slideDown(100,"easeOutQuad",function(){b.event.resetStyle.call(this),t.call(Q)})):"fade"==w.transition?(a(),o.hide().clearQueue().fadeIn(w.duration,function(){b.event.resetStyle.call(this),t.call(Q)})):b.error(C.transition,w.transition))},hide:function(t,n){var o=n||q,a=(n?.9*w.duration:w.duration,n?function(){}:function(){b.can.click()&&b.unbind.intent(),b.focusSearch(),b.remove.active()});t=e.isFunction(t)?t:function(){},(b.is.visible(o)||b.is.animating(o))&&(b.verbose("Doing menu hide animation",o),"auto"==w.transition&&(w.transition=b.is.upward()?"slide up":"slide down"),F.trigger("blur"),"none"==w.transition?t.call(Q):e.fn.transition!==i&&E.transition("is supported")?o.transition({animation:w.transition+" out",duration:w.duration,debug:w.debug,verbose:w.verbose,queue:!0,onStart:a,onComplete:function(){t.call(Q)}}):"slide down"==w.transition?(a(),o.show().clearQueue().children().clearQueue().css("opacity",1).animate({opacity:0},100,"easeOutQuad",b.event.resetStyle).end().delay(50).slideUp(100,"easeOutQuad",function(){b.event.resetStyle.call(this),t.call(Q)})):"fade"==w.transition?(a(),o.show().clearQueue().fadeOut(150,function(){b.event.resetStyle.call(this),t.call(Q)})):b.error(C.transition))}},delay:{show:function(){b.verbose("Delaying show event to ensure user intent"),clearTimeout(b.timer),b.timer=setTimeout(b.show,w.delay.show)},hide:function(){b.verbose("Delaying hide event to ensure user intent"),clearTimeout(b.timer),b.timer=setTimeout(b.hide,w.delay.hide)}},escape:{regExp:function(e){return e=String(e),e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")}},setting:function(t,n){if(b.debug("Changing setting",t,n),e.isPlainObject(t))e.extend(!0,w,t);else{if(n===i)return w[t];w[t]=n}},internal:function(t,n){if(e.isPlainObject(t))e.extend(!0,b,t);else{if(n===i)return b[t];b[t]=n}},debug:function(){w.debug&&(w.performance?b.performance.log(arguments):(b.debug=Function.prototype.bind.call(console.info,console,w.name+":"),b.debug.apply(console,arguments)))},verbose:function(){w.verbose&&w.debug&&(w.performance?b.performance.log(arguments):(b.verbose=Function.prototype.bind.call(console.info,console,w.name+":"),b.verbose.apply(console,arguments)))},error:function(){b.error=Function.prototype.bind.call(console.error,console,w.name+":"),b.error.apply(console,arguments)},performance:{log:function(e){var t,n,i;w.performance&&(t=(new Date).getTime(),i=u||t,n=t-i,u=t,d.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:Q,"Execution Time":n})),clearTimeout(b.performance.timer),b.performance.timer=setTimeout(b.performance.display,100)},display:function(){var t=w.name+":",n=0;u=!1,clearTimeout(b.performance.timer),e.each(d,function(e,t){n+=t["Execution Time"]}),t+=" "+n+"ms",c&&(t+=" '"+c+"'"),(console.group!==i||console.table!==i)&&d.length>0&&(console.groupCollapsed(t),console.table?console.table(d):e.each(d,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),d=[]}},invoke:function(t,n,o){var r,s,c,l=R;return n=n||h,o=Q||o,"string"==typeof t&&l!==i&&(t=t.split(/[\. ]/),r=t.length-1,e.each(t,function(n,o){var a=n!=r?o+t[n+1].charAt(0).toUpperCase()+t[n+1].slice(1):t;if(e.isPlainObject(l[a])&&n!=r)l=l[a];else{if(l[a]!==i)return s=l[a],!1;if(!e.isPlainObject(l[o])||n==r)return l[o]!==i?(s=l[o],!1):(b.error(C.method,t),!1);l=l[o]}})),e.isFunction(s)?c=s.apply(o,n):s!==i&&(c=s),e.isArray(a)?a.push(c):a!==i?a=[a,c]:c!==i&&(a=c),s}},v?(R===i&&b.initialize(),b.invoke(f)):(R!==i&&R.invoke("destroy"),b.initialize())}),a!==i?a:this},e.fn.dropdown.settings={debug:!1,verbose:!0,performance:!0,on:"click",action:"activate",allowTab:!0,fullTextSearch:!1,preserveHTML:!0,sortSelect:!1,allowCategorySelection:!1,delay:{hide:300,show:200,search:50,touch:50},forceSelection:!0,transition:"auto",duration:250,onNoResults:function(){},onChange:function(){},onShow:function(){},onHide:function(){},name:"Dropdown",namespace:"dropdown",error:{action:"You called a dropdown action that was not defined",alreadySetup:"Once a select has been initialized behaviors must be called on the created ui dropdown",method:"The method you called is not defined.",transition:"The requested transition was not found"},metadata:{defaultText:"defaultText",defaultValue:"defaultValue",placeholderText:"placeholderText",text:"text",value:"value"},selector:{dropdown:".ui.dropdown",input:'> input[type="hidden"], > select',item:".item",menu:".menu",menuIcon:".dropdown.icon",search:"> input.search, .menu > .search > input, .menu > input.search",text:"> .text:not(.icon)"},className:{active:"active",animating:"animating",disabled:"disabled",dropdown:"ui dropdown",filtered:"filtered",loading:"loading",menu:"menu",placeholder:"default",search:"search",selected:"selected",selection:"selection",upward:"upward",visible:"visible"}},e.fn.dropdown.settings.templates={menu:function(t){var n=(t.placeholder||!1,t.values||{},"");return e.each(t.values,function(e,t){n+='<div class="item" data-value="'+t.value+'">'+t.name+"</div>"}),n},dropdown:function(t){var n=t.placeholder||!1,i=(t.values||{},"");return i+='<i class="dropdown icon"></i>',i+=t.placeholder?'<div class="default text">'+n+"</div>":'<div class="text"></div>',i+='<div class="menu">',e.each(t.values,function(e,t){i+='<div class="item" data-value="'+t.value+'">'+t.name+"</div>"}),i+="</div>"}},e.extend(e.easing,{easeOutQuad:function(e,t,n,i,o){return-i*(t/=o)*(t-2)+n}})}(jQuery,window,document); |
964
index.js
@@ -56,3 +56,3 @@ /* | ||
$combo = ($module.prev().find(selector.text).size() > 0) | ||
$combo = ($module.prev().find(selector.text).length > 0) | ||
? $module.prev().find(selector.text) | ||
@@ -66,5 +66,7 @@ : $module.prev(), | ||
itemActivated = false, | ||
element = this, | ||
instance = $module.data(moduleNamespace), | ||
elementNamespace, | ||
id, | ||
observer, | ||
@@ -78,6 +80,15 @@ module | ||
module.debug('Initializing dropdown', settings); | ||
module.setup.layout(); | ||
if( module.is.alreadySetup() ) { | ||
module.error(error.alreadySetup); | ||
} | ||
else { | ||
module.setup.layout(); | ||
} | ||
module.save.defaults(); | ||
module.set.selected(); | ||
module.create.id(); | ||
if(hasTouch) { | ||
@@ -103,2 +114,3 @@ module.bind.touchEvents(); | ||
module.verbose('Destroying previous dropdown for', $module); | ||
module.remove.tabbable(); | ||
$module | ||
@@ -108,9 +120,21 @@ .off(eventNamespace) | ||
; | ||
$menu | ||
.off(eventNamespace) | ||
; | ||
$document | ||
.off(elementNamespace) | ||
; | ||
}, | ||
observeChanges: function() { | ||
if(MutationObserver !== undefined) { | ||
if('MutationObserver' in window) { | ||
observer = new MutationObserver(function(mutations) { | ||
module.debug('DOM tree modified, updating selector cache'); | ||
module.refresh(); | ||
if( module.is.selectMutation(mutations) ) { | ||
module.debug('<select> modified, recreating menu'); | ||
module.setup.select(); | ||
} | ||
else { | ||
module.debug('DOM tree modified, updating selector cache'); | ||
module.refresh(); | ||
} | ||
}); | ||
@@ -125,2 +149,23 @@ observer.observe(element, { | ||
create: { | ||
id: function() { | ||
module.verbose('Creating unique id for element'); | ||
id = module.get.uniqueID(); | ||
elementNamespace = '.' + id; | ||
} | ||
}, | ||
search: function() { | ||
var | ||
query | ||
; | ||
query = $search.val(); | ||
module.verbose('Searching for query', query); | ||
module.filter(query); | ||
if(module.is.searchSelection() && module.can.show() ) { | ||
module.show(); | ||
} | ||
}, | ||
setup: { | ||
@@ -139,23 +184,3 @@ | ||
if(settings.allowTab) { | ||
if( module.is.searchable() ) { | ||
module.debug('Searchable dropdown initialized'); | ||
$search | ||
.val('') | ||
.attr('tabindex', 0) | ||
; | ||
$menu | ||
.attr('tabindex', '-1') | ||
; | ||
} | ||
else { | ||
module.debug('Simple selection dropdown initialized'); | ||
if(!$module.attr('tabindex') ) { | ||
$module | ||
.attr('tabindex', 0) | ||
; | ||
$menu | ||
.attr('tabindex', '-1') | ||
; | ||
} | ||
} | ||
module.set.tabbable(); | ||
} | ||
@@ -165,20 +190,23 @@ }, | ||
var | ||
selectValues = module.get.selectValues() | ||
selectValues = module.get.selectValues() | ||
; | ||
module.debug('Dropdown initialized on a select', selectValues); | ||
// see if select exists inside a dropdown | ||
$input = $module; | ||
if($input.parents(selector.dropdown).size() > 0) { | ||
module.debug('Creating dropdown menu only from template'); | ||
if( $module.is('select') ) { | ||
$input = $module; | ||
} | ||
// see if select is placed correctly already | ||
if($input.parent(selector.dropdown).length > 0) { | ||
module.debug('UI dropdown already exists. Creating dropdown menu only'); | ||
$module = $input.closest(selector.dropdown); | ||
if($module.find('.' + className.dropdown).size() === 0) { | ||
$('<div />') | ||
$menu = $module.children(selector.menu); | ||
if($menu.length === 0) { | ||
$menu = $('<div />') | ||
.addClass(className.menu) | ||
.html( settings.templates.menu( selectValues )) | ||
.appendTo($module) | ||
; | ||
} | ||
$menu.html( settings.templates.menu( selectValues )); | ||
} | ||
else { | ||
module.debug('Creating entire dropdown from template'); | ||
module.debug('Creating entire dropdown from select'); | ||
$module = $('<div />') | ||
@@ -201,5 +229,10 @@ .attr('class', $input.attr('class') ) | ||
refresh: function() { | ||
module.verbose('Refreshing selector cache'); | ||
$text = $module.find(selector.text); | ||
$search = $module.find(selector.search); | ||
$input = $module.find(selector.input); | ||
$combo = ($module.prev().find(selector.text).length > 0) | ||
? $module.prev().find(selector.text) | ||
: $module.prev() | ||
; | ||
$menu = $module.children(selector.menu); | ||
@@ -219,5 +252,12 @@ $item = $menu.find(selector.item); | ||
show: function() { | ||
module.debug('Checking if dropdown can show'); | ||
if( !module.is.active() ) { | ||
show: function(callback) { | ||
callback = $.isFunction(callback) | ||
? callback | ||
: function(){} | ||
; | ||
if( module.is.searchSelection() && module.is.allFiltered() ) { | ||
return; | ||
} | ||
if( module.can.show() && !module.is.active() ) { | ||
module.debug('Showing dropdown'); | ||
module.animate.show(function() { | ||
@@ -228,15 +268,20 @@ if( module.can.click() ) { | ||
module.set.visible(); | ||
callback.call(element); | ||
}); | ||
$.proxy(settings.onShow, element)(); | ||
settings.onShow.call(element); | ||
} | ||
}, | ||
hide: function() { | ||
hide: function(callback) { | ||
callback = $.isFunction(callback) | ||
? callback | ||
: function(){} | ||
; | ||
if( module.is.active() ) { | ||
module.debug('Hiding dropdown'); | ||
module.animate.hide(function() { | ||
module.remove.filteredItem(); | ||
module.remove.visible(); | ||
callback.call(element); | ||
}); | ||
$.proxy(settings.onHide, element)(); | ||
settings.onHide.call(element); | ||
} | ||
@@ -256,10 +301,5 @@ }, | ||
var | ||
$subMenus = $menu.find(selector.menu), | ||
$activeSubMenu = $subMenus.has(selector.item + '.' + className.active) | ||
$subMenus = $menu.find(selector.menu) | ||
; | ||
$subMenus | ||
.not($activeSubMenu) | ||
.removeClass(className.visible) | ||
.removeAttr('style') | ||
; | ||
$subMenus.transition('hide'); | ||
}, | ||
@@ -280,4 +320,7 @@ | ||
touchEvents: function() { | ||
module.debug('Touch device detected binding touch events'); | ||
if( !module.is.searchSelection() ) { | ||
module.debug('Touch device detected binding additional touch events'); | ||
if( module.is.searchSelection() ) { | ||
// do nothing special yet | ||
} | ||
else { | ||
$module | ||
@@ -287,5 +330,4 @@ .on('touchstart' + eventNamespace, module.event.test.toggle) | ||
} | ||
$module | ||
$menu | ||
.on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter) | ||
.on('touchstart' + eventNamespace, selector.item, module.event.item.click) | ||
; | ||
@@ -297,4 +339,8 @@ }, | ||
$module | ||
.on('focus' + eventNamespace, selector.search, module.event.searchFocus) | ||
.on('blur' + eventNamespace, selector.search, module.event.searchBlur) | ||
.on('mousedown' + eventNamespace, selector.menu, module.event.menu.activate) | ||
.on('mouseup' + eventNamespace, selector.menu, module.event.menu.deactivate) | ||
.on('click' + eventNamespace, selector.search, module.show) | ||
.on('focus' + eventNamespace, selector.search, module.event.searchFocus) | ||
.on('blur' + eventNamespace, selector.search, module.event.searchBlur) | ||
.on('click' + eventNamespace, selector.text, module.event.searchTextFocus) | ||
; | ||
@@ -320,11 +366,9 @@ } | ||
$module | ||
.on('mousedown', module.event.mousedown) | ||
.on('mouseup', module.event.mouseup) | ||
.on('focus' + eventNamespace, module.event.focus) | ||
.on('blur' + eventNamespace, module.event.blur) | ||
.on('mousedown' + eventNamespace, module.event.mousedown) | ||
.on('mouseup' + eventNamespace, module.event.mouseup) | ||
.on('focus' + eventNamespace, module.event.focus) | ||
.on('blur' + eventNamespace, module.event.blur) | ||
; | ||
} | ||
$module | ||
.on('mousedown' + eventNamespace, selector.item, module.event.item.mousedown) | ||
.on('mouseup' + eventNamespace, selector.item, module.event.item.mouseup) | ||
$menu | ||
.on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter) | ||
@@ -339,8 +383,8 @@ .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave) | ||
$document | ||
.on('touchstart' + eventNamespace, module.event.test.touch) | ||
.on('touchmove' + eventNamespace, module.event.test.touch) | ||
.on('touchstart' + elementNamespace, module.event.test.touch) | ||
.on('touchmove' + elementNamespace, module.event.test.touch) | ||
; | ||
} | ||
$document | ||
.on('click' + eventNamespace, module.event.test.hide) | ||
.on('click' + elementNamespace, module.event.test.hide) | ||
; | ||
@@ -355,8 +399,8 @@ } | ||
$document | ||
.off('touchstart' + eventNamespace) | ||
.off('touchmove' + eventNamespace) | ||
.off('touchstart' + elementNamespace) | ||
.off('touchmove' + elementNamespace) | ||
; | ||
} | ||
$document | ||
.off('click' + eventNamespace) | ||
.off('click' + elementNamespace) | ||
; | ||
@@ -369,6 +413,8 @@ } | ||
$results = $(), | ||
exactRegExp = new RegExp('(?:\s|^)' + searchTerm, 'i'), | ||
fullTextRegExp = new RegExp(searchTerm, 'i'), | ||
$filteredItems | ||
escapedTerm = module.escape.regExp(searchTerm), | ||
exactRegExp = new RegExp('^' + escapedTerm, 'igm'), | ||
fullTextRegExp = new RegExp(escapedTerm, 'ig'), | ||
allItemsFiltered | ||
; | ||
module.verbose('Searching for matching values'); | ||
$item | ||
@@ -378,18 +424,10 @@ .each(function(){ | ||
$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 = String(module.get.choiceText($choice, false)), | ||
value = String(module.get.choiceValue($choice, text)) | ||
; | ||
if( exactRegExp.test( text ) || exactRegExp.test( value ) ) { | ||
if( text.match(exactRegExp) || value.match(exactRegExp) ) { | ||
$results = $results.add($choice); | ||
} | ||
else if(settings.fullTextSearch) { | ||
if( fullTextRegExp.test( text ) || fullTextRegExp.test( value ) ) { | ||
if( text.match(fullTextRegExp) || value.match(fullTextRegExp) ) { | ||
$results = $results.add($choice); | ||
@@ -400,8 +438,12 @@ } | ||
; | ||
$filteredItems = $item.not($results); | ||
module.debug('Setting filter', searchTerm); | ||
module.remove.filteredItem(); | ||
module.remove.selectedItem(); | ||
$filteredItems | ||
$item | ||
.not($results) | ||
.addClass(className.filtered) | ||
; | ||
module.verbose('Selecting first non-filtered element'); | ||
module.remove.selectedItem(); | ||
$item | ||
@@ -412,4 +454,33 @@ .not('.' + className.filtered) | ||
; | ||
if( module.is.allFiltered() ) { | ||
module.debug('All items filtered, hiding dropdown', searchTerm); | ||
if(module.is.searchSelection()) { | ||
module.hide(); | ||
} | ||
settings.onNoResults.call(element, searchTerm); | ||
} | ||
}, | ||
focusSearch: function() { | ||
if( module.is.search() ) { | ||
$search | ||
.focus() | ||
; | ||
} | ||
}, | ||
forceSelection: function() { | ||
var | ||
$currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0), | ||
$activeItem = $item.filter('.' + className.active).eq(0), | ||
$selectedItem = ($currentlySelected.length > 0) | ||
? $currentlySelected | ||
: $activeItem, | ||
hasSelected = ($selectedItem.size() > 0) | ||
; | ||
if(hasSelected) { | ||
module.event.item.click.call($selectedItem); | ||
} | ||
}, | ||
event: { | ||
@@ -424,3 +495,3 @@ // prevents focus callback from occuring on mousedown | ||
focus: function() { | ||
if(!activated) { | ||
if(!activated && module.is.hidden()) { | ||
module.show(); | ||
@@ -430,3 +501,6 @@ } | ||
blur: function(event) { | ||
if(!activated) { | ||
var | ||
pageLostFocus = (document.activeElement === this) | ||
; | ||
if(!activated && !pageLostFocus) { | ||
module.hide(); | ||
@@ -440,69 +514,114 @@ } | ||
searchBlur: function(event) { | ||
if(!itemActivated) { | ||
module.hide(); | ||
var | ||
pageLostFocus = (document.activeElement === this) | ||
; | ||
if(!itemActivated && !pageLostFocus) { | ||
if(settings.forceSelection) { | ||
module.forceSelection(); | ||
} | ||
else { | ||
module.hide(); | ||
} | ||
} | ||
}, | ||
searchTextFocus: function(event) { | ||
activated = true; | ||
$search.focus(); | ||
}, | ||
input: function(event) { | ||
var | ||
query = $search.val() | ||
; | ||
if(module.is.searchSelection()) { | ||
$text.addClass(className.filtered); | ||
module.set.filtered(); | ||
} | ||
module.filter(query); | ||
clearTimeout(module.timer); | ||
module.timer = setTimeout(module.search, settings.delay.search); | ||
}, | ||
keydown: function(event) { | ||
var | ||
$selectedItem = $item.not(className.filtered).filter('.' + className.selected).eq(0), | ||
$visibleItems = $item.not('.' + className.filtered), | ||
$currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0), | ||
$activeItem = $menu.children('.' + className.active).eq(0), | ||
$selectedItem = ($currentlySelected.length > 0) | ||
? $currentlySelected | ||
: $activeItem, | ||
$visibleItems = ($selectedItem.length > 0) | ||
? $selectedItem.siblings(':not(.' + className.filtered +')').andSelf() | ||
: $menu.children(':not(.' + className.filtered +')'), | ||
$subMenu = $selectedItem.children(selector.menu), | ||
$parentMenu = $selectedItem.closest(selector.menu), | ||
isSubMenuItem = $parentMenu[0] !== $menu[0], | ||
inVisibleMenu = $parentMenu.is(':visible'), | ||
pressedKey = event.which, | ||
keys = { | ||
enter : 13, | ||
escape : 27, | ||
upArrow : 38, | ||
downArrow : 40 | ||
enter : 13, | ||
escape : 27, | ||
leftArrow : 37, | ||
upArrow : 38, | ||
rightArrow : 39, | ||
downArrow : 40 | ||
}, | ||
selectedClass = className.selected, | ||
currentIndex = $visibleItems.index( $selectedItem ), | ||
hasSelectedItem = ($selectedItem.size() > 0), | ||
hasSubMenu = ($subMenu.length> 0), | ||
hasSelectedItem = ($selectedItem.length > 0), | ||
lastVisibleIndex = ($visibleItems.size() - 1), | ||
$nextItem, | ||
newIndex | ||
; | ||
// default to activated choice if no selection present | ||
if(!hasSelectedItem) { | ||
$selectedItem = $item.filter('.' + className.active).eq(0); | ||
hasSelectedItem = ($selectedItem.size() > 0); | ||
} | ||
// close shortcuts | ||
if(pressedKey == keys.escape) { | ||
module.verbose('Escape key pressed, closing dropdown'); | ||
$search.blur(); | ||
module.hide(); | ||
} | ||
// result shortcuts | ||
// visible menu keyboard shortcuts | ||
if(module.is.visible()) { | ||
// enter (select or sub-menu) | ||
if(pressedKey == keys.enter && hasSelectedItem) { | ||
module.verbose('Enter key pressed, choosing selected item'); | ||
if(module.is.searchable()) { | ||
module.verbose('Removing focus from search input'); | ||
$search.blur(); | ||
if(hasSubMenu && !settings.allowCategorySelection) { | ||
module.verbose('Pressed enter on unselectable category, opening sub menu'); | ||
pressedKey = keys.rightArrow; | ||
} | ||
$.proxy(module.event.item.click, $selectedItem)(event); | ||
else { | ||
module.verbose('Enter key pressed, choosing selected item'); | ||
module.event.item.click.call($selectedItem, event); | ||
} | ||
} | ||
// left arrow (hide sub-menu) | ||
if(pressedKey == keys.leftArrow) { | ||
if(isSubMenuItem) { | ||
module.verbose('Left key pressed, closing sub-menu'); | ||
module.animate.hide(false, $parentMenu); | ||
$selectedItem | ||
.removeClass(className.selected) | ||
; | ||
$parentMenu | ||
.closest(selector.item) | ||
.addClass(className.selected) | ||
; | ||
} | ||
event.preventDefault(); | ||
return false; | ||
} | ||
else if(pressedKey == keys.upArrow) { | ||
if(!hasSelectedItem) { | ||
$nextItem = $visibleItems.eq(0); | ||
// right arrow (show sub-menu) | ||
if(pressedKey == keys.rightArrow) { | ||
if(hasSubMenu) { | ||
module.verbose('Right key pressed, opening sub-menu'); | ||
module.animate.show(false, $subMenu); | ||
$selectedItem | ||
.removeClass(className.selected) | ||
; | ||
$subMenu | ||
.find(selector.item).eq(0) | ||
.addClass(className.selected) | ||
; | ||
} | ||
event.preventDefault(); | ||
} | ||
// up arrow (traverse menu up) | ||
if(pressedKey == keys.upArrow) { | ||
$nextItem = (hasSelectedItem && inVisibleMenu) | ||
? $selectedItem.prevAll(selector.item + ':not(.' + className.filtered + ')').eq(0) | ||
: $item.eq(0) | ||
; | ||
if($visibleItems.index( $nextItem ) < 0) { | ||
module.verbose('Up key pressed but reached top of current menu'); | ||
return; | ||
} | ||
else { | ||
$nextItem = $selectedItem.prevAll(selector.item + ':not(.' + className.filtered + ')').eq(0); | ||
} | ||
if(currentIndex !== 0) { | ||
module.verbose('Up key pressed, changing active item'); | ||
$item | ||
.removeClass(selectedClass) | ||
$selectedItem | ||
.removeClass(className.selected) | ||
; | ||
$nextItem | ||
.addClass(selectedClass) | ||
.addClass(className.selected) | ||
; | ||
@@ -513,16 +632,19 @@ module.set.scrollPosition($nextItem); | ||
} | ||
else if(pressedKey == keys.downArrow) { | ||
if(!hasSelectedItem) { | ||
$nextItem = $visibleItems.eq(0); | ||
// down arrow (traverse menu down) | ||
if(pressedKey == keys.downArrow) { | ||
$nextItem = (hasSelectedItem && inVisibleMenu) | ||
? $nextItem = $selectedItem.nextAll(selector.item + ':not(.' + className.filtered + ')').eq(0) | ||
: $item.eq(0) | ||
; | ||
if($nextItem.length === 0) { | ||
module.verbose('Down key pressed but reached bottom of current menu'); | ||
return; | ||
} | ||
else { | ||
$nextItem = $selectedItem.nextAll(selector.item + ':not(.' + className.filtered + ')').eq(0); | ||
} | ||
if(currentIndex + 1 < $visibleItems.size() ) { | ||
module.verbose('Down key pressed, changing active item'); | ||
$item | ||
.removeClass(selectedClass) | ||
.removeClass(className.selected) | ||
; | ||
$nextItem | ||
.addClass(selectedClass) | ||
.addClass(className.selected) | ||
; | ||
@@ -535,5 +657,17 @@ module.set.scrollPosition($nextItem); | ||
else { | ||
// enter (open menu) | ||
if(pressedKey == keys.enter) { | ||
module.verbose('Enter key pressed, showing dropdown'); | ||
module.show(); | ||
} | ||
// escape (close menu) | ||
if(pressedKey == keys.escape) { | ||
module.verbose('Escape key pressed, closing dropdown'); | ||
module.hide(); | ||
} | ||
// down arrow (open menu) | ||
if(pressedKey == keys.downArrow) { | ||
module.verbose('Down key pressed, showing dropdown'); | ||
module.show(); | ||
} | ||
} | ||
@@ -563,75 +697,64 @@ }, | ||
item: { | ||
mousedown: function() { | ||
menu: { | ||
activate: function() { | ||
itemActivated = true; | ||
}, | ||
mouseup: function() { | ||
deactivate: function() { | ||
itemActivated = false; | ||
}, | ||
} | ||
}, | ||
item: { | ||
mouseenter: function(event) { | ||
var | ||
$currentMenu = $(this).find(selector.menu), | ||
$otherMenus = $(this).siblings(selector.item).children(selector.menu) | ||
$subMenu = $(this).children(selector.menu), | ||
$otherMenus = $(this).siblings(selector.item).children(selector.menu) | ||
; | ||
if( $currentMenu.size() > 0 ) { | ||
if( $subMenu.length > 0 ) { | ||
clearTimeout(module.itemTimer); | ||
module.itemTimer = setTimeout(function() { | ||
module.animate.hide(false, $otherMenus); | ||
module.verbose('Showing sub-menu', $currentMenu); | ||
module.animate.show(false, $currentMenu); | ||
}, settings.delay.show * 2); | ||
module.verbose('Showing sub-menu', $subMenu); | ||
$.each($otherMenus, function() { | ||
module.animate.hide(false, $(this)); | ||
}); | ||
module.animate.show(false, $subMenu); | ||
}, settings.delay.show); | ||
event.preventDefault(); | ||
} | ||
}, | ||
mouseleave: function(event) { | ||
var | ||
$currentMenu = $(this).find(selector.menu) | ||
$subMenu = $(this).children(selector.menu) | ||
; | ||
if($currentMenu.size() > 0) { | ||
if($subMenu.length > 0) { | ||
clearTimeout(module.itemTimer); | ||
module.itemTimer = setTimeout(function() { | ||
module.verbose('Hiding sub-menu', $currentMenu); | ||
module.animate.hide(false, $currentMenu); | ||
module.verbose('Hiding sub-menu', $subMenu); | ||
module.animate.hide(false, $subMenu); | ||
}, settings.delay.hide); | ||
} | ||
}, | ||
click: function (event) { | ||
var | ||
$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, | ||
$choice = $(this), | ||
$target = (event) | ||
? $(event.target) | ||
: $(''), | ||
$subMenu = $choice.find(selector.menu), | ||
text = module.get.choiceText($choice), | ||
value = module.get.choiceValue($choice, text), | ||
callback = function() { | ||
$search.val(''); | ||
module.remove.searchTerm(); | ||
module.determine.selectAction(text, value); | ||
$.proxy(settings.onChange, element)(value, text, $choice); | ||
}, | ||
openingSubMenu = ($choice.find(selector.menu).size() > 0) | ||
hasSubMenu = ($subMenu.length > 0), | ||
isBubbledEvent = ($subMenu.find($target).length > 0) | ||
; | ||
if( !openingSubMenu ) { | ||
if(event.type == 'touchstart') { | ||
$choice.one('click', callback); | ||
} | ||
else { | ||
callback(); | ||
} | ||
if(!isBubbledEvent && (!hasSubMenu || settings.allowCategorySelection)) { | ||
callback(); | ||
} | ||
} | ||
}, | ||
resetStyle: function() { | ||
$(this).removeAttr('style'); | ||
} | ||
}, | ||
@@ -655,4 +778,7 @@ | ||
eventInModule: function(event, callback) { | ||
callback = callback || function(){}; | ||
if( $(event.target).closest($module).size() === 0 ) { | ||
callback = $.isFunction(callback) | ||
? callback | ||
: function(){} | ||
; | ||
if( $(event.target).closest($module).length === 0 ) { | ||
module.verbose('Triggering event', callback); | ||
@@ -668,4 +794,7 @@ callback(); | ||
eventInMenu: function(event, callback) { | ||
callback = callback || function(){}; | ||
if( $(event.target).closest($menu).size() === 0 ) { | ||
callback = $.isFunction(callback) | ||
? callback | ||
: function(){} | ||
; | ||
if( $(event.target).closest($menu).length === 0 ) { | ||
module.verbose('Triggering event', callback); | ||
@@ -686,7 +815,3 @@ callback(); | ||
hide: function() { | ||
module.hide(); | ||
}, | ||
select: function(text, value) { | ||
activate: function(text, value) { | ||
value = (value !== undefined) | ||
@@ -697,7 +822,8 @@ ? value | ||
module.set.selected(value); | ||
module.set.value(value); | ||
module.hide(); | ||
module.hide(function() { | ||
module.remove.filteredItem(); | ||
}); | ||
}, | ||
activate: function(text, value) { | ||
select: function(text, value) { | ||
value = (value !== undefined) | ||
@@ -708,4 +834,5 @@ ? value | ||
module.set.selected(value); | ||
module.set.value(value); | ||
module.hide(); | ||
module.hide(function() { | ||
module.remove.filteredItem(); | ||
}); | ||
}, | ||
@@ -719,4 +846,11 @@ | ||
module.set.selected(value); | ||
module.set.value(value); | ||
module.hide(); | ||
module.hide(function() { | ||
module.remove.filteredItem(); | ||
}); | ||
}, | ||
hide: function() { | ||
module.hide(function() { | ||
module.remove.filteredItem(); | ||
}); | ||
} | ||
@@ -731,3 +865,3 @@ | ||
value: function() { | ||
return ($input.size() > 0) | ||
return ($input.length > 0) | ||
? $input.val() | ||
@@ -737,2 +871,31 @@ : $module.data(metadata.value) | ||
}, | ||
choiceText: function($choice, preserveHTML) { | ||
preserveHTML = (preserveHTML !== undefined) | ||
? preserveHTML | ||
: settings.preserveHTML | ||
; | ||
if($choice !== undefined) { | ||
if($choice.find(selector.menu).length > 0) { | ||
module.verbose('Retreiving text of element with sub-menu'); | ||
$choice = $choice.clone(); | ||
$choice.find(selector.menu).remove(); | ||
$choice.find(selector.menuIcon).remove(); | ||
} | ||
return ($choice.data(metadata.text) !== undefined) | ||
? $choice.data(metadata.text) | ||
: (preserveHTML) | ||
? $choice.html().trim() | ||
: $choice.text().trim() | ||
; | ||
} | ||
}, | ||
choiceValue: function($choice, choiceText) { | ||
choiceText = choiceText || module.get.choiceText($choice); | ||
return ($choice.data(metadata.value) !== undefined) | ||
? $choice.data(metadata.value) | ||
: (typeof choiceText === 'string') | ||
? choiceText.toLowerCase().trim() | ||
: choiceText.trim() | ||
; | ||
}, | ||
inputEvent: function() { | ||
@@ -754,6 +917,8 @@ var | ||
var | ||
select = { | ||
values : {} | ||
} | ||
select = {} | ||
; | ||
select.values = (settings.sortSelect) | ||
? {} // properties will be sorted in object when re-accessed | ||
: [] // properties will keep original order in array | ||
; | ||
$module | ||
@@ -772,9 +937,28 @@ .find('option') | ||
else { | ||
select.values[value] = name; | ||
if(settings.sortSelect) { | ||
select.values[value] = { | ||
name : name, | ||
value : value | ||
}; | ||
} | ||
else { | ||
select.values.push({ | ||
name: name, | ||
value: value | ||
}); | ||
} | ||
} | ||
}) | ||
; | ||
module.debug('Retrieved values from select', select); | ||
if(settings.sortSelect) { | ||
module.debug('Retrieved and sorted values from select', select); | ||
} | ||
else { | ||
module.debug('Retreived values from select', select); | ||
} | ||
return select; | ||
}, | ||
activeItem: function() { | ||
return $item.filter('.' + className.active); | ||
}, | ||
item: function(value, strict) { | ||
@@ -799,15 +983,7 @@ var | ||
$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) { | ||
module.debug('Ambiguous dropdown value using strict type check', value); | ||
module.verbose('Ambiguous dropdown value using strict type check', $choice, value); | ||
if( optionValue === value ) { | ||
@@ -837,2 +1013,5 @@ $selectedItem = $(this); | ||
return $selectedItem || false; | ||
}, | ||
uniqueID: function() { | ||
return (Math.random().toString(16) + '000000000').substr(2,8); | ||
} | ||
@@ -852,2 +1031,3 @@ }, | ||
module.set.text(defaultText); | ||
$text.addClass(className.placeholder); | ||
}, | ||
@@ -860,4 +1040,9 @@ defaultValue: function() { | ||
module.debug('Restoring default value', defaultValue); | ||
module.set.selected(defaultValue); | ||
module.set.value(defaultValue); | ||
if(defaultValue.length) { | ||
module.set.selected(defaultValue); | ||
} | ||
else { | ||
module.remove.activeItem(); | ||
module.remove.selectedItem(); | ||
} | ||
} | ||
@@ -870,2 +1055,3 @@ } | ||
module.save.defaultText(); | ||
module.save.placeholderText(); | ||
module.save.defaultValue(); | ||
@@ -878,11 +1064,61 @@ }, | ||
$module.data(metadata.defaultText, $text.text() ); | ||
}, | ||
placeholderText: function() { | ||
if($text.hasClass(className.placeholder)) { | ||
$module.data(metadata.placeholderText, $text.text()); | ||
} | ||
} | ||
}, | ||
clear: function() { | ||
var | ||
placeholderText = $module.data(metadata.placeholderText) | ||
; | ||
module.set.text(placeholderText); | ||
module.set.value(''); | ||
module.remove.activeItem(); | ||
module.remove.selectedItem(); | ||
$text.addClass(className.placeholder); | ||
}, | ||
set: { | ||
scrollPosition: function($item) { | ||
filtered: function() { | ||
var | ||
$item = $item || module.get.item(), | ||
hasActive = ($item && $item.size() > 0), | ||
searchValue = $search.val(), | ||
hasSearchValue = (typeof searchValue === 'string' && searchValue.length > 0) | ||
; | ||
if(hasSearchValue) { | ||
$text.addClass(className.filtered); | ||
} | ||
else { | ||
$text.removeClass(className.filtered); | ||
} | ||
}, | ||
tabbable: function() { | ||
if( module.is.searchable() ) { | ||
module.debug('Searchable dropdown initialized'); | ||
$search | ||
.val('') | ||
.attr('tabindex', 0) | ||
; | ||
$menu | ||
.attr('tabindex', '-1') | ||
; | ||
} | ||
else { | ||
module.debug('Simple selection dropdown initialized'); | ||
if(!$module.attr('tabindex') ) { | ||
$module | ||
.attr('tabindex', 0) | ||
; | ||
$menu | ||
.attr('tabindex', '-1') | ||
; | ||
} | ||
} | ||
}, | ||
scrollPosition: function($item, forceScroll) { | ||
var | ||
edgeTolerance = 5, | ||
hasActive, | ||
offset, | ||
@@ -897,3 +1133,16 @@ itemHeight, | ||
; | ||
$item = $item || module.get.activeItem(); | ||
hasActive = ($item && $item.length > 0); | ||
forceScroll = (forceScroll !== undefined) | ||
? forceScroll | ||
: false | ||
; | ||
if($item && hasActive) { | ||
if(!$menu.hasClass(className.visible)) { | ||
$menu.addClass(className.loading); | ||
} | ||
menuHeight = $menu.height(); | ||
@@ -907,6 +1156,7 @@ itemHeight = $item.height(); | ||
abovePage = ((offset - edgeTolerance) < menuScroll); | ||
if(abovePage || belowPage) { | ||
module.debug('Scrolling to active item'); | ||
module.debug('Scrolling to active item', offset); | ||
if(abovePage || belowPage || forceScroll) { | ||
$menu | ||
.scrollTop(offset) | ||
.removeClass(className.loading) | ||
; | ||
@@ -942,3 +1192,3 @@ } | ||
module.debug('Adding selected value to hidden input', value, $input); | ||
if($input.size() > 0) { | ||
if($input.length > 0) { | ||
$input | ||
@@ -964,12 +1214,7 @@ .val(value) | ||
$selectedItem = module.get.item(value), | ||
selectedText | ||
selectedText, | ||
selectedValue | ||
; | ||
if($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(); | ||
@@ -981,3 +1226,7 @@ module.remove.selectedItem(); | ||
; | ||
selectedText = module.get.choiceText($selectedItem); | ||
selectedValue = module.get.choiceValue($selectedItem, selectedText); | ||
module.set.text(selectedText); | ||
module.set.value(selectedValue); | ||
settings.onChange.call(element, value, selectedText, $selectedItem); | ||
} | ||
@@ -1000,4 +1249,27 @@ } | ||
}, | ||
searchTerm: function() { | ||
$search.val(''); | ||
}, | ||
selectedItem: function() { | ||
$item.removeClass(className.selected); | ||
}, | ||
tabbable: function() { | ||
if( module.is.searchable() ) { | ||
module.debug('Searchable dropdown initialized'); | ||
$search | ||
.attr('tabindex', '-1') | ||
; | ||
$menu | ||
.attr('tabindex', '-1') | ||
; | ||
} | ||
else { | ||
module.debug('Simple selection dropdown initialized'); | ||
$module | ||
.attr('tabindex', '-1') | ||
; | ||
$menu | ||
.attr('tabindex', '-1') | ||
; | ||
} | ||
} | ||
@@ -1007,2 +1279,35 @@ }, | ||
is: { | ||
active: function() { | ||
return $module.hasClass(className.active); | ||
}, | ||
alreadySetup: function() { | ||
return ($module.is('select') && $module.parent(selector.dropdown).length > 0); | ||
}, | ||
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() { | ||
return ($item.filter('.' + className.filtered).length === $item.length); | ||
}, | ||
hidden: function($subMenu) { | ||
return ($subMenu) | ||
? $subMenu.is(':hidden') | ||
: $menu.is(':hidden') | ||
; | ||
}, | ||
selectMutation: function(mutations) { | ||
var | ||
selectChanged = false | ||
; | ||
$.each(mutations, function(index, mutation) { | ||
if(mutation.target && $(mutation.target).is('select')) { | ||
selectChanged = true; | ||
return true; | ||
} | ||
}); | ||
return selectChanged; | ||
}, | ||
search: function() { | ||
@@ -1012,3 +1317,3 @@ return $module.hasClass(className.search); | ||
searchable: function() { | ||
return ($search.size() > 0); | ||
return ($search.length > 0); | ||
}, | ||
@@ -1021,11 +1326,5 @@ searchSelection: function() { | ||
}, | ||
animated: function($subMenu) { | ||
return ($subMenu) | ||
? $subMenu.is(':animated') || $subMenu.transition && $subMenu.transition('is animating') | ||
: $menu.is(':animated') || $menu.transition && $menu.transition('is animating') | ||
; | ||
upward: function() { | ||
return $module.hasClass(className.upward); | ||
}, | ||
active: function() { | ||
return $module.hasClass(className.active); | ||
}, | ||
visible: function($subMenu) { | ||
@@ -1036,8 +1335,2 @@ return ($subMenu) | ||
; | ||
}, | ||
hidden: function($subMenu) { | ||
return ($subMenu) | ||
? $subMenu.is(':hidden') | ||
: $menu.is(':hidden') | ||
; | ||
} | ||
@@ -1062,12 +1355,24 @@ }, | ||
: function() { | ||
module.hideSubMenus(); | ||
module.hideOthers(); | ||
module.set.active(); | ||
module.set.scrollPosition(); | ||
} | ||
; | ||
callback = callback || function(){}; | ||
callback = $.isFunction(callback) | ||
? callback | ||
: function(){} | ||
; | ||
module.set.scrollPosition(module.get.activeItem(), true); | ||
module.verbose('Doing menu show animation', $currentMenu); | ||
if( module.is.hidden($currentMenu) ) { | ||
if( module.is.hidden($currentMenu) || module.is.animating($currentMenu) ) { | ||
if(settings.transition == 'auto') { | ||
settings.transition = module.is.upward() | ||
? 'slide up' | ||
: 'slide down' | ||
; | ||
module.verbose('Automatically determining animation based on animation direction', settings.transition); | ||
} | ||
if(settings.transition == 'none') { | ||
$.proxy(callback, element)(); | ||
callback.call(element); | ||
} | ||
@@ -1077,8 +1382,10 @@ else if($.fn.transition !== undefined && $module.transition('is supported')) { | ||
.transition({ | ||
animation : settings.transition + ' in', | ||
duration : settings.duration, | ||
queue : true, | ||
start : start, | ||
complete : function() { | ||
$.proxy(callback, element)(); | ||
animation : settings.transition + ' in', | ||
debug : settings.debug, | ||
verbose : settings.verbose, | ||
duration : settings.duration, | ||
queue : true, | ||
onStart : start, | ||
onComplete : function() { | ||
callback.call(element); | ||
} | ||
@@ -1102,4 +1409,4 @@ }) | ||
.slideDown(100, 'easeOutQuad', function() { | ||
$.proxy(module.event.resetStyle, this)(); | ||
$.proxy(callback, element)(); | ||
module.event.resetStyle.call(this); | ||
callback.call(element); | ||
}) | ||
@@ -1114,4 +1421,4 @@ ; | ||
.fadeIn(settings.duration, function() { | ||
$.proxy(module.event.resetStyle, this)(); | ||
$.proxy(callback, element)(); | ||
module.event.resetStyle.call(this); | ||
callback.call(element); | ||
}) | ||
@@ -1128,2 +1435,5 @@ ; | ||
$currentMenu = $subMenu || $menu, | ||
duration = ($subMenu) | ||
? (settings.duration * 0.9) | ||
: settings.duration, | ||
start = ($subMenu) | ||
@@ -1135,12 +1445,24 @@ ? function() {} | ||
} | ||
module.hideSubMenus(); | ||
module.focusSearch(); | ||
module.remove.active(); | ||
} | ||
; | ||
callback = callback || function(){}; | ||
if( module.is.visible($currentMenu) ) { | ||
callback = $.isFunction(callback) | ||
? callback | ||
: function(){} | ||
; | ||
if( module.is.visible($currentMenu) || module.is.animating($currentMenu) ) { | ||
module.verbose('Doing menu hide animation', $currentMenu); | ||
if(settings.transition == 'auto') { | ||
settings.transition = module.is.upward() | ||
? 'slide up' | ||
: 'slide down' | ||
; | ||
} | ||
$input.trigger('blur'); | ||
if(settings.transition == 'none') { | ||
$.proxy(callback, element)(); | ||
callback.call(element); | ||
} | ||
@@ -1150,8 +1472,10 @@ else if($.fn.transition !== undefined && $module.transition('is supported')) { | ||
.transition({ | ||
animation : settings.transition + ' out', | ||
duration : settings.duration, | ||
queue : true, | ||
start : start, | ||
complete : function() { | ||
$.proxy(callback, element)(); | ||
animation : settings.transition + ' out', | ||
duration : settings.duration, | ||
debug : settings.debug, | ||
verbose : settings.verbose, | ||
queue : true, | ||
onStart : start, | ||
onComplete : function() { | ||
callback.call(element); | ||
} | ||
@@ -1175,4 +1499,4 @@ }) | ||
.slideUp(100, 'easeOutQuad', function() { | ||
$.proxy(module.event.resetStyle, this)(); | ||
$.proxy(callback, element)(); | ||
module.event.resetStyle.call(this); | ||
callback.call(element); | ||
}) | ||
@@ -1187,4 +1511,4 @@ ; | ||
.fadeOut(150, function() { | ||
$.proxy(module.event.resetStyle, this)(); | ||
$.proxy(callback, element)(); | ||
module.event.resetStyle.call(this); | ||
callback.call(element); | ||
}) | ||
@@ -1213,2 +1537,9 @@ ; | ||
escape: { | ||
regExp: function(text) { | ||
text = String(text); | ||
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); | ||
} | ||
}, | ||
setting: function(name, value) { | ||
@@ -1378,3 +1709,3 @@ module.debug('Changing setting', name, value); | ||
if(instance !== undefined) { | ||
module.destroy(); | ||
instance.invoke('destroy'); | ||
} | ||
@@ -1394,28 +1725,34 @@ module.initialize(); | ||
debug : false, | ||
verbose : true, | ||
performance : true, | ||
debug : false, | ||
verbose : true, | ||
performance : true, | ||
on : 'click', | ||
action : 'activate', | ||
on : 'click', | ||
action : 'activate', | ||
allowTab : true, | ||
fullTextSearch : true, | ||
preserveHTML : true, | ||
allowTab : true, | ||
fullTextSearch : false, | ||
preserveHTML : true, | ||
sortSelect : false, | ||
delay : { | ||
show : 200, | ||
hide : 300, | ||
touch : 50 | ||
allowCategorySelection : false, | ||
delay : { | ||
hide : 300, | ||
show : 200, | ||
search : 50, | ||
touch : 50 | ||
}, | ||
transition : 'slide down', | ||
forceSelection: true, | ||
transition : 'auto', | ||
duration : 250, | ||
/* Callbacks */ | ||
onNoResults : function(searchTerm){}, | ||
onChange : function(value, text){}, | ||
onShow : function(){}, | ||
onHide : function(){}, | ||
onChange : function(value, text){}, | ||
onShow : function(){}, | ||
onHide : function(){}, | ||
/* Component */ | ||
@@ -1427,12 +1764,14 @@ | ||
error : { | ||
action : 'You called a dropdown action that was not defined', | ||
method : 'The method you called is not defined.', | ||
transition : 'The requested transition was not found' | ||
action : 'You called a dropdown action that was not defined', | ||
alreadySetup : 'Once a select has been initialized behaviors must be called on the created ui dropdown', | ||
method : 'The method you called is not defined.', | ||
transition : 'The requested transition was not found' | ||
}, | ||
metadata: { | ||
defaultText : 'defaultText', | ||
defaultValue : 'defaultValue', | ||
text : 'text', | ||
value : 'value' | ||
defaultText : 'defaultText', | ||
defaultValue : 'defaultValue', | ||
placeholderText : 'placeholderText', | ||
text : 'text', | ||
value : 'value' | ||
}, | ||
@@ -1442,7 +1781,8 @@ | ||
dropdown : '.ui.dropdown', | ||
text : '> .text:not(.icon)', | ||
input : '> input[type="hidden"], > select', | ||
search : '> .search, .menu > .search > input, .menu > input.search', | ||
item : '.item', | ||
menu : '.menu', | ||
item : '.item' | ||
menuIcon : '.dropdown.icon', | ||
search : '> input.search, .menu > .search > input, .menu > input.search', | ||
text : '> .text:not(.icon)' | ||
}, | ||
@@ -1456,2 +1796,3 @@ | ||
filtered : 'filtered', | ||
loading : 'loading', | ||
menu : 'menu', | ||
@@ -1462,2 +1803,3 @@ placeholder : 'default', | ||
selection : 'selection', | ||
upward : 'upward', | ||
visible : 'visible' | ||
@@ -1476,9 +1818,4 @@ } | ||
; | ||
$.each(select.values, function(value, name) { | ||
if(value === name) { | ||
html += '<div class="item">' + name + '</div>'; | ||
} | ||
else { | ||
html += '<div class="item" data-value="' + value + '">' + name + '</div>'; | ||
} | ||
$.each(select.values, function(index, option) { | ||
html += '<div class="item" data-value="' + option.value + '">' + option.name + '</div>'; | ||
}); | ||
@@ -1501,9 +1838,4 @@ return html; | ||
html += '<div class="menu">'; | ||
$.each(select.values, function(value, name) { | ||
if(value === name) { | ||
html += '<div class="item">' + name + '</div>'; | ||
} | ||
else { | ||
html += '<div class="item" data-value="' + value + '">' + name + '</div>'; | ||
} | ||
$.each(select.values, function(index, option) { | ||
html += '<div class="item" data-value="' + option.value + '">' + option.name + '</div>'; | ||
}); | ||
@@ -1524,2 +1856,2 @@ html += '</div>'; | ||
})( require("jquery"), window , document ); | ||
})( require("jquery"), window , document ); |
{ | ||
"name": "semantic-ui-dropdown", | ||
"version": "1.0.0", | ||
"version": "1.9.0", | ||
"title": "Semantic UI - Dropdown", | ||
@@ -11,3 +11,3 @@ "description": "Single component release of dropdown", | ||
"type": "git", | ||
"url": "git@github.com:Semantic-Org/UI-Dropdown.git" | ||
"url": "https://github.com/Semantic-Org/UI-Dropdown.git" | ||
}, | ||
@@ -17,7 +17,3 @@ "bugs": { | ||
}, | ||
"dependencies": { | ||
"jquery": "x.x.x" | ||
}, | ||
"devDependencies": {}, | ||
"main": "index.js" | ||
"devDependencies": {} | ||
} |
@@ -19,6 +19,12 @@ # Semantic Dropdown | ||
#### To install with Meteor | ||
``` | ||
meteor add semantic:ui-dropdown | ||
``` | ||
## Addendum | ||
This element's definitions (required class names, html structures) are available in the [Beta UI Docs](http://beta.semantic-ui.com) | ||
This element's definitions (required class names, html structures) are available in the [UI Docs](http://www.semantic-ui.com) | ||
Please consider checking out [all the benefits to theming](http://learnsemantic.com/guide/expert.html) before using these stand-alone releases. | ||
Please consider checking out [all the benefits to theming](http://www.learnsemantic.com/guide/expert.html) before using these stand-alone releases. |
@@ -1,3 +0,82 @@ | ||
### Version 1.0.0 - XX XX, 2014 | ||
### UI Changes | ||
- **Input** - Input with dropdowns is now much easier, see docs. `action input` and `labeled input` now use `display: flex`. `ui action input` now supports `<button>` tag usage (!) which support `flex` but not `table-cell` | ||
- **Dropdown** - `search selection dropdown` will now close the menu when a `dropdown icon` is clicked | ||
- **Dropdown** - Added new dropdown setting, `forceSelection` which forces `search selection` to a selected value on blur. Defaults to `true`. | ||
- **Form Validation** - Dropdown and checkbox will now validate after interaction with `on: 'blur'` | ||
- **Form** - Lightened error dropdown hover text color to be more legible | ||
- **Dropdown** - Upward dropdown now has upward arrow icon | ||
### Version 1.8.1 - January 26, 2015 | ||
- **Input** - `ui labeled input` now uses `flex` added example in ui docs with dropdown | ||
### Version 1.8.0 - January 23, 2015 | ||
- **Dropdown** - Dropdown now stores `placeholder text` (prompt text) as separate from `default text` (text set on page load). You can now reset placeholder conditions using `$('.ui.dropdown').dropdown('clear');`` | ||
- **Dropdown** - Keyboard navigation will now allow opening of sub menus with right/left arrow. Enter will open sub-menus on an unselectable category (`allowCategorySelection: false`) as well. | ||
- **Dropdown** - Mutation observers will now observe changed in `<select>` values after initialization, and will automatically update dropdown menu when changed | ||
- **Dropdown** - Dropdown behavior `set selected` will now also call `set value` automatically, so you do not have to invoke two behaviors to update a `selection dropdown` **Thanks @mktm** | ||
- **Dropdown** - Dropdown no longer will not show menu when no `item` are present in menu. Dropdown will now only filter results for `ui search dropdown` #1632 **Thanks PSyton**. | ||
- **Dropdown** - Dropdown will now produce an error if behaviors on an initialized `<select>` are not invoked on `ui dropdown` | ||
- **Dropdown** - Fixed bug where link items would not open in sub-menus due to `event.preventDefault` | ||
- **Label** - Fixed `ui corner label` appearing on-top of `ui dropdown` menu due to issue in z-index heirarchy | ||
### Version 1.7.0 - January 14, 2015 | ||
- **Dropdown** - Javascript Dropdown can now be disabled by adding ``disabled` class. No need to call `destroy`. **Thanks Psyton** | ||
- **Dropdown** - Search dropdown input can now have backgrounds. Fixes issues with autocompleted search dropdowns which have forced yellow "autocompleted" bg. | ||
- **Dropdown** - Fix issue with search selection not correctly matching when values are not strings | ||
- **Dropdown** - New `upward dropdown` variation, which opens its menu upward. Default animation now uses ``settings.transition = 'auto'` and determines direction of animation based on menu direction | ||
- **Dropdown** - Dropdown matching fields without values now trims whitespace by default | ||
- **Dropdown** - `restore defaults` will now set placeholder styling and remove active elemenet. Added example in docs. | ||
- **Dropdown** - Fixed bug where sub menus may sometimes have dropdown icon overlap text | ||
- **Dropdown** - Fixes dropdown search input from filtering text values when input is inside menu, i.e "In-Menu Search" | ||
- **Dropdown** - Fix issue with search selection not correctly creating RegExp when select values are not strings **Thanks @alufers** | ||
- **Dropdown** - Fix issue with `left floated` and `right floated` content sometimes not applying correctly | ||
### Version 1.6.0 - January 05, 2015 | ||
- **Form** - ``ui search dropdown`` inside a form has incorrect focus style | ||
### Version 1.5.0 - December 30, 2014 | ||
- **Dropdown** - New setting ``allowCategorySelection`` lets menu items with sub menus be selected. Added example in docs. | ||
- **Dropdown/Search** - Fixed issues with ``ui search`` and ``ui search dropdown`` using ``RegExp test`` which [advances pointer on match](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) causing results to display incorrectly | ||
### Version 1.4.1 - December 23, 2014 | ||
- **Dropdown** - ``<select>`` elements will now preserve original ``<option>`` order by default. Added ``sortSelect`` setting (disabled by default) to automatically sort ``<option>`` on initialization | ||
- **Button** - Fixes issue with ``will-change`` property added to ``ui button`` causing layout z-indexing issues (dropdown button) | ||
### Version 1.4.0 - December 22, 2014 | ||
- **Menu** - Fix border radius of dropdown menu inside `ui vertical menu` | ||
- **Menu** - Fix formatting of ``ui selection dropdown`` inside ``menu`` | ||
### Version 1.3.0 - December 17, 2014 | ||
- **Dropdown** - Dropdown can now specify which direction a menu should appear left/right, dropdown icons can also appear on the left | ||
- **Dropdown** - Full text search now defaults to ``false``, meaning search terms will return only results beginning with letters | ||
- **Dropdown** - Search Dropdown is now much more responsive, js improvements and input throttling added.Throttling defaults to `50ms` and can be modified with settings ``delay.search`` | ||
- **Dropdown** - Search Dropdown now correctly replaces placeholder text when backspacing to empty value | ||
- **Dropdown** - Search Dropdown now has a callback when all results filtered ``onNoResults`` | ||
- **Dropdown** - Search dropdown will now strip html before searching values when searching html | ||
- **Dropdown** - Search now has keyboard shortcut to open dropdown on arrow down | ||
- **Dropdown** - Dropdown now always scrolls to active element on menu open, calculates position with new ``loading`` class | ||
- **Dropdown** - Fix bug in position of sub menus with ``floating dropdown`` | ||
- **All UI** - Adds error message when triggering an invalid module behavior i.e. typos ``$('.dropdown').dropdown('hid');`` | ||
### Version 1.2.0 - December 08, 2014 | ||
- **Dropdown** - Fixes bug with dropdown converted from ``select`` that use ``<option`` values with capital letters not being selectable | ||
- Fixed documentation on dropdown actions, form field widths, form validation types, and many odds & ends | ||
### Version 1.1.0 - December 02, 2014 | ||
- **Dropdown** - Dropdown ``onChange`` callback now fires when calling ``setSelected`` programatically. | ||
- **Dropdown** - Fix ``action input`` used inside ``ui dropdown`` to appear correctly **Thanks ordepdev** | ||
### Version 1.0.0 - November 24, 2014 | ||
- **Dropdown** - Sub menus inside dropdowns now need a wrapping div **text** around sub-menu descriptions | ||
@@ -10,2 +89,14 @@ - **Dropdown** - New dropdown type, searchable selection for large lists of choices | ||
### Version 0.18.0 - June 6, 2014 | ||
- **Dropdown** - Fixes dropdown 'is animating' with dropdowns when CSS animations were not included **Thanks nathankot** | ||
### Version 0.17.0 - May 9, 2014 | ||
- **Dropdown** - Dropdowns can now receive focus and be navigated with a keyboard **Thanks Musatov** | ||
### Version 0.15.1 - Mar 14, 2014 | ||
- **Dropdown** - Typo in dropdown css was causing selection dropdowns not to appear | ||
### Version 0.15.0 - Mar 14, 2014 | ||
@@ -12,0 +103,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Wildcard dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
Found 1 instance in 1 package
200790
0
11
4430
1
30
1
- Removedjquery@x.x.x
- Removedjquery@3.7.1(transitive)