dae-material 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +3 -0
  5. data/CODE_OF_CONDUCT.md +13 -0
  6. data/Gemfile +4 -0
  7. data/README.md +39 -0
  8. data/Rakefile +1 -0
  9. data/app/assets/fonts/material-design-icons/LICENSE.txt +428 -0
  10. data/app/assets/fonts/material-design-icons/Material-Design-Icons.eot +0 -0
  11. data/app/assets/fonts/material-design-icons/Material-Design-Icons.svg +751 -0
  12. data/app/assets/fonts/material-design-icons/Material-Design-Icons.ttf +0 -0
  13. data/app/assets/fonts/material-design-icons/Material-Design-Icons.woff +0 -0
  14. data/app/assets/fonts/material-design-icons/Material-Design-Icons.woff2 +0 -0
  15. data/app/assets/fonts/roboto/Roboto-Bold.ttf +0 -0
  16. data/app/assets/fonts/roboto/Roboto-Bold.woff +0 -0
  17. data/app/assets/fonts/roboto/Roboto-Bold.woff2 +0 -0
  18. data/app/assets/fonts/roboto/Roboto-Light.ttf +0 -0
  19. data/app/assets/fonts/roboto/Roboto-Light.woff +0 -0
  20. data/app/assets/fonts/roboto/Roboto-Light.woff2 +0 -0
  21. data/app/assets/fonts/roboto/Roboto-Medium.ttf +0 -0
  22. data/app/assets/fonts/roboto/Roboto-Medium.woff +0 -0
  23. data/app/assets/fonts/roboto/Roboto-Medium.woff2 +0 -0
  24. data/app/assets/fonts/roboto/Roboto-Regular.ttf +0 -0
  25. data/app/assets/fonts/roboto/Roboto-Regular.woff +0 -0
  26. data/app/assets/fonts/roboto/Roboto-Regular.woff2 +0 -0
  27. data/app/assets/fonts/roboto/Roboto-Thin.ttf +0 -0
  28. data/app/assets/fonts/roboto/Roboto-Thin.woff +0 -0
  29. data/app/assets/fonts/roboto/Roboto-Thin.woff2 +0 -0
  30. data/app/assets/javascripts/materialize-sprockets.js +27 -0
  31. data/app/assets/javascripts/materialize.js +6023 -0
  32. data/app/assets/javascripts/materialize/animation.js +9 -0
  33. data/app/assets/javascripts/materialize/buttons.js +35 -0
  34. data/app/assets/javascripts/materialize/cards.js +27 -0
  35. data/app/assets/javascripts/materialize/character_counter.js +59 -0
  36. data/app/assets/javascripts/materialize/collapsible.js +139 -0
  37. data/app/assets/javascripts/materialize/date_picker/picker.date.js +1430 -0
  38. data/app/assets/javascripts/materialize/date_picker/picker.js +1123 -0
  39. data/app/assets/javascripts/materialize/dropdown.js +176 -0
  40. data/app/assets/javascripts/materialize/forms.js +397 -0
  41. data/app/assets/javascripts/materialize/global.js +31 -0
  42. data/app/assets/javascripts/materialize/hammer.min.js +1 -0
  43. data/app/assets/javascripts/materialize/init.js +137 -0
  44. data/app/assets/javascripts/materialize/jquery.easing.1.3.js +205 -0
  45. data/app/assets/javascripts/materialize/jquery.hammer.js +33 -0
  46. data/app/assets/javascripts/materialize/jquery.timeago.min.js +1 -0
  47. data/app/assets/javascripts/materialize/leanModal.js +139 -0
  48. data/app/assets/javascripts/materialize/materialbox.js +249 -0
  49. data/app/assets/javascripts/materialize/parallax.js +58 -0
  50. data/app/assets/javascripts/materialize/prism.js +8 -0
  51. data/app/assets/javascripts/materialize/pushpin.js +62 -0
  52. data/app/assets/javascripts/materialize/scrollFire.js +69 -0
  53. data/app/assets/javascripts/materialize/scrollspy.js +284 -0
  54. data/app/assets/javascripts/materialize/sideNav.js +335 -0
  55. data/app/assets/javascripts/materialize/slider.js +263 -0
  56. data/app/assets/javascripts/materialize/tabs.js +129 -0
  57. data/app/assets/javascripts/materialize/toasts.js +121 -0
  58. data/app/assets/javascripts/materialize/tooltip.js +166 -0
  59. data/app/assets/javascripts/materialize/transitions.js +145 -0
  60. data/app/assets/javascripts/materialize/velocity.min.js +4 -0
  61. data/app/assets/javascripts/materialize/waves.js +338 -0
  62. data/app/assets/stylesheets/materialize.scss +38 -0
  63. data/app/assets/stylesheets/materialize/components/_buttons.scss +151 -0
  64. data/app/assets/stylesheets/materialize/components/_cards.scss +150 -0
  65. data/app/assets/stylesheets/materialize/components/_collapsible.scss +88 -0
  66. data/app/assets/stylesheets/materialize/components/_color.scss +412 -0
  67. data/app/assets/stylesheets/materialize/components/_dropdown.scss +38 -0
  68. data/app/assets/stylesheets/materialize/components/_form.scss +850 -0
  69. data/app/assets/stylesheets/materialize/components/_global.scss +682 -0
  70. data/app/assets/stylesheets/materialize/components/_grid.scss +118 -0
  71. data/app/assets/stylesheets/materialize/components/_icons-material-design.scss +783 -0
  72. data/app/assets/stylesheets/materialize/components/_materialbox.scss +41 -0
  73. data/app/assets/stylesheets/materialize/components/_mixins.scss +5 -0
  74. data/app/assets/stylesheets/materialize/components/_modal.scss +89 -0
  75. data/app/assets/stylesheets/materialize/components/_navbar.scss +143 -0
  76. data/app/assets/stylesheets/materialize/components/_normalize.scss +427 -0
  77. data/app/assets/stylesheets/materialize/components/_prefixer.scss +376 -0
  78. data/app/assets/stylesheets/materialize/components/_preloader.scss +332 -0
  79. data/app/assets/stylesheets/materialize/components/_roboto.scss +38 -0
  80. data/app/assets/stylesheets/materialize/components/_sideNav.scss +111 -0
  81. data/app/assets/stylesheets/materialize/components/_slider.scss +92 -0
  82. data/app/assets/stylesheets/materialize/components/_table_of_contents.scss +33 -0
  83. data/app/assets/stylesheets/materialize/components/_tabs.scss +42 -0
  84. data/app/assets/stylesheets/materialize/components/_toast.scss +63 -0
  85. data/app/assets/stylesheets/materialize/components/_tooltip.scss +34 -0
  86. data/app/assets/stylesheets/materialize/components/_typography.scss +56 -0
  87. data/app/assets/stylesheets/materialize/components/_variables.scss +143 -0
  88. data/app/assets/stylesheets/materialize/components/_waves.scss +167 -0
  89. data/app/assets/stylesheets/materialize/components/date_picker/_default.date.scss +435 -0
  90. data/app/assets/stylesheets/materialize/components/date_picker/_default.scss +201 -0
  91. data/app/assets/stylesheets/materialize/components/date_picker/_default.time.scss +125 -0
  92. data/bin/console +14 -0
  93. data/bin/setup +7 -0
  94. data/dae-material.gemspec +23 -0
  95. data/lib/dae/material.rb +7 -0
  96. data/lib/dae/material/version.rb +8 -0
  97. metadata +166 -0
