You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1658 lines
52 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. /*
  2. * # Semantic - Dropdown
  3. * http://github.com/semantic-org/semantic-ui/
  4. *
  5. *
  6. * Copyright 2014 Contributor
  7. * Released under the MIT license
  8. * http://opensource.org/licenses/MIT
  9. *
  10. */
  11. ;(function ( $, window, document, undefined ) {
  12. "use strict";
  13. $.fn.dropdown = function(parameters) {
  14. var
  15. $allModules = $(this),
  16. $document = $(document),
  17. moduleSelector = $allModules.selector || '',
  18. hasTouch = ('ontouchstart' in document.documentElement),
  19. time = new Date().getTime(),
  20. performance = [],
  21. query = arguments[0],
  22. methodInvoked = (typeof query == 'string'),
  23. queryArguments = [].slice.call(arguments, 1),
  24. returnedValue
  25. ;
  26. $allModules
  27. .each(function() {
  28. var
  29. settings = ( $.isPlainObject(parameters) )
  30. ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
  31. : $.extend({}, $.fn.dropdown.settings),
  32. className = settings.className,
  33. metadata = settings.metadata,
  34. namespace = settings.namespace,
  35. selector = settings.selector,
  36. error = settings.error,
  37. eventNamespace = '.' + namespace,
  38. moduleNamespace = 'module-' + namespace,
  39. $module = $(this),
  40. $text = $module.find(selector.text),
  41. $search = $module.find(selector.search),
  42. $input = $module.find(selector.input),
  43. $combo = ($module.prev().find(selector.text).length > 0)
  44. ? $module.prev().find(selector.text)
  45. : $module.prev(),
  46. $menu = $module.children(selector.menu),
  47. $item = $menu.find(selector.item),
  48. activated = false,
  49. itemActivated = false,
  50. element = this,
  51. instance = $module.data(moduleNamespace),
  52. elementNamespace,
  53. id,
  54. observer,
  55. module
  56. ;
  57. module = {
  58. initialize: function() {
  59. module.debug('Initializing dropdown', settings);
  60. module.setup.layout();
  61. module.save.defaults();
  62. module.set.selected();
  63. module.create.id();
  64. if(hasTouch) {
  65. module.bind.touchEvents();
  66. }
  67. module.bind.mouseEvents();
  68. module.bind.keyboardEvents();
  69. module.observeChanges();
  70. module.instantiate();
  71. },
  72. instantiate: function() {
  73. module.verbose('Storing instance of dropdown', module);
  74. instance = module;
  75. $module
  76. .data(moduleNamespace, module)
  77. ;
  78. },
  79. destroy: function() {
  80. module.verbose('Destroying previous dropdown for', $module);
  81. module.remove.tabbable();
  82. $module
  83. .off(eventNamespace)
  84. .removeData(moduleNamespace)
  85. ;
  86. $document
  87. .off(elementNamespace)
  88. ;
  89. },
  90. observeChanges: function() {
  91. if('MutationObserver' in window) {
  92. observer = new MutationObserver(function(mutations) {
  93. module.debug('DOM tree modified, updating selector cache');
  94. module.refresh();
  95. });
  96. observer.observe(element, {
  97. childList : true,
  98. subtree : true
  99. });
  100. module.debug('Setting up mutation observer', observer);
  101. }
  102. },
  103. create: {
  104. id: function() {
  105. module.verbose('Creating unique id for element');
  106. id = module.get.uniqueID();
  107. elementNamespace = '.' + id;
  108. }
  109. },
  110. search: function() {
  111. var
  112. query
  113. ;
  114. query = $search.val();
  115. module.verbose('Searching for query', query);
  116. module.filter(query);
  117. if(module.is.searchSelection() && module.can.show() ) {
  118. module.show();
  119. }
  120. },
  121. setup: {
  122. layout: function() {
  123. if( $module.is('select') ) {
  124. module.setup.select();
  125. }
  126. if( module.is.search() && !module.is.searchable() ) {
  127. $search = $('<input />')
  128. .addClass(className.search)
  129. .insertBefore($text)
  130. ;
  131. }
  132. if(settings.allowTab) {
  133. module.set.tabbable();
  134. }
  135. },
  136. select: function() {
  137. var
  138. selectValues = module.get.selectValues()
  139. ;
  140. module.debug('Dropdown initialized on a select', selectValues);
  141. // see if select exists inside a dropdown
  142. $input = $module;
  143. if($input.parents(selector.dropdown).length > 0) {
  144. module.debug('Creating dropdown menu only from template');
  145. $module = $input.closest(selector.dropdown);
  146. if($module.find('.' + className.dropdown).length === 0) {
  147. $('<div />')
  148. .addClass(className.menu)
  149. .html( settings.templates.menu( selectValues ))
  150. .appendTo($module)
  151. ;
  152. }
  153. }
  154. else {
  155. module.debug('Creating entire dropdown from template');
  156. $module = $('<div />')
  157. .attr('class', $input.attr('class') )
  158. .addClass(className.selection)
  159. .addClass(className.dropdown)
  160. .html( settings.templates.dropdown(selectValues) )
  161. .insertBefore($input)
  162. ;
  163. $input
  164. .removeAttr('class')
  165. .prependTo($module)
  166. ;
  167. }
  168. module.refresh();
  169. }
  170. },
  171. refresh: function() {
  172. $text = $module.find(selector.text);
  173. $search = $module.find(selector.search);
  174. $input = $module.find(selector.input);
  175. $menu = $module.children(selector.menu);
  176. $item = $menu.find(selector.item);
  177. },
  178. toggle: function() {
  179. module.verbose('Toggling menu visibility');
  180. if( !module.is.active() ) {
  181. module.show();
  182. }
  183. else {
  184. module.hide();
  185. }
  186. },
  187. show: function(callback) {
  188. callback = $.isFunction(callback)
  189. ? callback
  190. : function(){}
  191. ;
  192. if( module.can.show() && !module.is.active() && !module.is.allFiltered() ) {
  193. module.debug('Showing dropdown');
  194. module.animate.show(function() {
  195. if( module.can.click() ) {
  196. module.bind.intent();
  197. }
  198. module.set.visible();
  199. callback.call(element);
  200. });
  201. settings.onShow.call(element);
  202. }
  203. },
  204. hide: function(callback) {
  205. callback = $.isFunction(callback)
  206. ? callback
  207. : function(){}
  208. ;
  209. if( module.is.active() ) {
  210. module.debug('Hiding dropdown');
  211. module.animate.hide(function() {
  212. module.remove.visible();
  213. callback.call(element);
  214. });
  215. settings.onHide.call(element);
  216. }
  217. },
  218. hideOthers: function() {
  219. module.verbose('Finding other dropdowns to hide');
  220. $allModules
  221. .not($module)
  222. .has(selector.menu + ':visible:not(.' + className.animating + ')')
  223. .dropdown('hide')
  224. ;
  225. },
  226. hideSubMenus: function() {
  227. var
  228. $subMenus = $menu.find(selector.menu)
  229. ;
  230. $subMenus.transition('hide');
  231. },
  232. bind: {
  233. keyboardEvents: function() {
  234. module.debug('Binding keyboard events');
  235. $module
  236. .on('keydown' + eventNamespace, module.event.keydown)
  237. ;
  238. if( module.is.searchable() ) {
  239. $module
  240. .on(module.get.inputEvent(), selector.search, module.event.input)
  241. ;
  242. }
  243. },
  244. touchEvents: function() {
  245. module.debug('Touch device detected binding additional touch events');
  246. if( module.is.searchSelection() ) {
  247. // do nothing special yet
  248. }
  249. else {
  250. $module
  251. .on('touchstart' + eventNamespace, module.event.test.toggle)
  252. ;
  253. }
  254. $menu
  255. .on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter)
  256. ;
  257. },
  258. mouseEvents: function() {
  259. module.verbose('Mouse detected binding mouse events');
  260. if( module.is.searchSelection() ) {
  261. $module
  262. .on('mousedown' + eventNamespace, selector.menu, module.event.menu.activate)
  263. .on('mouseup' + eventNamespace, selector.menu, module.event.menu.deactivate)
  264. .on('click' + eventNamespace, selector.search, module.show)
  265. .on('focus' + eventNamespace, selector.search, module.event.searchFocus)
  266. .on('blur' + eventNamespace, selector.search, module.event.searchBlur)
  267. .on('click' + eventNamespace, selector.text, module.event.searchTextFocus)
  268. ;
  269. }
  270. else {
  271. if(settings.on == 'click') {
  272. $module
  273. .on('click' + eventNamespace, module.event.test.toggle)
  274. ;
  275. }
  276. else if(settings.on == 'hover') {
  277. $module
  278. .on('mouseenter' + eventNamespace, module.delay.show)
  279. .on('mouseleave' + eventNamespace, module.delay.hide)
  280. ;
  281. }
  282. else {
  283. $module
  284. .on(settings.on + eventNamespace, module.toggle)
  285. ;
  286. }
  287. $module
  288. .on('mousedown' + eventNamespace, module.event.mousedown)
  289. .on('mouseup' + eventNamespace, module.event.mouseup)
  290. .on('focus' + eventNamespace, module.event.focus)
  291. .on('blur' + eventNamespace, module.event.blur)
  292. ;
  293. }
  294. $menu
  295. .on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter)
  296. .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave)
  297. .on('click' + eventNamespace, selector.item, module.event.item.click)
  298. ;
  299. },
  300. intent: function() {
  301. module.verbose('Binding hide intent event to document');
  302. if(hasTouch) {
  303. $document
  304. .on('touchstart' + elementNamespace, module.event.test.touch)
  305. .on('touchmove' + elementNamespace, module.event.test.touch)
  306. ;
  307. }
  308. $document
  309. .on('click' + elementNamespace, module.event.test.hide)
  310. ;
  311. }
  312. },
  313. unbind: {
  314. intent: function() {
  315. module.verbose('Removing hide intent event from document');
  316. if(hasTouch) {
  317. $document
  318. .off('touchstart' + elementNamespace)
  319. .off('touchmove' + elementNamespace)
  320. ;
  321. }
  322. $document
  323. .off('click' + elementNamespace)
  324. ;
  325. }
  326. },
  327. filter: function(searchTerm) {
  328. var
  329. $results = $(),
  330. escapedTerm = module.escape.regExp(searchTerm),
  331. exactRegExp = new RegExp('^' + escapedTerm, 'igm'),
  332. fullTextRegExp = new RegExp(escapedTerm, 'ig'),
  333. allItemsFiltered
  334. ;
  335. module.verbose('Searching for matching values');
  336. $item
  337. .each(function(){
  338. var
  339. $choice = $(this),
  340. text = String(module.get.choiceText($choice, false)),
  341. value = String(module.get.choiceValue($choice, text))
  342. ;
  343. if( text.match(exactRegExp) || value.match(exactRegExp) ) {
  344. $results = $results.add($choice);
  345. }
  346. else if(settings.fullTextSearch) {
  347. if( text.match(fullTextRegExp) || value.match(fullTextRegExp) ) {
  348. $results = $results.add($choice);
  349. }
  350. }
  351. })
  352. ;
  353. module.debug('Setting filter', searchTerm);
  354. module.remove.filteredItem();
  355. $item
  356. .not($results)
  357. .addClass(className.filtered)
  358. ;
  359. module.verbose('Selecting first non-filtered element');
  360. module.remove.selectedItem();
  361. $item
  362. .not('.' + className.filtered)
  363. .eq(0)
  364. .addClass(className.selected)
  365. ;
  366. if( module.is.allFiltered() ) {
  367. module.debug('All items filtered, hiding dropdown', searchTerm);
  368. if(module.is.searchSelection()) {
  369. module.hide();
  370. }
  371. settings.onNoResults.call(element, searchTerm);
  372. }
  373. },
  374. focusSearch: function() {
  375. if( module.is.search() ) {
  376. $search
  377. .focus()
  378. ;
  379. }
  380. },
  381. event: {
  382. // prevents focus callback from occuring on mousedown
  383. mousedown: function() {
  384. activated = true;
  385. },
  386. mouseup: function() {
  387. activated = false;
  388. },
  389. focus: function() {
  390. if(!activated && module.is.hidden()) {
  391. module.show();
  392. }
  393. },
  394. blur: function(event) {
  395. var
  396. pageLostFocus = (document.activeElement === this)
  397. ;
  398. if(!activated && !pageLostFocus) {
  399. module.hide();
  400. }
  401. },
  402. searchFocus: function() {
  403. activated = true;
  404. module.show();
  405. },
  406. searchBlur: function(event) {
  407. var
  408. pageLostFocus = (document.activeElement === this)
  409. ;
  410. if(!itemActivated && !pageLostFocus) {
  411. module.hide();
  412. }
  413. },
  414. searchTextFocus: function(event) {
  415. activated = true;
  416. $search.focus();
  417. },
  418. input: function(event) {
  419. if(module.is.searchSelection()) {
  420. module.set.filtered();
  421. }
  422. clearTimeout(module.timer);
  423. module.timer = setTimeout(module.search, settings.delay.search);
  424. },
  425. keydown: function(event) {
  426. var
  427. $selectedItem = $item.not(className.filtered).filter('.' + className.selected).eq(0),
  428. $visibleItems = $item.not('.' + className.filtered),
  429. pressedKey = event.which,
  430. keys = {
  431. enter : 13,
  432. escape : 27,
  433. upArrow : 38,
  434. downArrow : 40
  435. },
  436. selectedClass = className.selected,
  437. currentIndex = $visibleItems.index( $selectedItem ),
  438. hasSelectedItem = ($selectedItem.length > 0),
  439. $nextItem,
  440. newIndex
  441. ;
  442. // default to activated choice if no selection present
  443. if(!hasSelectedItem) {
  444. $selectedItem = $item.filter('.' + className.active).eq(0);
  445. hasSelectedItem = ($selectedItem.length > 0);
  446. }
  447. // close shortcuts
  448. if(pressedKey == keys.escape) {
  449. module.verbose('Escape key pressed, closing dropdown');
  450. module.hide();
  451. }
  452. // open menu
  453. if(pressedKey == keys.downArrow) {
  454. module.verbose('Down key pressed, showing dropdown');
  455. module.show();
  456. }
  457. // result shortcuts
  458. if(module.is.visible()) {
  459. if(pressedKey == keys.enter && hasSelectedItem) {
  460. module.verbose('Enter key pressed, choosing selected item');
  461. module.event.item.click.call($selectedItem, event);
  462. event.preventDefault();
  463. return false;
  464. }
  465. else if(pressedKey == keys.upArrow) {
  466. if(!hasSelectedItem) {
  467. $nextItem = $visibleItems.eq(0);
  468. }
  469. else {
  470. $nextItem = $selectedItem.prevAll(selector.item + ':not(.' + className.filtered + ')').eq(0);
  471. }
  472. if(currentIndex !== 0) {
  473. module.verbose('Up key pressed, changing active item');
  474. $item
  475. .removeClass(selectedClass)
  476. ;
  477. $nextItem
  478. .addClass(selectedClass)
  479. ;
  480. module.set.scrollPosition($nextItem);
  481. }
  482. event.preventDefault();
  483. }
  484. else if(pressedKey == keys.downArrow) {
  485. if(!hasSelectedItem) {
  486. $nextItem = $visibleItems.eq(0);
  487. }
  488. else {
  489. $nextItem = $selectedItem.nextAll(selector.item + ':not(.' + className.filtered + ')').eq(0);
  490. }
  491. if(currentIndex + 1 < $visibleItems.length ) {
  492. module.verbose('Down key pressed, changing active item');
  493. $item
  494. .removeClass(selectedClass)
  495. ;
  496. $nextItem
  497. .addClass(selectedClass)
  498. ;
  499. module.set.scrollPosition($nextItem);
  500. }
  501. event.preventDefault();
  502. }
  503. }
  504. else {
  505. if(pressedKey == keys.enter) {
  506. module.show();
  507. }
  508. }
  509. },
  510. test: {
  511. toggle: function(event) {
  512. if( module.determine.eventInMenu(event, module.toggle) ) {
  513. event.preventDefault();
  514. }
  515. },
  516. touch: function(event) {
  517. module.determine.eventInMenu(event, function() {
  518. if(event.type == 'touchstart') {
  519. module.timer = setTimeout(module.hide, settings.delay.touch);
  520. }
  521. else if(event.type == 'touchmove') {
  522. clearTimeout(module.timer);
  523. }
  524. });
  525. event.stopPropagation();
  526. },
  527. hide: function(event) {
  528. module.determine.eventInModule(event, module.hide);
  529. }
  530. },
  531. menu: {
  532. activate: function() {
  533. itemActivated = true;
  534. },
  535. deactivate: function() {
  536. itemActivated = false;
  537. }
  538. },
  539. item: {
  540. mouseenter: function(event) {
  541. var
  542. $currentMenu = $(this).children(selector.menu),
  543. $otherMenus = $(this).siblings(selector.item).children(selector.menu)
  544. ;
  545. if( $currentMenu.length > 0 ) {
  546. clearTimeout(module.itemTimer);
  547. module.itemTimer = setTimeout(function() {
  548. $.each($otherMenus, function() {
  549. module.animate.hide(false, $(this));
  550. });
  551. module.verbose('Showing sub-menu', $currentMenu);
  552. module.animate.show(false, $currentMenu);
  553. }, settings.delay.show);
  554. event.preventDefault();
  555. }
  556. },
  557. mouseleave: function(event) {
  558. var
  559. $currentMenu = $(this).children(selector.menu)
  560. ;
  561. if($currentMenu.length > 0) {
  562. clearTimeout(module.itemTimer);
  563. module.itemTimer = setTimeout(function() {
  564. module.verbose('Hiding sub-menu', $currentMenu);
  565. module.animate.hide(false, $currentMenu);
  566. }, settings.delay.hide);
  567. }
  568. },
  569. click: function (event) {
  570. var
  571. $choice = $(this),
  572. $target = $(event.target),
  573. $subMenu = $choice.find(selector.menu),
  574. text = module.get.choiceText($choice),
  575. value = module.get.choiceValue($choice, text),
  576. callback = function() {
  577. module.remove.searchTerm();
  578. module.determine.selectAction(text, value);
  579. },
  580. openingSubMenu = ($subMenu.length > 0),
  581. isSubItem = ($subMenu.find($target).length > 0)
  582. ;
  583. if(isSubItem) {
  584. return false;
  585. }
  586. if(!openingSubMenu || settings.allowCategorySelection) {
  587. callback();
  588. }
  589. }
  590. },
  591. resetStyle: function() {
  592. $(this).removeAttr('style');
  593. }
  594. },
  595. determine: {
  596. selectAction: function(text, value) {
  597. module.verbose('Determining action', settings.action);
  598. if( $.isFunction( module.action[settings.action] ) ) {
  599. module.verbose('Triggering preset action', settings.action, text, value);
  600. module.action[ settings.action ](text, value);
  601. }
  602. else if( $.isFunction(settings.action) ) {
  603. module.verbose('Triggering user action', settings.action, text, value);
  604. settings.action(text, value);
  605. }
  606. else {
  607. module.error(error.action, settings.action);
  608. }
  609. },
  610. eventInModule: function(event, callback) {
  611. callback = $.isFunction(callback)
  612. ? callback
  613. : function(){}
  614. ;
  615. if( $(event.target).closest($module).length === 0 ) {
  616. module.verbose('Triggering event', callback);
  617. callback();
  618. return true;
  619. }
  620. else {
  621. module.verbose('Event occurred in dropdown, canceling callback');
  622. return false;
  623. }
  624. },
  625. eventInMenu: function(event, callback) {
  626. callback = $.isFunction(callback)
  627. ? callback
  628. : function(){}
  629. ;
  630. if( $(event.target).closest($menu).length === 0 ) {
  631. module.verbose('Triggering event', callback);
  632. callback();
  633. return true;
  634. }
  635. else {
  636. module.verbose('Event occurred in dropdown menu, canceling callback');
  637. return false;
  638. }
  639. }
  640. },
  641. action: {
  642. nothing: function() {},
  643. hide: function() {
  644. module.hide(function() {
  645. module.remove.filteredItem();
  646. });
  647. },
  648. select: function(text, value) {
  649. value = (value !== undefined)
  650. ? value
  651. : text
  652. ;
  653. module.set.selected(value);
  654. module.set.value(value);
  655. module.hide(function() {
  656. module.remove.filteredItem();
  657. });
  658. },
  659. activate: function(text, value) {
  660. value = (value !== undefined)
  661. ? value
  662. : text
  663. ;
  664. module.set.selected(value);
  665. module.set.value(value);
  666. module.hide(function() {
  667. module.remove.filteredItem();
  668. });
  669. },
  670. combo: function(text, value) {
  671. value = (value !== undefined)
  672. ? value
  673. : text
  674. ;
  675. module.set.selected(value);
  676. module.set.value(value);
  677. module.hide(function() {
  678. module.remove.filteredItem();
  679. });
  680. }
  681. },
  682. get: {
  683. text: function() {
  684. return $text.text();
  685. },
  686. value: function() {
  687. return ($input.length > 0)
  688. ? $input.val()
  689. : $module.data(metadata.value)
  690. ;
  691. },
  692. choiceText: function($choice, preserveHTML) {
  693. preserveHTML = (preserveHTML !== undefined)
  694. ? preserveHTML
  695. : settings.preserveHTML
  696. ;
  697. if($choice !== undefined) {
  698. if($choice.find(selector.menu).length > 0) {
  699. module.verbose('Retreiving text of element with sub-menu');
  700. $choice = $choice.clone();
  701. $choice.find(selector.menu).remove();
  702. $choice.find(selector.menuIcon).remove();
  703. }
  704. return ($choice.data(metadata.text) !== undefined)
  705. ? $choice.data(metadata.text)
  706. : (preserveHTML)
  707. ? $choice.html().trim()
  708. : $choice.text().trim()
  709. ;
  710. }
  711. },
  712. choiceValue: function($choice, choiceText) {
  713. choiceText = choiceText || module.get.choiceText($text);
  714. return ($choice.data(metadata.value) !== undefined)
  715. ? $choice.data(metadata.value)
  716. : (typeof choiceText === 'string')
  717. ? choiceText.toLowerCase().trim()
  718. : choiceText.trim()
  719. ;
  720. },
  721. inputEvent: function() {
  722. var
  723. input = $search[0]
  724. ;
  725. if(input) {
  726. return (input.oninput !== undefined)
  727. ? 'input'
  728. : (input.onpropertychange !== undefined)
  729. ? 'propertychange'
  730. : 'keyup'
  731. ;
  732. }
  733. return false;
  734. },
  735. selectValues: function() {
  736. var
  737. select = {}
  738. ;
  739. select.values = (settings.sortSelect)
  740. ? {} // properties will be sorted in object when re-accessed
  741. : [] // properties will keep original order in array
  742. ;
  743. $module
  744. .find('option')
  745. .each(function() {
  746. var
  747. name = $(this).html(),
  748. value = ( $(this).attr('value') !== undefined )
  749. ? $(this).attr('value')
  750. : name
  751. ;
  752. if(value === '') {
  753. select.placeholder = name;
  754. }
  755. else {
  756. if(settings.sortSelect) {
  757. select.values[value] = {
  758. name : name,
  759. value : value
  760. };
  761. }
  762. else {
  763. select.values.push({
  764. name: name,
  765. value: value
  766. });
  767. }
  768. }
  769. })
  770. ;
  771. if(settings.sortSelect) {
  772. module.debug('Retrieved and sorted values from select', select);
  773. }
  774. else {
  775. module.debug('Retreived values from select', select);
  776. }
  777. return select;
  778. },
  779. activeItem: function() {
  780. return $item.filter('.' + className.active);
  781. },
  782. item: function(value, strict) {
  783. var
  784. $selectedItem = false
  785. ;
  786. value = (value !== undefined)
  787. ? value
  788. : ( module.get.value() !== undefined)
  789. ? module.get.value()
  790. : module.get.text()
  791. ;
  792. strict = (value === '' || value === 0)
  793. ? true
  794. : strict || false
  795. ;
  796. if(value !== undefined) {
  797. $item
  798. .each(function() {
  799. var
  800. $choice = $(this),
  801. optionText = module.get.choiceText($choice),
  802. optionValue = module.get.choiceValue($choice, optionText)
  803. ;
  804. if(strict) {
  805. module.verbose('Ambiguous dropdown value using strict type check', $choice, value);
  806. if( optionValue === value ) {
  807. $selectedItem = $(this);
  808. }
  809. else if( !$selectedItem && optionText === value ) {
  810. $selectedItem = $(this);
  811. }
  812. }
  813. else {
  814. if( optionValue == value ) {
  815. module.verbose('Found select item by value', optionValue, value);
  816. $selectedItem = $(this);
  817. }
  818. else if( !$selectedItem && optionText == value ) {
  819. module.verbose('Found select item by text', optionText, value);
  820. $selectedItem = $(this);
  821. }
  822. }
  823. })
  824. ;
  825. }
  826. else {
  827. value = module.get.text();
  828. }
  829. return $selectedItem || false;
  830. },
  831. uniqueID: function() {
  832. return (Math.random().toString(16) + '000000000').substr(2,8);
  833. }
  834. },
  835. restore: {
  836. defaults: function() {
  837. module.restore.defaultText();
  838. module.restore.defaultValue();
  839. },
  840. defaultText: function() {
  841. var
  842. defaultText = $module.data(metadata.defaultText)
  843. ;
  844. module.debug('Restoring default text', defaultText);
  845. module.set.text(defaultText);
  846. $text.addClass(settings.className.placeholder);
  847. },
  848. defaultValue: function() {
  849. var
  850. defaultValue = $module.data(metadata.defaultValue)
  851. ;
  852. if(defaultValue !== undefined) {
  853. module.debug('Restoring default value', defaultValue);
  854. if(defaultValue.length) {
  855. module.set.selected(defaultValue);
  856. module.set.value(defaultValue);
  857. }
  858. else {
  859. module.remove.activeItem();
  860. module.remove.selectedItem();
  861. }
  862. }
  863. }
  864. },
  865. save: {
  866. defaults: function() {
  867. module.save.defaultText();
  868. module.save.defaultValue();
  869. },
  870. defaultValue: function() {
  871. $module.data(metadata.defaultValue, module.get.value() );
  872. },
  873. defaultText: function() {
  874. $module.data(metadata.defaultText, $text.text() );
  875. }
  876. },
  877. set: {
  878. filtered: function() {
  879. var
  880. searchValue = $search.val(),
  881. hasSearchValue = (typeof searchValue === 'string' && searchValue.length > 0)
  882. ;
  883. if(hasSearchValue) {
  884. $text.addClass(className.filtered);
  885. }
  886. else {
  887. $text.removeClass(className.filtered);
  888. }
  889. },
  890. tabbable: function() {
  891. if( module.is.searchable() ) {
  892. module.debug('Searchable dropdown initialized');
  893. $search
  894. .val('')
  895. .attr('tabindex', 0)
  896. ;
  897. $menu
  898. .attr('tabindex', '-1')
  899. ;
  900. }
  901. else {
  902. module.debug('Simple selection dropdown initialized');
  903. if(!$module.attr('tabindex') ) {
  904. $module
  905. .attr('tabindex', 0)
  906. ;
  907. $menu
  908. .attr('tabindex', '-1')
  909. ;
  910. }
  911. }
  912. },
  913. scrollPosition: function($item, forceScroll) {
  914. var
  915. edgeTolerance = 5,
  916. hasActive,
  917. offset,
  918. itemHeight,
  919. itemOffset,
  920. menuOffset,
  921. menuScroll,
  922. menuHeight,
  923. abovePage,
  924. belowPage
  925. ;
  926. $item = $item || module.get.activeItem();
  927. hasActive = ($item && $item.length > 0);
  928. forceScroll = (forceScroll !== undefined)
  929. ? forceScroll
  930. : false
  931. ;
  932. if($item && hasActive) {
  933. if(!$menu.hasClass(className.visible)) {
  934. $menu.addClass(className.loading);
  935. }
  936. menuHeight = $menu.height();
  937. itemHeight = $item.height();
  938. menuScroll = $menu.scrollTop();
  939. menuOffset = $menu.offset().top;
  940. itemOffset = $item.offset().top;
  941. offset = menuScroll - menuOffset + itemOffset;
  942. belowPage = menuScroll + menuHeight < (offset + edgeTolerance);
  943. abovePage = ((offset - edgeTolerance) < menuScroll);
  944. module.debug('Scrolling to active item', offset);
  945. if(abovePage || belowPage || forceScroll) {
  946. $menu
  947. .scrollTop(offset)
  948. .removeClass(className.loading)
  949. ;
  950. }
  951. }
  952. },
  953. text: function(text) {
  954. if(settings.action == 'combo') {
  955. module.debug('Changing combo button text', text, $combo);
  956. if(settings.preserveHTML) {
  957. $combo.html(text);
  958. }
  959. else {
  960. $combo.text(text);
  961. }
  962. }
  963. else if(settings.action !== 'select') {
  964. module.debug('Changing text', text, $text);
  965. $text
  966. .removeClass(className.filtered)
  967. .removeClass(className.placeholder)
  968. ;
  969. if(settings.preserveHTML) {
  970. $text.html(text);
  971. }
  972. else {
  973. $text.text(text);
  974. }
  975. }
  976. },
  977. value: function(value) {
  978. module.debug('Adding selected value to hidden input', value, $input);
  979. if($input.length > 0) {
  980. $input
  981. .val(value)
  982. .trigger('change')
  983. ;
  984. }
  985. else {
  986. $module.data(metadata.value, value);
  987. }
  988. },
  989. active: function() {
  990. $module
  991. .addClass(className.active)
  992. ;
  993. },
  994. visible: function() {
  995. $module.addClass(className.visible);
  996. },
  997. selected: function(value) {
  998. var
  999. $selectedItem = module.get.item(value),
  1000. selectedText
  1001. ;
  1002. if($selectedItem) {
  1003. module.debug('Setting selected menu item to', $selectedItem);
  1004. module.remove.activeItem();
  1005. module.remove.selectedItem();
  1006. $selectedItem
  1007. .addClass(className.active)
  1008. .addClass(className.selected)
  1009. ;
  1010. selectedText = module.get.choiceText($selectedItem);
  1011. module.set.text(selectedText);
  1012. settings.onChange.call(element, value, selectedText, $selectedItem);
  1013. }
  1014. }
  1015. },
  1016. remove: {
  1017. active: function() {
  1018. $module.removeClass(className.active);
  1019. },
  1020. visible: function() {
  1021. $module.removeClass(className.visible);
  1022. },
  1023. activeItem: function() {
  1024. $item.removeClass(className.active);
  1025. },
  1026. filteredItem: function() {
  1027. $item.removeClass(className.filtered);
  1028. },
  1029. searchTerm: function() {
  1030. $search.val('');
  1031. },
  1032. selectedItem: function() {
  1033. $item.removeClass(className.selected);
  1034. },
  1035. tabbable: function() {
  1036. if( module.is.searchable() ) {
  1037. module.debug('Searchable dropdown initialized');
  1038. $search
  1039. .attr('tabindex', '-1')
  1040. ;
  1041. $menu
  1042. .attr('tabindex', '-1')
  1043. ;
  1044. }
  1045. else {
  1046. module.debug('Simple selection dropdown initialized');
  1047. $module
  1048. .attr('tabindex', '-1')
  1049. ;
  1050. $menu
  1051. .attr('tabindex', '-1')
  1052. ;
  1053. }
  1054. }
  1055. },
  1056. is: {
  1057. active: function() {
  1058. return $module.hasClass(className.active);
  1059. },
  1060. animating: function($subMenu) {
  1061. return ($subMenu)
  1062. ? $subMenu.is(':animated') || $subMenu.transition && $subMenu.transition('is animating')
  1063. : $menu.is(':animated') || $menu.transition && $menu.transition('is animating')
  1064. ;
  1065. },
  1066. allFiltered: function() {
  1067. return ($item.filter('.' + className.filtered).length === $item.length);
  1068. },
  1069. hidden: function($subMenu) {
  1070. return ($subMenu)
  1071. ? $subMenu.is(':hidden')
  1072. : $menu.is(':hidden')
  1073. ;
  1074. },
  1075. search: function() {
  1076. return $module.hasClass(className.search);
  1077. },
  1078. searchable: function() {
  1079. return ($search.length > 0);
  1080. },
  1081. searchSelection: function() {
  1082. return ( module.is.searchable() && $search.parent().is($module) );
  1083. },
  1084. selection: function() {
  1085. return $module.hasClass(className.selection);
  1086. },
  1087. upward: function() {
  1088. return $module.hasClass(className.upward);
  1089. },
  1090. visible: function($subMenu) {
  1091. return ($subMenu)
  1092. ? $subMenu.is(':visible')
  1093. : $menu.is(':visible')
  1094. ;
  1095. }
  1096. },
  1097. can: {
  1098. click: function() {
  1099. return (hasTouch || settings.on == 'click');
  1100. },
  1101. show: function() {
  1102. return !$module.hasClass(className.disabled);
  1103. }
  1104. },
  1105. animate: {
  1106. show: function(callback, $subMenu) {
  1107. var
  1108. $currentMenu = $subMenu || $menu,
  1109. start = ($subMenu)
  1110. ? function() {}
  1111. : function() {
  1112. module.hideSubMenus();
  1113. module.hideOthers();
  1114. module.set.active();
  1115. }
  1116. ;
  1117. callback = $.isFunction(callback)
  1118. ? callback
  1119. : function(){}
  1120. ;
  1121. module.set.scrollPosition(module.get.activeItem(), true);
  1122. module.verbose('Doing menu show animation', $currentMenu);
  1123. if( module.is.hidden($currentMenu) || module.is.animating($currentMenu) ) {
  1124. if(settings.transition == 'auto') {
  1125. settings.transition = module.is.upward()
  1126. ? 'slide up'
  1127. : 'slide down'
  1128. ;
  1129. }
  1130. if(settings.transition == 'none') {
  1131. callback.call(element);
  1132. }
  1133. else if($.fn.transition !== undefined && $module.transition('is supported')) {
  1134. $currentMenu
  1135. .transition({
  1136. animation : settings.transition + ' in',
  1137. debug : settings.debug,
  1138. verbose : settings.verbose,
  1139. duration : settings.duration,
  1140. queue : true,
  1141. onStart : start,
  1142. onComplete : function() {
  1143. callback.call(element);
  1144. }
  1145. })
  1146. ;
  1147. }
  1148. else if(settings.transition == 'slide down') {
  1149. start();
  1150. $currentMenu
  1151. .hide()
  1152. .clearQueue()
  1153. .children()
  1154. .clearQueue()
  1155. .css('opacity', 0)
  1156. .delay(50)
  1157. .animate({
  1158. opacity : 1
  1159. }, settings.duration, 'easeOutQuad', module.event.resetStyle)
  1160. .end()
  1161. .slideDown(100, 'easeOutQuad', function() {
  1162. module.event.resetStyle.call(this);
  1163. callback.call(element);
  1164. })
  1165. ;
  1166. }
  1167. else if(settings.transition == 'fade') {
  1168. start();
  1169. $currentMenu
  1170. .hide()
  1171. .clearQueue()
  1172. .fadeIn(settings.duration, function() {
  1173. module.event.resetStyle.call(this);
  1174. callback.call(element);
  1175. })
  1176. ;
  1177. }
  1178. else {
  1179. module.error(error.transition, settings.transition);
  1180. }
  1181. }
  1182. },
  1183. hide: function(callback, $subMenu) {
  1184. var
  1185. $currentMenu = $subMenu || $menu,
  1186. duration = ($subMenu)
  1187. ? (settings.duration * 0.9)
  1188. : settings.duration,
  1189. start = ($subMenu)
  1190. ? function() {}
  1191. : function() {
  1192. if( module.can.click() ) {
  1193. module.unbind.intent();
  1194. }
  1195. module.focusSearch();
  1196. module.remove.active();
  1197. }
  1198. ;
  1199. callback = $.isFunction(callback)
  1200. ? callback
  1201. : function(){}
  1202. ;
  1203. if( module.is.visible($currentMenu) || module.is.animating($currentMenu) ) {
  1204. module.verbose('Doing menu hide animation', $currentMenu);
  1205. if(settings.transition == 'auto') {
  1206. settings.transition = module.is.upward()
  1207. ? 'slide up'
  1208. : 'slide down'
  1209. ;
  1210. }
  1211. if(settings.transition == 'none') {
  1212. callback.call(element);
  1213. }
  1214. else if($.fn.transition !== undefined && $module.transition('is supported')) {
  1215. $currentMenu
  1216. .transition({
  1217. animation : settings.transition + ' out',
  1218. duration : settings.duration,
  1219. debug : settings.debug,
  1220. verbose : settings.verbose,
  1221. queue : true,
  1222. onStart : start,
  1223. onComplete : function() {
  1224. callback.call(element);
  1225. }
  1226. })
  1227. ;
  1228. }
  1229. else if(settings.transition == 'slide down') {
  1230. start();
  1231. $currentMenu
  1232. .show()
  1233. .clearQueue()
  1234. .children()
  1235. .clearQueue()
  1236. .css('opacity', 1)
  1237. .animate({
  1238. opacity : 0
  1239. }, 100, 'easeOutQuad', module.event.resetStyle)
  1240. .end()
  1241. .delay(50)
  1242. .slideUp(100, 'easeOutQuad', function() {
  1243. module.event.resetStyle.call(this);
  1244. callback.call(element);
  1245. })
  1246. ;
  1247. }
  1248. else if(settings.transition == 'fade') {
  1249. start();
  1250. $currentMenu
  1251. .show()
  1252. .clearQueue()
  1253. .fadeOut(150, function() {
  1254. module.event.resetStyle.call(this);
  1255. callback.call(element);
  1256. })
  1257. ;
  1258. }
  1259. else {
  1260. module.error(error.transition);
  1261. }
  1262. }
  1263. }
  1264. },
  1265. delay: {
  1266. show: function() {
  1267. module.verbose('Delaying show event to ensure user intent');
  1268. clearTimeout(module.timer);
  1269. module.timer = setTimeout(module.show, settings.delay.show);
  1270. },
  1271. hide: function() {
  1272. module.verbose('Delaying hide event to ensure user intent');
  1273. clearTimeout(module.timer);
  1274. module.timer = setTimeout(module.hide, settings.delay.hide);
  1275. }
  1276. },
  1277. escape: {
  1278. regExp: function(text) {
  1279. text = String(text);
  1280. return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
  1281. }
  1282. },
  1283. setting: function(name, value) {
  1284. module.debug('Changing setting', name, value);
  1285. if( $.isPlainObject(name) ) {
  1286. $.extend(true, settings, name);
  1287. }
  1288. else if(value !== undefined) {
  1289. settings[name] = value;
  1290. }
  1291. else {
  1292. return settings[name];
  1293. }
  1294. },
  1295. internal: function(name, value) {
  1296. if( $.isPlainObject(name) ) {
  1297. $.extend(true, module, name);
  1298. }
  1299. else if(value !== undefined) {
  1300. module[name] = value;
  1301. }
  1302. else {
  1303. return module[name];
  1304. }
  1305. },
  1306. debug: function() {
  1307. if(settings.debug) {
  1308. if(settings.performance) {
  1309. module.performance.log(arguments);
  1310. }
  1311. else {
  1312. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  1313. module.debug.apply(console, arguments);
  1314. }
  1315. }
  1316. },
  1317. verbose: function() {
  1318. if(settings.verbose && settings.debug) {
  1319. if(settings.performance) {
  1320. module.performance.log(arguments);
  1321. }
  1322. else {
  1323. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  1324. module.verbose.apply(console, arguments);
  1325. }
  1326. }
  1327. },
  1328. error: function() {
  1329. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  1330. module.error.apply(console, arguments);
  1331. },
  1332. performance: {
  1333. log: function(message) {
  1334. var
  1335. currentTime,
  1336. executionTime,
  1337. previousTime
  1338. ;
  1339. if(settings.performance) {
  1340. currentTime = new Date().getTime();
  1341. previousTime = time || currentTime;
  1342. executionTime = currentTime - previousTime;
  1343. time = currentTime;
  1344. performance.push({
  1345. 'Name' : message[0],
  1346. 'Arguments' : [].slice.call(message, 1) || '',
  1347. 'Element' : element,
  1348. 'Execution Time' : executionTime
  1349. });
  1350. }
  1351. clearTimeout(module.performance.timer);
  1352. module.performance.timer = setTimeout(module.performance.display, 100);
  1353. },
  1354. display: function() {
  1355. var
  1356. title = settings.name + ':',
  1357. totalTime = 0
  1358. ;
  1359. time = false;
  1360. clearTimeout(module.performance.timer);
  1361. $.each(performance, function(index, data) {
  1362. totalTime += data['Execution Time'];
  1363. });
  1364. title += ' ' + totalTime + 'ms';
  1365. if(moduleSelector) {
  1366. title += ' \'' + moduleSelector + '\'';
  1367. }
  1368. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  1369. console.groupCollapsed(title);
  1370. if(console.table) {
  1371. console.table(performance);
  1372. }
  1373. else {
  1374. $.each(performance, function(index, data) {
  1375. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  1376. });
  1377. }
  1378. console.groupEnd();
  1379. }
  1380. performance = [];
  1381. }
  1382. },
  1383. invoke: function(query, passedArguments, context) {
  1384. var
  1385. object = instance,
  1386. maxDepth,
  1387. found,
  1388. response
  1389. ;
  1390. passedArguments = passedArguments || queryArguments;
  1391. context = element || context;
  1392. if(typeof query == 'string' && object !== undefined) {
  1393. query = query.split(/[\. ]/);
  1394. maxDepth = query.length - 1;
  1395. $.each(query, function(depth, value) {
  1396. var camelCaseValue = (depth != maxDepth)
  1397. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  1398. : query
  1399. ;
  1400. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  1401. object = object[camelCaseValue];
  1402. }
  1403. else if( object[camelCaseValue] !== undefined ) {
  1404. found = object[camelCaseValue];
  1405. return false;
  1406. }
  1407. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  1408. object = object[value];
  1409. }
  1410. else if( object[value] !== undefined ) {
  1411. found = object[value];
  1412. return false;
  1413. }
  1414. else {
  1415. module.error(error.method, query);
  1416. return false;
  1417. }
  1418. });
  1419. }
  1420. if ( $.isFunction( found ) ) {
  1421. response = found.apply(context, passedArguments);
  1422. }
  1423. else if(found !== undefined) {
  1424. response = found;
  1425. }
  1426. if($.isArray(returnedValue)) {
  1427. returnedValue.push(response);
  1428. }
  1429. else if(returnedValue !== undefined) {
  1430. returnedValue = [returnedValue, response];
  1431. }
  1432. else if(response !== undefined) {
  1433. returnedValue = response;
  1434. }
  1435. return found;
  1436. }
  1437. };
  1438. if(methodInvoked) {
  1439. if(instance === undefined) {
  1440. module.initialize();
  1441. }
  1442. module.invoke(query);
  1443. }
  1444. else {
  1445. if(instance !== undefined) {
  1446. module.destroy();
  1447. }
  1448. module.initialize();
  1449. }
  1450. })
  1451. ;
  1452. return (returnedValue !== undefined)
  1453. ? returnedValue
  1454. : this
  1455. ;
  1456. };
  1457. $.fn.dropdown.settings = {
  1458. debug : false,
  1459. verbose : true,
  1460. performance : true,
  1461. on : 'click',
  1462. action : 'activate',
  1463. allowTab : true,
  1464. fullTextSearch : false,
  1465. preserveHTML : true,
  1466. sortSelect : false,
  1467. allowCategorySelection : false,
  1468. delay : {
  1469. hide : 300,
  1470. show : 200,
  1471. search : 50,
  1472. touch : 50
  1473. },
  1474. transition : 'auto',
  1475. duration : 250,
  1476. /* Callbacks */
  1477. onNoResults : function(searchTerm){},
  1478. onChange : function(value, text){},
  1479. onShow : function(){},
  1480. onHide : function(){},
  1481. /* Component */
  1482. name : 'Dropdown',
  1483. namespace : 'dropdown',
  1484. error : {
  1485. action : 'You called a dropdown action that was not defined',
  1486. method : 'The method you called is not defined.',
  1487. transition : 'The requested transition was not found'
  1488. },
  1489. metadata: {
  1490. defaultText : 'defaultText',
  1491. defaultValue : 'defaultValue',
  1492. text : 'text',
  1493. value : 'value'
  1494. },
  1495. selector : {
  1496. dropdown : '.ui.dropdown',
  1497. input : '> input[type="hidden"], > select',
  1498. item : '.item',
  1499. menu : '.menu',
  1500. menuIcon : '.dropdown.icon',
  1501. search : '> input.search, .menu > .search > input, .menu > input.search',
  1502. text : '> .text:not(.icon)'
  1503. },
  1504. className : {
  1505. active : 'active',
  1506. animating : 'animating',
  1507. disabled : 'disabled',
  1508. dropdown : 'ui dropdown',
  1509. filtered : 'filtered',
  1510. loading : 'loading',
  1511. menu : 'menu',
  1512. placeholder : 'default',
  1513. search : 'search',
  1514. selected : 'selected',
  1515. selection : 'selection',
  1516. upward : 'upward',
  1517. visible : 'visible'
  1518. }
  1519. };
  1520. /* Templates */
  1521. $.fn.dropdown.settings.templates = {
  1522. menu: function(select) {
  1523. var
  1524. placeholder = select.placeholder || false,
  1525. values = select.values || {},
  1526. html = ''
  1527. ;
  1528. $.each(select.values, function(index, option) {
  1529. html += '<div class="item" data-value="' + option.value + '">' + option.name + '</div>';
  1530. });
  1531. return html;
  1532. },
  1533. dropdown: function(select) {
  1534. var
  1535. placeholder = select.placeholder || false,
  1536. values = select.values || {},
  1537. html = ''
  1538. ;
  1539. html += '<i class="dropdown icon"></i>';
  1540. if(select.placeholder) {
  1541. html += '<div class="default text">' + placeholder + '</div>';
  1542. }
  1543. else {
  1544. html += '<div class="text"></div>';
  1545. }
  1546. html += '<div class="menu">';
  1547. $.each(select.values, function(index, option) {
  1548. html += '<div class="item" data-value="' + option.value + '">' + option.name + '</div>';
  1549. });
  1550. html += '</div>';
  1551. return html;
  1552. }
  1553. };
  1554. /* Dependencies */
  1555. $.extend( $.easing, {
  1556. easeOutQuad: function (x, t, b, c, d) {
  1557. return -c *(t/=d)*(t-2) + b;
  1558. },
  1559. });
  1560. })( jQuery, window , document );