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.

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