@@ -0,0 +1,176 @@
1
+ (function ($) {
2
+
3
+ // Add posibility to scroll to selected option
4
+ // usefull for select for example
5
+ $.fn.scrollTo = function(elem) {
6
+ $(this).scrollTop($(this).scrollTop() - $(this).offset().top + $(elem).offset().top);
7
+ return this;
8
+ };
9
+
10
+ $.fn.dropdown = function (option) {
11
+ var defaults = {
12
+ inDuration: 300,
13
+ outDuration: 225,
14
+ constrain_width: true, // Constrains width of dropdown to the activator
15
+ hover: false,
16
+ gutter: 0, // Spacing from edge
17
+ belowOrigin: false
18
+ }
19
+
20
+ this.each(function(){
21
+ var origin = $(this);
22
+ var options = $.extend({}, defaults, option);
23
+
24
+ // Dropdown menu
25
+ var activates = $("#"+ origin.attr('data-activates'));
26
+
27
+ function updateOptions() {
28
+ if (origin.data('induration') != undefined)
29
+ options.inDuration = origin.data('inDuration');
30
+ if (origin.data('outduration') != undefined)
31
+ options.outDuration = origin.data('outDuration');
32
+ if (origin.data('constrainwidth') != undefined)
33
+ options.constrain_width = origin.data('constrainwidth');
34
+ if (origin.data('hover') != undefined)
35
+ options.hover = origin.data('hover');
36
+ if (origin.data('gutter') != undefined)
37
+ options.gutter = origin.data('gutter');
38
+ if (origin.data('beloworigin') != undefined)
39
+ options.belowOrigin = origin.data('beloworigin');
40
+ }
41
+
42
+ updateOptions();
43
+
44
+ // Attach dropdown to its activator
45
+ origin.after(activates);
46
+
47
+ /*
48
+ Helper function to position and resize dropdown.
49
+ Used in hover and click handler.
50
+ */
51
+ function placeDropdown() {
52
+ // Check html data attributes
53
+ updateOptions();
54
+
55
+ // Set Dropdown state
56
+ activates.addClass('active');
57
+
58
+ // Constrain width
59
+ if (options.constrain_width == true) {
60
+ activates.css('width', origin.outerWidth());
61
+ }
62
+ var offset = 0;
63
+ if (options.belowOrigin == true) {
64
+ offset = origin.height();
65
+ }
66
+
67
+ // Handle edge alignment
68
+ var offsetLeft = origin.offset().left;
69
+ var width_difference = 0;
70
+ var gutter_spacing = options.gutter;
71
+
72
+
73
+ if (offsetLeft + activates.innerWidth() > $(window).width()) {
74
+ width_difference = origin.innerWidth() - activates.innerWidth();
75
+ gutter_spacing = gutter_spacing * -1;
76
+ }
77
+
78
+ // Position dropdown
79
+ activates.css({
80
+ position: 'absolute',
81
+ top: origin.position().top + offset,
82
+ left: origin.position().left + width_difference + gutter_spacing
83
+ });
84
+
85
+
86
+
87
+ // Show dropdown
88
+ activates.stop(true, true).css('opacity', 0)
89
+ .slideDown({
90
+ queue: false,
91
+ duration: options.inDuration,
92
+ easing: 'easeOutCubic',
93
+ complete: function() {
94
+ $(this).css('height', '');
95
+ }
96
+ })
97
+ .animate( {opacity: 1}, {queue: false, duration: options.inDuration, easing: 'easeOutSine'});
98
+ }
99
+
100
+ function hideDropdown() {
101
+ activates.fadeOut(options.outDuration);
102
+ activates.removeClass('active');
103
+ }
104
+
105
+ // Hover
106
+ if (options.hover) {
107
+ var open = false;
108
+ origin.unbind('click.' + origin.attr('id'));
109
+ // Hover handler to show dropdown
110
+ origin.on('mouseenter', function(e){ // Mouse over
111
+ if (open === false) {
112
+ placeDropdown();
113
+ open = true
114
+ }
115
+ });
116
+ origin.on('mouseleave', function(e){
117
+ // If hover on origin then to something other than dropdown content, then close
118
+ if(!$(e.toElement).closest('.dropdown-content').is(activates)) {
119
+ activates.stop(true, true);
120
+ hideDropdown();
121
+ open = false;
122
+ }
123
+ });
124
+
125
+ activates.on('mouseleave', function(e){ // Mouse out
126
+ if(!$(e.toElement).closest('.dropdown-button').is(origin)) {
127
+ activates.stop(true, true);
128
+ hideDropdown();
129
+ open = false;
130
+ }
131
+ });
132
+
133
+ // Click
134
+ } else {
135
+
136
+ // Click handler to show dropdown
137
+ origin.unbind('click.' + origin.attr('id'));
138
+ origin.bind('click.'+origin.attr('id'), function(e){
139
+
140
+ if ( origin[0] == e.currentTarget && ($(e.target).closest('.dropdown-content').length === 0) ) {
141
+ e.preventDefault(); // Prevents button click from moving window
142
+ placeDropdown();
143
+
144
+ }
145
+ // If origin is clicked and menu is open, close menu
146
+ else {
147
+ if (origin.hasClass('active')) {
148
+ hideDropdown();
149
+ $(document).unbind('click.' + activates.attr('id'));
150
+ }
151
+ }
152
+ // If menu open, add click close handler to document
153
+ if (activates.hasClass('active')) {
154
+ $(document).bind('click.'+ activates.attr('id'), function (e) {
155
+ if (!activates.is(e.target) && !origin.is(e.target) && (!origin.find(e.target).length > 0) ) {
156
+ hideDropdown();
157
+ $(document).unbind('click.' + activates.attr('id'));
158
+ }
159
+ });
160
+ }
161
+ });
162
+
163
+ } // End else
164
+
165
+ // Listen to open and close event - useful for select component
166
+ origin.on('open', placeDropdown);
167
+ origin.on('close', hideDropdown);
168
+
169
+
170
+ });
171
+ }; // End dropdown plugin
172
+
173
+ $(document).ready(function(){
174
+ $('.dropdown-button').dropdown();
175
+ });
176
+ }( jQuery ));
@@ -0,0 +1,397 @@
1
+ (function ($) {
2
+ $(document).ready(function() {
3
+
4
+ // Function to update labels of text fields
5
+ Materialize.updateTextFields = function() {
6
+ var input_selector = 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea';
7
+ $(input_selector).each(function(index, element) {
8
+ if ($(element).val().length > 0 || $(this).attr('placeholder') !== undefined) {
9
+ $(this).siblings('label, i').addClass('active');
10
+ }
11
+ else {
12
+ $(this).siblings('label, i').removeClass('active');
13
+ }
14
+ });
15
+ }
16
+
17
+ // Text based inputs
18
+ var input_selector = 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea';
19
+
20
+ // Handle HTML5 autofocus
21
+ $('input[autofocus]').siblings('label, i').addClass('active');
22
+
23
+ // Add active if form auto complete
24
+ $(document).on('change', input_selector, function () {
25
+ if($(this).val().length !== 0 || $(this).attr('placeholder') !== undefined) {
26
+ $(this).siblings('label, i').addClass('active');
27
+ }
28
+ validate_field($(this));
29
+ });
30
+
31
+ // Add active if input element has been pre-populated on document ready
32
+ $(document).ready(function() {
33
+ Materialize.updateTextFields();
34
+ });
35
+
36
+ // HTML DOM FORM RESET handling
37
+ $(document).on('reset', function(e) {
38
+ if ($(e.target).is('form')) {
39
+ $(this).find(input_selector).removeClass('valid').removeClass('invalid');
40
+ $(this).find(input_selector).siblings('label, i').removeClass('active');
41
+
42
+ // Reset select
43
+ $(this).find('select.initialized').each(function () {
44
+ var reset_text = $(this).find('option[selected]').text();
45
+ $(this).siblings('input.select-dropdown').val(reset_text);
46
+ });
47
+ }
48
+ });
49
+
50
+ // Add active when element has focus
51
+ $(document).on('focus', input_selector, function () {
52
+ $(this).siblings('label, i').addClass('active');
53
+ });
54
+
55
+ $(document).on('blur', input_selector, function () {
56
+ if ($(this).val().length === 0 && $(this).attr('placeholder') === undefined) {
57
+ $(this).siblings('label, i').removeClass('active');
58
+ }
59
+ validate_field($(this));
60
+ });
61
+
62
+ validate_field = function(object) {
63
+ if (object.val().length === 0) {
64
+ if (object.hasClass('validate')) {
65
+ object.removeClass('valid');
66
+ object.removeClass('invalid');
67
+ }
68
+ }
69
+ else {
70
+ if (object.hasClass('validate')) {
71
+ if (object.is(':valid')) {
72
+ object.removeClass('invalid');
73
+ object.addClass('valid');
74
+ }
75
+ else {
76
+ object.removeClass('valid');
77
+ object.addClass('invalid');
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+
84
+ // Textarea Auto Resize
85
+ var hiddenDiv = $('.hiddendiv').first();
86
+ if (!hiddenDiv.length) {
87
+ hiddenDiv = $('<div class="hiddendiv common"></div>');
88
+ $('body').append(hiddenDiv);
89
+ }
90
+ var text_area_selector = '.materialize-textarea';
91
+
92
+ function textareaAutoResize($textarea) {
93
+ hiddenDiv.text($textarea.val() + '\n');
94
+ var content = hiddenDiv.html().replace(/\n/g, '<br>');
95
+ hiddenDiv.html(content);
96
+
97
+ // When textarea is hidden, width goes crazy.
98
+ // Approximate with half of window size
99
+
100
+ if ($textarea.is(':visible')) {
101
+ hiddenDiv.css('width', $textarea.width());
102
+ }
103
+ else {
104
+ hiddenDiv.css('width', $(window).width()/2);
105
+ }
106
+
107
+ $textarea.css('height', hiddenDiv.height());
108
+ }
109
+
110
+ $(text_area_selector).each(function () {
111
+ var $textarea = $(this);
112
+ if ($textarea.val().length) {
113
+ textareaAutoResize($textarea);
114
+ }
115
+ });
116
+
117
+ $('body').on('keyup keydown', text_area_selector, function () {
118
+ textareaAutoResize($(this));
119
+ });
120
+
121
+
122
+ // File Input Path
123
+ $('.file-field').each(function() {
124
+ var path_input = $(this).find('input.file-path');
125
+ $(this).find('input[type="file"]').change(function () {
126
+ path_input.val($(this)[0].files[0].name);
127
+ path_input.trigger('change');
128
+ });
129
+ });
130
+
131
+
132
+ // Range Input
133
+ var range_type = 'input[type=range]';
134
+ var range_mousedown = false;
135
+
136
+ $(range_type).each(function () {
137
+ var thumb = $('<span class="thumb"><span class="value"></span></span>');
138
+ $(this).after(thumb);
139
+ });
140
+
141
+ var range_wrapper = '.range-field';
142
+
143
+ $(document).on("mousedown", range_wrapper, function(e) {
144
+ var thumb = $(this).children('.thumb');
145
+ if (thumb.length <= 0) {
146
+ thumb = $('<span class="thumb"><span class="value"></span></span>');
147
+ $(this).append(thumb);
148
+ }
149
+
150
+ range_mousedown = true;
151
+ $(this).addClass('active');
152
+
153
+ if (!thumb.hasClass('active')) {
154
+ thumb.velocity({ height: "30px", width: "30px", top: "-20px", marginLeft: "-15px"}, { duration: 300, easing: 'easeOutExpo' });
155
+ }
156
+ var left = e.pageX - $(this).offset().left;
157
+ var width = $(this).outerWidth();
158
+
159
+ if (left < 0) {
160
+ left = 0;
161
+ }
162
+ else if (left > width) {
163
+ left = width;
164
+ }
165
+ thumb.addClass('active').css('left', left);
166
+ thumb.find('.value').html($(this).children('input[type=range]').val());
167
+
168
+ });
169
+ $(document).on("mouseup", range_wrapper, function() {
170
+ range_mousedown = false;
171
+ $(this).removeClass('active');
172
+ });
173
+
174
+ $(document).on("mousemove", range_wrapper, function(e) {
175
+
176
+ var thumb = $(this).children('.thumb');
177
+ if (range_mousedown) {
178
+ if (!thumb.hasClass('active')) {
179
+ thumb.velocity({ height: "30px", width: "30px", top: "-20px", marginLeft: "-15px"}, { duration: 300, easing: 'easeOutExpo' });
180
+ }
181
+ var left = e.pageX - $(this).offset().left;
182
+ var width = $(this).outerWidth();
183
+
184
+ if (left < 0) {
185
+ left = 0;
186
+ }
187
+ else if (left > width) {
188
+ left = width;
189
+ }
190
+ thumb.addClass('active').css('left', left);
191
+ thumb.find('.value').html($(this).children('input[type=range]').val());
192
+ }
193
+
194
+ });
195
+ $(document).on("mouseout", range_wrapper, function() {
196
+ if (!range_mousedown) {
197
+
198
+ var thumb = $(this).children('.thumb');
199
+
200
+ if (thumb.hasClass('active')) {
201
+ thumb.velocity({ height: "0", width: "0", top: "10px", marginLeft: "-6px"}, { duration: 100 });
202
+ }
203
+ thumb.removeClass('active');
204
+ }
205
+ });
206
+
207
+ }); // End of $(document).ready
208
+
209
+
210
+
211
+
212
+ // Select Plugin
213
+ $.fn.material_select = function (callback) {
214
+ $(this).each(function(){
215
+ $select = $(this);
216
+
217
+ if ( $select.hasClass('browser-default')) {
218
+ return; // Continue to next (return false breaks out of entire loop)
219
+ }
220
+
221
+ // Tear down structure if Select needs to be rebuilt
222
+ var lastID = $select.data('select-id');
223
+ if (lastID) {
224
+ $select.parent().find('i').remove();
225
+ $select.parent().find('input').remove();
226
+
227
+ $select.unwrap();
228
+ $('ul#select-options-'+lastID).remove();
229
+ }
230
+
231
+ // If destroying the select, remove the selelct-id and reset it to it's uninitialized state.
232
+ if(callback === 'destroy') {
233
+ $select.data('select-id', null).removeClass('initialized');
234
+ return;
235
+ }
236
+
237
+ var uniqueID = Materialize.guid();
238
+ $select.data('select-id', uniqueID);
239
+ var wrapper = $('<div class="select-wrapper"></div>');
240
+ wrapper.addClass($select.attr('class'));
241
+ var options = $('<ul id="select-options-' + uniqueID+'" class="dropdown-content select-dropdown"></ul>');
242
+ var selectOptions = $select.children('option');
243
+ if ($select.find('option:selected') !== undefined) {
244
+ var label = $select.find('option:selected');
245
+ }
246
+ else {
247
+ var label = options.first();
248
+ }
249
+
250
+
251
+ // Create Dropdown structure
252
+ selectOptions.each(function () {
253
+ // Add disabled attr if disabled
254
+ options.append($('<li class="' + (($(this).is(':disabled')) ? 'disabled' : '') + '"><span>' + $(this).html() + '</span></li>'));
255
+ });
256
+
257
+
258
+ options.find('li').each(function (i) {
259
+ var $curr_select = $select;
260
+ $(this).click(function () {
261
+ // Check if option element is disabled
262
+ if (!$(this).hasClass('disabled')) {
263
+ $curr_select.find('option').eq(i).prop('selected', true);
264
+ // Trigger onchange() event
265
+ $curr_select.trigger('change');
266
+ $curr_select.siblings('input.select-dropdown').val($(this).text());
267
+ if (typeof callback !== 'undefined') callback();
268
+ }
269
+ });
270
+
271
+ });
272
+
273
+ // Wrap Elements
274
+ $select.wrap(wrapper);
275
+ // Add Select Display Element
276
+ var dropdownIcon = $('<i class="mdi-navigation-arrow-drop-down"></i>');
277
+ if ( $select.is(':disabled') )
278
+ dropdownIcon.addClass('disabled');
279
+
280
+ var $newSelect = $('<input type="text" class="select-dropdown" readonly="true" ' + (($select.is(':disabled')) ? 'disabled' : '')
281
+ + ' data-activates="select-options-' + uniqueID +'" value="'+ label.html() +'"/>');
282
+ $select.before($newSelect);
283
+ $newSelect.before(dropdownIcon);
284
+
285
+ $('body').append(options);
286
+ // Check if section element is disabled
287
+ if (!$select.is(':disabled')) {
288
+ $newSelect.dropdown({"hover": false});
289
+ }
290
+
291
+ // Copy tabindex
292
+ if ($select.attr('tabindex')) {
293
+ $($newSelect[0]).attr('tabindex', $select.attr('tabindex'));
294
+ }
295
+
296
+ $select.addClass('initialized');
297
+
298
+ $newSelect.on('focus', function(){
299
+ $(this).trigger('open');
300
+ label = $(this).val();
301
+ selectedOption = options.find('li').filter(function() {
302
+ return $(this).text().toLowerCase() === label.toLowerCase();
303
+ })[0];
304
+ activateOption(options, selectedOption);
305
+ });
306
+
307
+ $newSelect.on('blur', function(){
308
+ $(this).trigger('close');
309
+ });
310
+
311
+ // Make option as selected and scroll to selected position
312
+ activateOption = function(collection, newOption) {
313
+ collection.find('li.active').removeClass('active');
314
+ $(newOption).addClass('active');
315
+ collection.scrollTo(newOption);
316
+ }
317
+
318
+ // Allow user to search by typing
319
+ // this array is cleared after 1 second
320
+ filterQuery = []
321
+
322
+ onKeyDown = function(event){
323
+ // TAB - switch to another input
324
+ if(event.which == 9){
325
+ $newSelect.trigger('close');
326
+ return
327
+ }
328
+
329
+ // ARROW DOWN WHEN SELECT IS CLOSED - open select options
330
+ if(event.which == 40 && !options.is(":visible")){
331
+ $newSelect.trigger('open');
332
+ return
333
+ }
334
+
335
+ // ENTER WHEN SELECT IS CLOSED - submit form
336
+ if(event.which == 13 && !options.is(":visible")){
337
+ return
338
+ }
339
+
340
+ event.preventDefault();
341
+
342
+ // CASE WHEN USER TYPE LETTERS
343
+ letter = String.fromCharCode(event.which).toLowerCase();
344
+
345
+ if (letter){
346
+ filterQuery.push(letter);
347
+
348
+ string = filterQuery.join("");
349
+
350
+ newOption = options.find('li').filter(function() {
351
+ return $(this).text().toLowerCase().indexOf(string) === 0;
352
+ })[0];
353
+
354
+ if(newOption){
355
+ activateOption(options, newOption);
356
+ }
357
+ }
358
+
359
+ // ENTER - select option and close when select options are opened
360
+ if(event.which == 13){
361
+ activeOption = options.find('li.active:not(.disabled)')[0];
362
+ if(activeOption){
363
+ $(activeOption).trigger('click');
364
+ $newSelect.trigger('close');
365
+ }
366
+ }
367
+
368
+ // ARROW DOWN - move to next not disabled option
369
+ if(event.which == 40){
370
+ newOption = options.find('li.active').next('li:not(.disabled)')[0];
371
+ if(newOption){
372
+ activateOption(options, newOption);
373
+ }
374
+ }
375
+
376
+ // ESC - close options
377
+ if(event.which == 27){
378
+ $newSelect.trigger('close');
379
+ }
380
+
381
+ // ARROW UP - move to previous not disabled option
382
+ if(event.which == 38){
383
+ newOption = options.find('li.active').prev('li:not(.disabled)')[0];
384
+ if(newOption){
385
+ activateOption(options, newOption);
386
+ }
387
+ }
388
+
389
+ // Automaticaly clean filter query so user can search again by starting letters
390
+ setTimeout(function(){filterQuery = []}, 1000)
391
+ }
392
+
393
+ $newSelect.on('keydown', onKeyDown);
394
+ });
395
+ }
396
+
397
+ }( jQuery ));