volt-semantic-ui 0.0.2 → 0.0.3

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