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.

1006 lines
31 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
  1. /*
  2. * # Semantic - Dropdown
  3. * http://github.com/jlukic/semantic-ui/
  4. *
  5. *
  6. * Copyright 2013 Contributors
  7. * Released under the MIT license
  8. * http://opensource.org/licenses/MIT
  9. *
  10. */
  11. ;(function ( $, window, document, undefined ) {
  12. $.fn.dropdown = function(parameters) {
  13. var
  14. $allModules = $(this),
  15. $document = $(document),
  16. moduleSelector = $allModules.selector || '',
  17. hasTouch = ('ontouchstart' in document.documentElement),
  18. time = new Date().getTime(),
  19. performance = [],
  20. query = arguments[0],
  21. methodInvoked = (typeof query == 'string'),
  22. queryArguments = [].slice.call(arguments, 1),
  23. returnedValue
  24. ;
  25. $allModules
  26. .each(function() {
  27. var
  28. settings = ( $.isPlainObject(parameters) )
  29. ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
  30. : $.extend({}, $.fn.dropdown.settings),
  31. className = settings.className,
  32. metadata = settings.metadata,
  33. namespace = settings.namespace,
  34. selector = settings.selector,
  35. error = settings.error,
  36. eventNamespace = '.' + namespace,
  37. moduleNamespace = 'module-' + namespace,
  38. $module = $(this),
  39. $item = $module.find(selector.item),
  40. $text = $module.find(selector.text),
  41. $input = $module.find(selector.input),
  42. $menu = $module.children(selector.menu),
  43. element = this,
  44. instance = $module.data(moduleNamespace),
  45. module
  46. ;
  47. module = {
  48. initialize: function() {
  49. module.debug('Initializing dropdown', settings);
  50. module.save.defaults();
  51. module.set.selected();
  52. if(hasTouch) {
  53. module.bind.touchEvents();
  54. }
  55. module.bind.mouseEvents();
  56. module.bind.keyboardEvents();
  57. module.instantiate();
  58. },
  59. instantiate: function() {
  60. module.verbose('Storing instance of dropdown', module);
  61. instance = module;
  62. $module
  63. .data(moduleNamespace, module)
  64. ;
  65. },
  66. destroy: function() {
  67. module.verbose('Destroying previous dropdown for', $module);
  68. $item
  69. .off(eventNamespace)
  70. ;
  71. $module
  72. .off(eventNamespace)
  73. .removeData(moduleNamespace)
  74. ;
  75. },
  76. bind: {
  77. keyboardEvents: function() {
  78. module.debug('Binding keyboard events');
  79. $module
  80. .on('keydown' + eventNamespace, module.handleKeyboard)
  81. ;
  82. $module
  83. .on('focus' + eventNamespace, module.show)
  84. ;
  85. },
  86. touchEvents: function() {
  87. module.debug('Touch device detected binding touch events');
  88. $module
  89. .on('touchstart' + eventNamespace, module.event.test.toggle)
  90. ;
  91. $item
  92. .on('touchstart' + eventNamespace, module.event.item.mouseenter)
  93. .on('touchstart' + eventNamespace, module.event.item.click)
  94. ;
  95. },
  96. mouseEvents: function() {
  97. module.verbose('Mouse detected binding mouse events');
  98. if(settings.on == 'click') {
  99. $module
  100. .on('click' + eventNamespace, module.event.test.toggle)
  101. ;
  102. }
  103. else if(settings.on == 'hover') {
  104. $module
  105. .on('mouseenter' + eventNamespace, module.delay.show)
  106. .on('mouseleave' + eventNamespace, module.delay.hide)
  107. ;
  108. }
  109. else {
  110. $module
  111. .on(settings.on + eventNamespace, module.toggle)
  112. ;
  113. }
  114. $item
  115. .on('mouseenter' + eventNamespace, module.event.item.mouseenter)
  116. .on('mouseleave' + eventNamespace, module.event.item.mouseleave)
  117. .on('click' + eventNamespace, module.event.item.click)
  118. ;
  119. },
  120. intent: function() {
  121. module.verbose('Binding hide intent event to document');
  122. if(hasTouch) {
  123. $document
  124. .on('touchstart' + eventNamespace, module.event.test.touch)
  125. .on('touchmove' + eventNamespace, module.event.test.touch)
  126. ;
  127. }
  128. $document
  129. .on('click' + eventNamespace, module.event.test.hide)
  130. ;
  131. }
  132. },
  133. unbind: {
  134. intent: function() {
  135. module.verbose('Removing hide intent event from document');
  136. if(hasTouch) {
  137. $document
  138. .off('touchstart' + eventNamespace)
  139. .off('touchmove' + eventNamespace)
  140. ;
  141. }
  142. $document
  143. .off('click' + eventNamespace)
  144. ;
  145. }
  146. },
  147. handleKeyboard: function(event) {
  148. var
  149. $selectedItem = $item.filter('.' + className.selected),
  150. pressedKey = event.which,
  151. keys = {
  152. enter : 13,
  153. escape : 27,
  154. upArrow : 38,
  155. downArrow : 40
  156. },
  157. selectedClass = className.selected,
  158. currentIndex = $item.index( $selectedItem ),
  159. hasSelectedItem = ($selectedItem.size() > 0),
  160. resultSize = $item.size(),
  161. newIndex
  162. ;
  163. // close shortcuts
  164. if(pressedKey == keys.escape) {
  165. module.verbose('Escape key pressed, closing dropdown');
  166. module.hide();
  167. }
  168. // result shortcuts
  169. if(module.is.visible()) {
  170. if(pressedKey == keys.enter && hasSelectedItem) {
  171. module.verbose('Enter key pressed, choosing selected item');
  172. $.proxy(module.event.item.click, $item.filter('.' + selectedClass) )(event);
  173. event.preventDefault();
  174. return false;
  175. }
  176. else if(pressedKey == keys.upArrow) {
  177. module.verbose('Up key pressed, changing active item');
  178. newIndex = (currentIndex - 1 < 0)
  179. ? currentIndex
  180. : currentIndex - 1
  181. ;
  182. $item
  183. .removeClass(selectedClass)
  184. .eq(newIndex)
  185. .addClass(selectedClass)
  186. ;
  187. event.preventDefault();
  188. }
  189. else if(pressedKey == keys.downArrow) {
  190. module.verbose('Down key pressed, changing active item');
  191. newIndex = (currentIndex + 1 >= resultSize)
  192. ? currentIndex
  193. : currentIndex + 1
  194. ;
  195. $item
  196. .removeClass(selectedClass)
  197. .eq(newIndex)
  198. .addClass(selectedClass)
  199. ;
  200. event.preventDefault();
  201. }
  202. }
  203. else {
  204. if(pressedKey == keys.enter) {
  205. module.show();
  206. }
  207. }
  208. },
  209. event: {
  210. test: {
  211. toggle: function(event) {
  212. if( module.determine.intent(event, module.toggle) ) {
  213. event.preventDefault();
  214. }
  215. },
  216. touch: function(event) {
  217. module.determine.intent(event, function() {
  218. if(event.type == 'touchstart') {
  219. module.timer = setTimeout(module.hide, settings.delay.touch);
  220. }
  221. else if(event.type == 'touchmove') {
  222. clearTimeout(module.timer);
  223. }
  224. });
  225. event.stopPropagation();
  226. },
  227. hide: function(event) {
  228. module.determine.intent(event, module.hide);
  229. }
  230. },
  231. item: {
  232. mouseenter: function(event) {
  233. var
  234. $currentMenu = $(this).find(selector.submenu),
  235. $otherMenus = $(this).siblings(selector.item).children(selector.menu)
  236. ;
  237. if($currentMenu.length > 0 || $otherMenus.length > 0) {
  238. clearTimeout(module.itemTimer);
  239. module.itemTimer = setTimeout(function() {
  240. if($otherMenus.length > 0) {
  241. module.animate.hide(false, $otherMenus.filter(':visible'));
  242. }
  243. if($currentMenu.length > 0) {
  244. module.verbose('Showing sub-menu', $currentMenu);
  245. module.animate.show(false, $currentMenu);
  246. }
  247. }, settings.delay.show * 2);
  248. event.preventDefault();
  249. event.stopPropagation();
  250. }
  251. },
  252. mouseleave: function(event) {
  253. var
  254. $currentMenu = $(this).find(selector.menu)
  255. ;
  256. if($currentMenu.size() > 0) {
  257. clearTimeout(module.itemTimer);
  258. module.itemTimer = setTimeout(function() {
  259. module.verbose('Hiding sub-menu', $currentMenu);
  260. module.animate.hide(false, $currentMenu);
  261. }, settings.delay.hide);
  262. }
  263. },
  264. click: function (event) {
  265. var
  266. $choice = $(this),
  267. text = ( $choice.data(metadata.text) !== undefined )
  268. ? $choice.data(metadata.text)
  269. : $choice.text(),
  270. value = ( $choice.data(metadata.value) !== undefined)
  271. ? $choice.data(metadata.value)
  272. : (typeof text === 'string')
  273. ? text.toLowerCase()
  274. : text,
  275. callback = function() {
  276. module.determine.selectAction(text, value);
  277. $.proxy(settings.onChange, element)(value, text);
  278. }
  279. ;
  280. if( $choice.find(selector.menu).size() === 0 ) {
  281. if(event.type == 'touchstart') {
  282. $choice.one('click', callback);
  283. }
  284. else {
  285. callback();
  286. }
  287. }
  288. }
  289. },
  290. resetStyle: function() {
  291. $(this).removeAttr('style');
  292. }
  293. },
  294. determine: {
  295. selectAction: function(text, value) {
  296. module.verbose('Determining action', settings.action);
  297. if( $.isFunction( module.action[settings.action] ) ) {
  298. module.verbose('Triggering preset action', settings.action, text, value);
  299. module.action[ settings.action ](text, value);
  300. }
  301. else if( $.isFunction(settings.action) ) {
  302. module.verbose('Triggering user action', settings.action, text, value);
  303. settings.action(text, value);
  304. }
  305. else {
  306. module.error(error.action, settings.action);
  307. }
  308. },
  309. intent: function(event, callback) {
  310. module.debug('Determining whether event occurred in dropdown', event.target);
  311. callback = callback || function(){};
  312. if( $(event.target).closest($menu).size() === 0 ) {
  313. module.verbose('Triggering event', callback);
  314. callback();
  315. return true;
  316. }
  317. else {
  318. module.verbose('Event occurred in dropdown, canceling callback');
  319. return false;
  320. }
  321. }
  322. },
  323. action: {
  324. nothing: function() {},
  325. hide: function() {
  326. module.hide();
  327. },
  328. activate: function(text, value) {
  329. value = (value !== undefined)
  330. ? value
  331. : text
  332. ;
  333. module.set.selected(value);
  334. module.set.value(value);
  335. module.hide();
  336. },
  337. /* Deprecated */
  338. auto: function(text, value) {
  339. value = (value !== undefined)
  340. ? value
  341. : text
  342. ;
  343. module.set.selected(value);
  344. module.set.value(value);
  345. module.hide();
  346. },
  347. /* Deprecated */
  348. changeText: function(text, value) {
  349. value = (value !== undefined)
  350. ? value
  351. : text
  352. ;
  353. module.set.selected(value);
  354. module.hide();
  355. },
  356. /* Deprecated */
  357. updateForm: function(text, value) {
  358. value = (value !== undefined)
  359. ? value
  360. : text
  361. ;
  362. module.set.selected(value);
  363. module.set.value(value);
  364. module.hide();
  365. }
  366. },
  367. get: {
  368. text: function() {
  369. return $text.text();
  370. },
  371. value: function() {
  372. return ($input.size() > 0)
  373. ? $input.val()
  374. : $module.data(metadata.value)
  375. ;
  376. },
  377. item: function(value, strict) {
  378. var
  379. $selectedItem = false
  380. ;
  381. value = (value !== undefined)
  382. ? value
  383. : ( module.get.value() !== undefined)
  384. ? module.get.value()
  385. : module.get.text()
  386. ;
  387. if(strict === undefined && value === '') {
  388. module.debug('Ambiguous dropdown value using strict type check', value);
  389. strict = true;
  390. }
  391. else {
  392. strict = strict || false;
  393. }
  394. if(value !== undefined) {
  395. $item
  396. .each(function() {
  397. var
  398. $choice = $(this),
  399. optionText = ( $choice.data(metadata.text) !== undefined )
  400. ? $choice.data(metadata.text)
  401. : $choice.text(),
  402. optionValue = ( $choice.data(metadata.value) !== undefined )
  403. ? $choice.data(metadata.value)
  404. : (typeof optionText === 'string')
  405. ? optionText.toLowerCase()
  406. : optionText
  407. ;
  408. if(strict) {
  409. if( optionValue === value ) {
  410. $selectedItem = $(this);
  411. }
  412. else if( !$selectedItem && optionText === value ) {
  413. $selectedItem = $(this);
  414. }
  415. }
  416. else {
  417. if( optionValue == value ) {
  418. $selectedItem = $(this);
  419. }
  420. else if( !$selectedItem && optionText == value ) {
  421. $selectedItem = $(this);
  422. }
  423. }
  424. })
  425. ;
  426. }
  427. else {
  428. value = module.get.text();
  429. }
  430. return $selectedItem || false;
  431. }
  432. },
  433. restore: {
  434. defaults: function() {
  435. module.restore.defaultText();
  436. module.restore.defaultValue();
  437. },
  438. defaultText: function() {
  439. var
  440. defaultText = $module.data(metadata.defaultText)
  441. ;
  442. module.debug('Restoring default text', defaultText);
  443. module.set.text(defaultText);
  444. },
  445. defaultValue: function() {
  446. var
  447. defaultValue = $module.data(metadata.defaultValue)
  448. ;
  449. if(defaultValue !== undefined) {
  450. module.debug('Restoring default value', defaultValue);
  451. module.set.selected(defaultValue);
  452. module.set.value(defaultValue);
  453. }
  454. }
  455. },
  456. save: {
  457. defaults: function() {
  458. module.save.defaultText();
  459. module.save.defaultValue();
  460. },
  461. defaultValue: function() {
  462. $module.data(metadata.defaultValue, module.get.value() );
  463. },
  464. defaultText: function() {
  465. $module.data(metadata.defaultText, $text.text() );
  466. }
  467. },
  468. set: {
  469. text: function(text) {
  470. module.debug('Changing text', text, $text);
  471. $text.removeClass(className.placeholder);
  472. $text.text(text);
  473. },
  474. value: function(value) {
  475. module.debug('Adding selected value to hidden input', value, $input);
  476. if($input.size() > 0) {
  477. $input
  478. .val(value)
  479. .trigger('change')
  480. ;
  481. }
  482. else {
  483. $module.data(metadata.value, value);
  484. }
  485. },
  486. active: function() {
  487. $module.addClass(className.active);
  488. },
  489. visible: function() {
  490. $module.addClass(className.visible);
  491. },
  492. selected: function(value) {
  493. var
  494. $selectedItem = module.get.item(value),
  495. selectedText
  496. ;
  497. if($selectedItem) {
  498. module.debug('Setting selected menu item to', $selectedItem);
  499. selectedText = ($selectedItem.data(metadata.text) !== undefined)
  500. ? $selectedItem.data(metadata.text)
  501. : $selectedItem.text()
  502. ;
  503. $item
  504. .removeClass(className.active)
  505. ;
  506. $selectedItem
  507. .addClass(className.active)
  508. ;
  509. module.set.text(selectedText);
  510. }
  511. }
  512. },
  513. remove: {
  514. active: function() {
  515. $module.removeClass(className.active);
  516. },
  517. visible: function() {
  518. $module.removeClass(className.visible);
  519. }
  520. },
  521. is: {
  522. selection: function() {
  523. return $module.hasClass(className.selection);
  524. },
  525. animated: function($subMenu) {
  526. return ($subMenu)
  527. ? $subMenu.is(':animated') || $subMenu.transition && $subMenu.transition('is animating')
  528. : $menu.is(':animated') || $menu.transition && $menu.transition('is animating')
  529. ;
  530. },
  531. visible: function($subMenu) {
  532. return ($subMenu)
  533. ? $subMenu.is(':visible')
  534. : $menu.is(':visible')
  535. ;
  536. },
  537. hidden: function($subMenu) {
  538. return ($subMenu)
  539. ? $subMenu.is(':not(:visible)')
  540. : $menu.is(':not(:visible)')
  541. ;
  542. }
  543. },
  544. can: {
  545. click: function() {
  546. return (hasTouch || settings.on == 'click');
  547. },
  548. show: function() {
  549. return !$module.hasClass(className.disabled);
  550. }
  551. },
  552. animate: {
  553. show: function(callback, $subMenu) {
  554. var
  555. $currentMenu = $subMenu || $menu
  556. ;
  557. callback = callback || function(){};
  558. if( module.is.hidden($currentMenu) ) {
  559. module.verbose('Doing menu show animation', $currentMenu);
  560. if(settings.transition == 'none') {
  561. callback();
  562. }
  563. else if($.fn.transition !== undefined && $module.transition('is supported')) {
  564. $currentMenu
  565. .transition({
  566. animation : settings.transition + ' in',
  567. duration : settings.duration,
  568. complete : callback,
  569. queue : false
  570. })
  571. ;
  572. }
  573. else if(settings.transition == 'slide down') {
  574. $currentMenu
  575. .hide()
  576. .clearQueue()
  577. .children()
  578. .clearQueue()
  579. .css('opacity', 0)
  580. .delay(50)
  581. .animate({
  582. opacity : 1
  583. }, settings.duration, 'easeOutQuad', module.event.resetStyle)
  584. .end()
  585. .slideDown(100, 'easeOutQuad', function() {
  586. $.proxy(module.event.resetStyle, this)();
  587. callback();
  588. })
  589. ;
  590. }
  591. else if(settings.transition == 'fade') {
  592. $currentMenu
  593. .hide()
  594. .clearQueue()
  595. .fadeIn(settings.duration, function() {
  596. $.proxy(module.event.resetStyle, this)();
  597. callback();
  598. })
  599. ;
  600. }
  601. else {
  602. module.error(error.transition, settings.transition);
  603. }
  604. }
  605. },
  606. hide: function(callback, $subMenu) {
  607. var
  608. $currentMenu = $subMenu || $menu
  609. ;
  610. callback = callback || function(){};
  611. if(module.is.visible($currentMenu) ) {
  612. module.verbose('Doing menu hide animation', $currentMenu);
  613. if($.fn.transition !== undefined && $module.transition('is supported')) {
  614. $currentMenu
  615. .transition({
  616. animation : settings.transition + ' out',
  617. duration : settings.duration,
  618. complete : callback,
  619. queue : false
  620. })
  621. ;
  622. }
  623. else if(settings.transition == 'none') {
  624. callback();
  625. }
  626. else if(settings.transition == 'slide down') {
  627. $currentMenu
  628. .show()
  629. .clearQueue()
  630. .children()
  631. .clearQueue()
  632. .css('opacity', 1)
  633. .animate({
  634. opacity : 0
  635. }, 100, 'easeOutQuad', module.event.resetStyle)
  636. .end()
  637. .delay(50)
  638. .slideUp(100, 'easeOutQuad', function() {
  639. $.proxy(module.event.resetStyle, this)();
  640. callback();
  641. })
  642. ;
  643. }
  644. else if(settings.transition == 'fade') {
  645. $currentMenu
  646. .show()
  647. .clearQueue()
  648. .fadeOut(150, function() {
  649. $.proxy(module.event.resetStyle, this)();
  650. callback();
  651. })
  652. ;
  653. }
  654. else {
  655. module.error(error.transition);
  656. }
  657. }
  658. }
  659. },
  660. show: function() {
  661. module.debug('Checking if dropdown can show');
  662. if( module.is.hidden() ) {
  663. module.hideOthers();
  664. module.set.active();
  665. module.animate.show(function() {
  666. if( module.can.click() ) {
  667. module.bind.intent();
  668. }
  669. module.set.visible();
  670. });
  671. $.proxy(settings.onShow, element)();
  672. }
  673. },
  674. hide: function() {
  675. if( !module.is.animated() && module.is.visible() ) {
  676. module.debug('Hiding dropdown');
  677. if( module.can.click() ) {
  678. module.unbind.intent();
  679. }
  680. module.remove.active();
  681. module.animate.hide(module.remove.visible);
  682. $.proxy(settings.onHide, element)();
  683. }
  684. },
  685. delay: {
  686. show: function() {
  687. module.verbose('Delaying show event to ensure user intent');
  688. clearTimeout(module.timer);
  689. module.timer = setTimeout(module.show, settings.delay.show);
  690. },
  691. hide: function() {
  692. module.verbose('Delaying hide event to ensure user intent');
  693. clearTimeout(module.timer);
  694. module.timer = setTimeout(module.hide, settings.delay.hide);
  695. }
  696. },
  697. hideOthers: function() {
  698. module.verbose('Finding other dropdowns to hide');
  699. $allModules
  700. .not($module)
  701. .has(selector.menu + ':visible')
  702. .dropdown('hide')
  703. ;
  704. },
  705. toggle: function() {
  706. module.verbose('Toggling menu visibility');
  707. if( module.is.hidden() ) {
  708. module.show();
  709. }
  710. else {
  711. module.hide();
  712. }
  713. },
  714. setting: function(name, value) {
  715. if( $.isPlainObject(name) ) {
  716. $.extend(true, settings, name);
  717. }
  718. else if(value !== undefined) {
  719. settings[name] = value;
  720. }
  721. else {
  722. return settings[name];
  723. }
  724. },
  725. internal: function(name, value) {
  726. if( $.isPlainObject(name) ) {
  727. $.extend(true, module, name);
  728. }
  729. else if(value !== undefined) {
  730. module[name] = value;
  731. }
  732. else {
  733. return module[name];
  734. }
  735. },
  736. debug: function() {
  737. if(settings.debug) {
  738. if(settings.performance) {
  739. module.performance.log(arguments);
  740. }
  741. else {
  742. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  743. module.debug.apply(console, arguments);
  744. }
  745. }
  746. },
  747. verbose: function() {
  748. if(settings.verbose && settings.debug) {
  749. if(settings.performance) {
  750. module.performance.log(arguments);
  751. }
  752. else {
  753. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  754. module.verbose.apply(console, arguments);
  755. }
  756. }
  757. },
  758. error: function() {
  759. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  760. module.error.apply(console, arguments);
  761. },
  762. performance: {
  763. log: function(message) {
  764. var
  765. currentTime,
  766. executionTime,
  767. previousTime
  768. ;
  769. if(settings.performance) {
  770. currentTime = new Date().getTime();
  771. previousTime = time || currentTime;
  772. executionTime = currentTime - previousTime;
  773. time = currentTime;
  774. performance.push({
  775. 'Element' : element,
  776. 'Name' : message[0],
  777. 'Arguments' : [].slice.call(message, 1) || '',
  778. 'Execution Time' : executionTime
  779. });
  780. }
  781. clearTimeout(module.performance.timer);
  782. module.performance.timer = setTimeout(module.performance.display, 100);
  783. },
  784. display: function() {
  785. var
  786. title = settings.name + ':',
  787. totalTime = 0
  788. ;
  789. time = false;
  790. clearTimeout(module.performance.timer);
  791. $.each(performance, function(index, data) {
  792. totalTime += data['Execution Time'];
  793. });
  794. title += ' ' + totalTime + 'ms';
  795. if(moduleSelector) {
  796. title += ' \'' + moduleSelector + '\'';
  797. }
  798. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  799. console.groupCollapsed(title);
  800. if(console.table) {
  801. console.table(performance);
  802. }
  803. else {
  804. $.each(performance, function(index, data) {
  805. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  806. });
  807. }
  808. console.groupEnd();
  809. }
  810. performance = [];
  811. }
  812. },
  813. invoke: function(query, passedArguments, context) {
  814. var
  815. object = instance,
  816. maxDepth,
  817. found,
  818. response
  819. ;
  820. passedArguments = passedArguments || queryArguments;
  821. context = element || context;
  822. if(typeof query == 'string' && object !== undefined) {
  823. query = query.split(/[\. ]/);
  824. maxDepth = query.length - 1;
  825. $.each(query, function(depth, value) {
  826. var camelCaseValue = (depth != maxDepth)
  827. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  828. : query
  829. ;
  830. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  831. object = object[camelCaseValue];
  832. }
  833. else if( object[camelCaseValue] !== undefined ) {
  834. found = object[camelCaseValue];
  835. return false;
  836. }
  837. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  838. object = object[value];
  839. }
  840. else if( object[value] !== undefined ) {
  841. found = object[value];
  842. return false;
  843. }
  844. else {
  845. module.error(error.method, query);
  846. return false;
  847. }
  848. });
  849. }
  850. if ( $.isFunction( found ) ) {
  851. response = found.apply(context, passedArguments);
  852. }
  853. else if(found !== undefined) {
  854. response = found;
  855. }
  856. if($.isArray(returnedValue)) {
  857. returnedValue.push(response);
  858. }
  859. else if(returnedValue !== undefined) {
  860. returnedValue = [returnedValue, response];
  861. }
  862. else if(response !== undefined) {
  863. returnedValue = response;
  864. }
  865. return found;
  866. }
  867. };
  868. if(methodInvoked) {
  869. if(instance === undefined) {
  870. module.initialize();
  871. }
  872. module.invoke(query);
  873. }
  874. else {
  875. if(instance !== undefined) {
  876. module.destroy();
  877. }
  878. module.initialize();
  879. }
  880. })
  881. ;
  882. return (returnedValue !== undefined)
  883. ? returnedValue
  884. : this
  885. ;
  886. };
  887. $.fn.dropdown.settings = {
  888. name : 'Dropdown',
  889. namespace : 'dropdown',
  890. debug : false,
  891. verbose : true,
  892. performance : true,
  893. on : 'click',
  894. action : 'activate',
  895. delay: {
  896. show : 200,
  897. hide : 300,
  898. touch : 50
  899. },
  900. transition : 'slide down',
  901. duration : 250,
  902. onChange : function(value, text){},
  903. onShow : function(){},
  904. onHide : function(){},
  905. error : {
  906. action : 'You called a dropdown action that was not defined',
  907. method : 'The method you called is not defined.',
  908. transition : 'The requested transition was not found'
  909. },
  910. metadata: {
  911. defaultText : 'defaultText',
  912. defaultValue : 'defaultValue',
  913. text : 'text',
  914. value : 'value'
  915. },
  916. selector : {
  917. menu : '.menu',
  918. submenu : '> .menu',
  919. item : '.menu > .item',
  920. text : '> .text',
  921. input : '> input[type="hidden"]'
  922. },
  923. className : {
  924. active : 'active',
  925. placeholder : 'default',
  926. disabled : 'disabled',
  927. visible : 'visible',
  928. selected : 'selected',
  929. selection : 'selection'
  930. }
  931. };
  932. // Adds easing
  933. $.extend( $.easing, {
  934. easeOutQuad: function (x, t, b, c, d) {
  935. return -c *(t/=d)*(t-2) + b;
  936. }
  937. });
  938. })( jQuery, window , document );