materialize-sass 0.97.8 → 1.0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +5 -5
  2. data/.gitattributes +1 -0
  3. data/.gitignore +1 -0
  4. data/README.md +34 -32
  5. data/Rakefile +38 -21
  6. data/assets/javascripts/materialize/anime.min.js +417 -0
  7. data/assets/javascripts/materialize/autocomplete.js +504 -0
  8. data/assets/javascripts/materialize/buttons.js +409 -0
  9. data/assets/javascripts/materialize/cards.js +34 -0
  10. data/assets/javascripts/materialize/carousel.js +797 -0
  11. data/assets/javascripts/materialize/cash.js +990 -0
  12. data/assets/javascripts/materialize/characterCounter.js +180 -0
  13. data/assets/javascripts/materialize/chips.js +564 -0
  14. data/assets/javascripts/materialize/collapsible.js +337 -0
  15. data/assets/javascripts/materialize/component.js +57 -0
  16. data/assets/javascripts/materialize/datepicker.js +935 -0
  17. data/assets/javascripts/materialize/dropdown.js +659 -0
  18. data/assets/javascripts/materialize/extras/nouislider.js +2147 -0
  19. data/assets/javascripts/materialize/extras/nouislider.min.js +1 -0
  20. data/assets/javascripts/materialize/forms.js +244 -0
  21. data/assets/javascripts/materialize/global.js +408 -0
  22. data/assets/javascripts/materialize/materialbox.js +513 -0
  23. data/assets/javascripts/materialize/modal.js +449 -0
  24. data/assets/javascripts/materialize/parallax.js +173 -0
  25. data/assets/javascripts/materialize/pushpin.js +179 -0
  26. data/assets/javascripts/materialize/range.js +310 -0
  27. data/assets/javascripts/materialize/scrollspy.js +328 -0
  28. data/assets/javascripts/materialize/select.js +497 -0
  29. data/assets/javascripts/materialize/sidenav.js +655 -0
  30. data/assets/javascripts/materialize/slider.js +424 -0
  31. data/assets/javascripts/materialize/tabs.js +476 -0
  32. data/assets/javascripts/materialize/tapTarget.js +364 -0
  33. data/assets/javascripts/materialize/timepicker.js +647 -0
  34. data/assets/javascripts/materialize/toasts.js +355 -0
  35. data/assets/javascripts/materialize/tooltip.js +351 -0
  36. data/{app/assets → assets}/javascripts/materialize/waves.js +42 -47
  37. data/{app/assets → assets}/javascripts/materialize-sprockets.js +12 -13
  38. data/assets/javascripts/materialize.js +12374 -0
  39. data/assets/stylesheets/materialize/components/_badges.scss +55 -0
  40. data/{app/assets → assets}/stylesheets/materialize/components/_buttons.scss +99 -58
  41. data/{app/assets → assets}/stylesheets/materialize/components/_cards.scss +14 -6
  42. data/{app/assets → assets}/stylesheets/materialize/components/_carousel.scss +12 -7
  43. data/{app/assets → assets}/stylesheets/materialize/components/_chips.scss +13 -6
  44. data/{app/assets → assets}/stylesheets/materialize/components/_collapsible.scss +16 -15
  45. data/assets/stylesheets/materialize/components/_color-classes.scss +32 -0
  46. data/{app/assets/stylesheets/materialize/components/_color.scss → assets/stylesheets/materialize/components/_color-variables.scss} +2 -44
  47. data/assets/stylesheets/materialize/components/_datepicker.scss +191 -0
  48. data/{app/assets → assets}/stylesheets/materialize/components/_dropdown.scss +35 -15
  49. data/{app/assets → assets}/stylesheets/materialize/components/_global.scss +96 -125
  50. data/{app/assets → assets}/stylesheets/materialize/components/_grid.scss +45 -36
  51. data/{app/assets → assets}/stylesheets/materialize/components/_icons-material-design.scss +0 -0
  52. data/{app/assets → assets}/stylesheets/materialize/components/_materialbox.scss +13 -12
  53. data/{app/assets → assets}/stylesheets/materialize/components/_modal.scss +7 -3
  54. data/{app/assets → assets}/stylesheets/materialize/components/_navbar.scss +29 -11
  55. data/assets/stylesheets/materialize/components/_normalize.scss +447 -0
  56. data/{app/assets → assets}/stylesheets/materialize/components/_preloader.scss +2 -2
  57. data/assets/stylesheets/materialize/components/_pulse.scss +34 -0
  58. data/{app/assets/stylesheets/materialize/components/_sideNav.scss → assets/stylesheets/materialize/components/_sidenav.scss} +47 -47
  59. data/{app/assets → assets}/stylesheets/materialize/components/_slider.scss +0 -0
  60. data/{app/assets → assets}/stylesheets/materialize/components/_table_of_contents.scss +5 -5
  61. data/{app/assets → assets}/stylesheets/materialize/components/_tabs.scss +10 -10
  62. data/assets/stylesheets/materialize/components/_tapTarget.scss +103 -0
  63. data/assets/stylesheets/materialize/components/_timepicker.scss +183 -0
  64. data/{app/assets → assets}/stylesheets/materialize/components/_toast.scss +7 -14
  65. data/{app/assets → assets}/stylesheets/materialize/components/_tooltip.scss +3 -3
  66. data/assets/stylesheets/materialize/components/_transitions.scss +13 -0
  67. data/{app/assets → assets}/stylesheets/materialize/components/_typography.scss +8 -9
  68. data/{app/assets → assets}/stylesheets/materialize/components/_variables.scss +65 -29
  69. data/assets/stylesheets/materialize/components/_waves.scss +114 -0
  70. data/{app/assets → assets}/stylesheets/materialize/components/forms/_checkboxes.scss +26 -46
  71. data/{app/assets → assets}/stylesheets/materialize/components/forms/_file-input.scss +6 -0
  72. data/{app/assets → assets}/stylesheets/materialize/components/forms/_forms.scss +0 -0
  73. data/{app/assets → assets}/stylesheets/materialize/components/forms/_input-fields.scss +131 -63
  74. data/assets/stylesheets/materialize/components/forms/_radio-buttons.scss +115 -0
  75. data/{app/assets → assets}/stylesheets/materialize/components/forms/_range.scss +35 -33
  76. data/{app/assets → assets}/stylesheets/materialize/components/forms/_select.scss +88 -19
  77. data/{app/assets → assets}/stylesheets/materialize/components/forms/_switches.scss +32 -21
  78. data/assets/stylesheets/materialize/extras/nouislider.css +406 -0
  79. data/{app/assets → assets}/stylesheets/materialize.scss +10 -9
  80. data/lib/materialize-sass/engine.rb +9 -7
  81. data/lib/materialize-sass/helpers.rb +38 -0
  82. data/lib/materialize-sass/version.rb +1 -1
  83. data/lib/materialize-sass.rb +13 -28
  84. data/materialize-sass.gemspec +5 -5
  85. metadata +97 -119
  86. data/app/assets/fonts/roboto/Roboto-Bold.eot +0 -0
  87. data/app/assets/fonts/roboto/Roboto-Bold.ttf +0 -0
  88. data/app/assets/fonts/roboto/Roboto-Bold.woff +0 -0
  89. data/app/assets/fonts/roboto/Roboto-Bold.woff2 +0 -0
  90. data/app/assets/fonts/roboto/Roboto-Light.eot +0 -0
  91. data/app/assets/fonts/roboto/Roboto-Light.ttf +0 -0
  92. data/app/assets/fonts/roboto/Roboto-Light.woff +0 -0
  93. data/app/assets/fonts/roboto/Roboto-Light.woff2 +0 -0
  94. data/app/assets/fonts/roboto/Roboto-Medium.eot +0 -0
  95. data/app/assets/fonts/roboto/Roboto-Medium.ttf +0 -0
  96. data/app/assets/fonts/roboto/Roboto-Medium.woff +0 -0
  97. data/app/assets/fonts/roboto/Roboto-Medium.woff2 +0 -0
  98. data/app/assets/fonts/roboto/Roboto-Regular.eot +0 -0
  99. data/app/assets/fonts/roboto/Roboto-Regular.ttf +0 -0
  100. data/app/assets/fonts/roboto/Roboto-Regular.woff +0 -0
  101. data/app/assets/fonts/roboto/Roboto-Regular.woff2 +0 -0
  102. data/app/assets/fonts/roboto/Roboto-Thin.eot +0 -0
  103. data/app/assets/fonts/roboto/Roboto-Thin.ttf +0 -0
  104. data/app/assets/fonts/roboto/Roboto-Thin.woff +0 -0
  105. data/app/assets/fonts/roboto/Roboto-Thin.woff2 +0 -0
  106. data/app/assets/javascripts/materialize/animation.js +0 -9
  107. data/app/assets/javascripts/materialize/buttons.js +0 -267
  108. data/app/assets/javascripts/materialize/cards.js +0 -26
  109. data/app/assets/javascripts/materialize/carousel.js +0 -454
  110. data/app/assets/javascripts/materialize/character_counter.js +0 -72
  111. data/app/assets/javascripts/materialize/chips.js +0 -289
  112. data/app/assets/javascripts/materialize/collapsible.js +0 -160
  113. data/app/assets/javascripts/materialize/date_picker/picker.date.js +0 -1430
  114. data/app/assets/javascripts/materialize/date_picker/picker.js +0 -1123
  115. data/app/assets/javascripts/materialize/dropdown.js +0 -265
  116. data/app/assets/javascripts/materialize/extras/nouislider.js +0 -1666
  117. data/app/assets/javascripts/materialize/extras/nouislider.min.js +0 -1
  118. data/app/assets/javascripts/materialize/forms.js +0 -682
  119. data/app/assets/javascripts/materialize/global.js +0 -98
  120. data/app/assets/javascripts/materialize/hammer.min.js +0 -1
  121. data/app/assets/javascripts/materialize/init.js +0 -174
  122. data/app/assets/javascripts/materialize/initial.js +0 -11
  123. data/app/assets/javascripts/materialize/jquery.easing.1.3.js +0 -205
  124. data/app/assets/javascripts/materialize/jquery.hammer.js +0 -33
  125. data/app/assets/javascripts/materialize/jquery.timeago.min.js +0 -1
  126. data/app/assets/javascripts/materialize/materialbox.js +0 -269
  127. data/app/assets/javascripts/materialize/modal.js +0 -184
  128. data/app/assets/javascripts/materialize/parallax.js +0 -58
  129. data/app/assets/javascripts/materialize/prism.js +0 -8
  130. data/app/assets/javascripts/materialize/pushpin.js +0 -71
  131. data/app/assets/javascripts/materialize/scrollFire.js +0 -48
  132. data/app/assets/javascripts/materialize/scrollspy.js +0 -284
  133. data/app/assets/javascripts/materialize/sideNav.js +0 -370
  134. data/app/assets/javascripts/materialize/slider.js +0 -321
  135. data/app/assets/javascripts/materialize/tabs.js +0 -164
  136. data/app/assets/javascripts/materialize/toasts.js +0 -137
  137. data/app/assets/javascripts/materialize/tooltip.js +0 -236
  138. data/app/assets/javascripts/materialize/transitions.js +0 -169
  139. data/app/assets/javascripts/materialize/velocity.min.js +0 -5
  140. data/app/assets/javascripts/materialize.js +0 -5
  141. data/app/assets/stylesheets/materialize/components/_mixins.scss +0 -5
  142. data/app/assets/stylesheets/materialize/components/_normalize.scss +0 -424
  143. data/app/assets/stylesheets/materialize/components/_prefixer.scss +0 -384
  144. data/app/assets/stylesheets/materialize/components/_roboto.scss +0 -49
  145. data/app/assets/stylesheets/materialize/components/_waves.scss +0 -177
  146. data/app/assets/stylesheets/materialize/components/date_picker/_default.date.scss +0 -435
  147. data/app/assets/stylesheets/materialize/components/date_picker/_default.scss +0 -201
  148. data/app/assets/stylesheets/materialize/components/date_picker/_default.time.scss +0 -125
  149. data/app/assets/stylesheets/materialize/components/forms/_radio-buttons.scss +0 -117
  150. data/app/assets/stylesheets/materialize/extras/nouislider.css +0 -259
@@ -1,682 +0,0 @@
1
- (function ($) {
2
- $(document).on('turbolinks:load', 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 || element.autofocus ||$(this).attr('placeholder') !== undefined || $(element)[0].validity.badInput === true) {
9
- $(this).siblings('label').addClass('active');
10
- }
11
- else {
12
- $(this).siblings('label').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
- // Add active if form auto complete
21
- $(document).on('change', input_selector, function () {
22
- if($(this).val().length !== 0 || $(this).attr('placeholder') !== undefined) {
23
- $(this).siblings('label').addClass('active');
24
- }
25
- validate_field($(this));
26
- });
27
-
28
- // Add active if input element has been pre-populated on document ready
29
- $(document).on('turbolinks:load', function() {
30
- Materialize.updateTextFields();
31
- });
32
-
33
- // HTML DOM FORM RESET handling
34
- $(document).on('reset', function(e) {
35
- var formReset = $(e.target);
36
- if (formReset.is('form')) {
37
- formReset.find(input_selector).removeClass('valid').removeClass('invalid');
38
- formReset.find(input_selector).each(function () {
39
- if ($(this).attr('value') === '') {
40
- $(this).siblings('label').removeClass('active');
41
- }
42
- });
43
-
44
- // Reset select
45
- formReset.find('select.initialized').each(function () {
46
- var reset_text = formReset.find('option[selected]').text();
47
- formReset.siblings('input.select-dropdown').val(reset_text);
48
- });
49
- }
50
- });
51
-
52
- // Add active when element has focus
53
- $(document).on('focus', input_selector, function () {
54
- $(this).siblings('label, .prefix').addClass('active');
55
- });
56
-
57
- $(document).on('blur', input_selector, function () {
58
- var $inputElement = $(this);
59
- var selector = ".prefix";
60
-
61
- if ($inputElement.val().length === 0 && $inputElement[0].validity.badInput !== true && $inputElement.attr('placeholder') === undefined) {
62
- selector += ", label";
63
- }
64
-
65
- $inputElement.siblings(selector).removeClass('active');
66
-
67
- validate_field($inputElement);
68
- });
69
-
70
- window.validate_field = function(object) {
71
- var hasLength = object.attr('length') !== undefined;
72
- var lenAttr = parseInt(object.attr('length'));
73
- var len = object.val().length;
74
-
75
- if (object.val().length === 0 && object[0].validity.badInput === false) {
76
- if (object.hasClass('validate')) {
77
- object.removeClass('valid');
78
- object.removeClass('invalid');
79
- }
80
- }
81
- else {
82
- if (object.hasClass('validate')) {
83
- // Check for character counter attributes
84
- if ((object.is(':valid') && hasLength && (len <= lenAttr)) || (object.is(':valid') && !hasLength)) {
85
- object.removeClass('invalid');
86
- object.addClass('valid');
87
- }
88
- else {
89
- object.removeClass('valid');
90
- object.addClass('invalid');
91
- }
92
- }
93
- }
94
- };
95
-
96
- // Radio and Checkbox focus class
97
- var radio_checkbox = 'input[type=radio], input[type=checkbox]';
98
- $(document).on('keyup.radio', radio_checkbox, function(e) {
99
- // TAB, check if tabbing to radio or checkbox.
100
- if (e.which === 9) {
101
- $(this).addClass('tabbed');
102
- var $this = $(this);
103
- $this.one('blur', function(e) {
104
-
105
- $(this).removeClass('tabbed');
106
- });
107
- return;
108
- }
109
- });
110
-
111
- // Textarea Auto Resize
112
- var hiddenDiv = $('.hiddendiv').first();
113
- if (!hiddenDiv.length) {
114
- hiddenDiv = $('<div class="hiddendiv common"></div>');
115
- $('body').append(hiddenDiv);
116
- }
117
- var text_area_selector = '.materialize-textarea';
118
-
119
- function textareaAutoResize($textarea) {
120
- // Set font properties of hiddenDiv
121
-
122
- var fontFamily = $textarea.css('font-family');
123
- var fontSize = $textarea.css('font-size');
124
- var lineHeight = $textarea.css('line-height');
125
-
126
- if (fontSize) { hiddenDiv.css('font-size', fontSize); }
127
- if (fontFamily) { hiddenDiv.css('font-family', fontFamily); }
128
- if (lineHeight) { hiddenDiv.css('line-height', lineHeight); }
129
-
130
- if ($textarea.attr('wrap') === "off") {
131
- hiddenDiv.css('overflow-wrap', "normal")
132
- .css('white-space', "pre");
133
- }
134
-
135
- hiddenDiv.text($textarea.val() + '\n');
136
- var content = hiddenDiv.html().replace(/\n/g, '<br>');
137
- hiddenDiv.html(content);
138
-
139
-
140
- // When textarea is hidden, width goes crazy.
141
- // Approximate with half of window size
142
-
143
- if ($textarea.is(':visible')) {
144
- hiddenDiv.css('width', $textarea.width());
145
- }
146
- else {
147
- hiddenDiv.css('width', $(window).width()/2);
148
- }
149
-
150
- $textarea.css('height', hiddenDiv.height());
151
- }
152
-
153
- $(text_area_selector).each(function () {
154
- var $textarea = $(this);
155
- if ($textarea.val().length) {
156
- textareaAutoResize($textarea);
157
- }
158
- });
159
-
160
- $('body').on('keyup keydown autoresize', text_area_selector, function () {
161
- textareaAutoResize($(this));
162
- });
163
-
164
- // File Input Path
165
- $(document).on('change', '.file-field input[type="file"]', function () {
166
- var file_field = $(this).closest('.file-field');
167
- var path_input = file_field.find('input.file-path');
168
- var files = $(this)[0].files;
169
- var file_names = [];
170
- for (var i = 0; i < files.length; i++) {
171
- file_names.push(files[i].name);
172
- }
173
- path_input.val(file_names.join(", "));
174
- path_input.trigger('change');
175
- });
176
-
177
- /****************
178
- * Range Input *
179
- ****************/
180
-
181
- var range_type = 'input[type=range]';
182
- var range_mousedown = false;
183
- var left;
184
-
185
- $(range_type).each(function () {
186
- var thumb = $('<span class="thumb"><span class="value"></span></span>');
187
- $(this).after(thumb);
188
- });
189
-
190
- var range_wrapper = '.range-field';
191
- $(document).on('change', range_type, function(e) {
192
- var thumb = $(this).siblings('.thumb');
193
- thumb.find('.value').html($(this).val());
194
- });
195
-
196
- $(document).on('input mousedown touchstart', range_type, function(e) {
197
- var thumb = $(this).siblings('.thumb');
198
- var width = $(this).outerWidth();
199
-
200
- // If thumb indicator does not exist yet, create it
201
- if (thumb.length <= 0) {
202
- thumb = $('<span class="thumb"><span class="value"></span></span>');
203
- $(this).after(thumb);
204
- }
205
-
206
- // Set indicator value
207
- thumb.find('.value').html($(this).val());
208
-
209
- range_mousedown = true;
210
- $(this).addClass('active');
211
-
212
- if (!thumb.hasClass('active')) {
213
- thumb.velocity({ height: "30px", width: "30px", top: "-20px", marginLeft: "-15px"}, { duration: 300, easing: 'easeOutExpo' });
214
- }
215
-
216
- if (e.type !== 'input') {
217
- if(e.pageX === undefined || e.pageX === null){//mobile
218
- left = e.originalEvent.touches[0].pageX - $(this).offset().left;
219
- }
220
- else{ // desktop
221
- left = e.pageX - $(this).offset().left;
222
- }
223
- if (left < 0) {
224
- left = 0;
225
- }
226
- else if (left > width) {
227
- left = width;
228
- }
229
- thumb.addClass('active').css('left', left);
230
- }
231
-
232
- thumb.find('.value').html($(this).val());
233
- });
234
-
235
- $(document).on('mouseup touchend', range_wrapper, function() {
236
- range_mousedown = false;
237
- $(this).removeClass('active');
238
- });
239
-
240
- $(document).on('mousemove touchmove', range_wrapper, function(e) {
241
- var thumb = $(this).children('.thumb');
242
- var left;
243
- if (range_mousedown) {
244
- if (!thumb.hasClass('active')) {
245
- thumb.velocity({ height: '30px', width: '30px', top: '-20px', marginLeft: '-15px'}, { duration: 300, easing: 'easeOutExpo' });
246
- }
247
- if (e.pageX === undefined || e.pageX === null) { //mobile
248
- left = e.originalEvent.touches[0].pageX - $(this).offset().left;
249
- }
250
- else{ // desktop
251
- left = e.pageX - $(this).offset().left;
252
- }
253
- var width = $(this).outerWidth();
254
-
255
- if (left < 0) {
256
- left = 0;
257
- }
258
- else if (left > width) {
259
- left = width;
260
- }
261
- thumb.addClass('active').css('left', left);
262
- thumb.find('.value').html(thumb.siblings(range_type).val());
263
- }
264
- });
265
-
266
- $(document).on('mouseout touchleave', range_wrapper, function() {
267
- if (!range_mousedown) {
268
-
269
- var thumb = $(this).children('.thumb');
270
-
271
- if (thumb.hasClass('active')) {
272
- thumb.velocity({ height: '0', width: '0', top: '10px', marginLeft: '-6px'}, { duration: 100 });
273
- }
274
- thumb.removeClass('active');
275
- }
276
- });
277
-
278
- /**************************
279
- * Auto complete plugin *
280
- *************************/
281
- $.fn.autocomplete = function (options) {
282
- // Defaults
283
- var defaults = {
284
- data: {}
285
- };
286
-
287
- options = $.extend(defaults, options);
288
-
289
- return this.each(function() {
290
- var $input = $(this);
291
- var data = options.data,
292
- $inputDiv = $input.closest('.input-field'); // Div to append on
293
-
294
- // Check if data isn't empty
295
- if (!$.isEmptyObject(data)) {
296
- // Create autocomplete element
297
- var $autocomplete = $('<ul class="autocomplete-content dropdown-content"></ul>');
298
-
299
- // Append autocomplete element
300
- if ($inputDiv.length) {
301
- $inputDiv.append($autocomplete); // Set ul in body
302
- } else {
303
- $input.after($autocomplete);
304
- }
305
-
306
- var highlight = function(string, $el) {
307
- var img = $el.find('img');
308
- var matchStart = $el.text().toLowerCase().indexOf("" + string.toLowerCase() + ""),
309
- matchEnd = matchStart + string.length - 1,
310
- beforeMatch = $el.text().slice(0, matchStart),
311
- matchText = $el.text().slice(matchStart, matchEnd + 1),
312
- afterMatch = $el.text().slice(matchEnd + 1);
313
- $el.html("<span>" + beforeMatch + "<span class='highlight'>" + matchText + "</span>" + afterMatch + "</span>");
314
- if (img.length) {
315
- $el.prepend(img);
316
- }
317
- };
318
-
319
- // Perform search
320
- $input.on('keyup', function (e) {
321
- // Capture Enter
322
- if (e.which === 13) {
323
- $autocomplete.find('li').first().click();
324
- return;
325
- }
326
-
327
- var val = $input.val().toLowerCase();
328
- $autocomplete.empty();
329
-
330
- // Check if the input isn't empty
331
- if (val !== '') {
332
- for(var key in data) {
333
- if (data.hasOwnProperty(key) &&
334
- key.toLowerCase().indexOf(val) !== -1 &&
335
- key.toLowerCase() !== val) {
336
- var autocompleteOption = $('<li></li>');
337
- if(!!data[key]) {
338
- autocompleteOption.append('<img src="'+ data[key] +'" class="right circle"><span>'+ key +'</span>');
339
- } else {
340
- autocompleteOption.append('<span>'+ key +'</span>');
341
- }
342
- $autocomplete.append(autocompleteOption);
343
-
344
- highlight(val, autocompleteOption);
345
- }
346
- }
347
- }
348
- });
349
-
350
- // Set input value
351
- $autocomplete.on('click', 'li', function () {
352
- $input.val($(this).text().trim());
353
- $input.trigger('change');
354
- $autocomplete.empty();
355
- });
356
- }
357
- });
358
- };
359
-
360
- }); // End of $(document).ready
361
-
362
- /*******************
363
- * Select Plugin *
364
- ******************/
365
- $.fn.material_select = function (callback) {
366
- $(this).each(function(){
367
- var $select = $(this);
368
-
369
- if ($select.hasClass('browser-default')) {
370
- return; // Continue to next (return false breaks out of entire loop)
371
- }
372
-
373
- var multiple = $select.attr('multiple') ? true : false,
374
- lastID = $select.data('select-id'); // Tear down structure if Select needs to be rebuilt
375
-
376
- if (lastID) {
377
- $select.parent().find('span.caret').remove();
378
- $select.parent().find('input').remove();
379
-
380
- $select.unwrap();
381
- $('ul#select-options-'+lastID).remove();
382
- }
383
-
384
- // If destroying the select, remove the selelct-id and reset it to it's uninitialized state.
385
- if(callback === 'destroy') {
386
- $select.data('select-id', null).removeClass('initialized');
387
- return;
388
- }
389
-
390
- var uniqueID = Materialize.guid();
391
- $select.data('select-id', uniqueID);
392
- var wrapper = $('<div class="select-wrapper"></div>');
393
- wrapper.addClass($select.attr('class'));
394
- var options = $('<ul id="select-options-' + uniqueID +'" class="dropdown-content select-dropdown ' + (multiple ? 'multiple-select-dropdown' : '') + '"></ul>'),
395
- selectChildren = $select.children('option, optgroup'),
396
- valuesSelected = [],
397
- optionsHover = false;
398
-
399
- var label = $select.find('option:selected').html() || $select.find('option:first').html() || "";
400
-
401
- // Function that renders and appends the option taking into
402
- // account type and possible image icon.
403
- var appendOptionWithIcon = function(select, option, type) {
404
- // Add disabled attr if disabled
405
- var disabledClass = (option.is(':disabled')) ? 'disabled ' : '';
406
- var optgroupClass = (type === 'optgroup-option') ? 'optgroup-option ' : '';
407
-
408
- // add icons
409
- var icon_url = option.data('icon');
410
- var classes = option.attr('class');
411
- if (!!icon_url) {
412
- var classString = '';
413
- if (!!classes) classString = ' class="' + classes + '"';
414
-
415
- // Check for multiple type.
416
- if (type === 'multiple') {
417
- options.append($('<li class="' + disabledClass + '"><img alt="" src="' + icon_url + '"' + classString + '><span><input type="checkbox"' + disabledClass + '/><label></label>' + option.html() + '</span></li>'));
418
- } else {
419
- options.append($('<li class="' + disabledClass + optgroupClass + '"><img alt="" src="' + icon_url + '"' + classString + '><span>' + option.html() + '</span></li>'));
420
- }
421
- return true;
422
- }
423
-
424
- // Check for multiple type.
425
- if (type === 'multiple') {
426
- options.append($('<li class="' + disabledClass + '"><span><input type="checkbox"' + disabledClass + '/><label></label>' + option.html() + '</span></li>'));
427
- } else {
428
- options.append($('<li class="' + disabledClass + optgroupClass + '"><span>' + option.html() + '</span></li>'));
429
- }
430
- };
431
-
432
- /* Create dropdown structure. */
433
- if (selectChildren.length) {
434
- selectChildren.each(function() {
435
- if ($(this).is('option')) {
436
- // Direct descendant option.
437
- if (multiple) {
438
- appendOptionWithIcon($select, $(this), 'multiple');
439
-
440
- } else {
441
- appendOptionWithIcon($select, $(this));
442
- }
443
- } else if ($(this).is('optgroup')) {
444
- // Optgroup.
445
- var selectOptions = $(this).children('option');
446
- options.append($('<li class="optgroup"><span>' + $(this).attr('label') + '</span></li>'));
447
-
448
- selectOptions.each(function() {
449
- appendOptionWithIcon($select, $(this), 'optgroup-option');
450
- });
451
- }
452
- });
453
- }
454
-
455
- options.find('li:not(.optgroup)').each(function (i) {
456
- $(this).click(function (e) {
457
- // Check if option element is disabled
458
- if (!$(this).hasClass('disabled') && !$(this).hasClass('optgroup')) {
459
- var selected = true;
460
-
461
- if (multiple) {
462
- $('input[type="checkbox"]', this).prop('checked', function(i, v) { return !v; });
463
- selected = toggleEntryFromArray(valuesSelected, $(this).index(), $select);
464
- $newSelect.trigger('focus');
465
- } else {
466
- options.find('li').removeClass('active');
467
- $(this).toggleClass('active');
468
- $newSelect.val($(this).text());
469
- }
470
-
471
- activateOption(options, $(this));
472
- $select.find('option').eq(i).prop('selected', selected);
473
- // Trigger onchange() event
474
- $select.trigger('change');
475
- if (typeof callback !== 'undefined') callback();
476
- }
477
-
478
- e.stopPropagation();
479
- });
480
- });
481
-
482
- // Wrap Elements
483
- $select.wrap(wrapper);
484
- // Add Select Display Element
485
- var dropdownIcon = $('<span class="caret">&#9660;</span>');
486
- if ($select.is(':disabled'))
487
- dropdownIcon.addClass('disabled');
488
-
489
- // escape double quotes
490
- var sanitizedLabelHtml = label.replace(/"/g, '&quot;');
491
-
492
- var $newSelect = $('<input type="text" class="select-dropdown" readonly="true" ' + (($select.is(':disabled')) ? 'disabled' : '') + ' data-activates="select-options-' + uniqueID +'" value="'+ sanitizedLabelHtml +'"/>');
493
- $select.before($newSelect);
494
- $newSelect.before(dropdownIcon);
495
-
496
- $newSelect.after(options);
497
- // Check if section element is disabled
498
- if (!$select.is(':disabled')) {
499
- $newSelect.dropdown({'hover': false, 'closeOnClick': false});
500
- }
501
-
502
- // Copy tabindex
503
- if ($select.attr('tabindex')) {
504
- $($newSelect[0]).attr('tabindex', $select.attr('tabindex'));
505
- }
506
-
507
- $select.addClass('initialized');
508
-
509
- $newSelect.on({
510
- 'focus': function (){
511
- if ($('ul.select-dropdown').not(options[0]).is(':visible')) {
512
- $('input.select-dropdown').trigger('close');
513
- }
514
- if (!options.is(':visible')) {
515
- $(this).trigger('open', ['focus']);
516
- var label = $(this).val();
517
- var selectedOption = options.find('li').filter(function() {
518
- return $(this).text().toLowerCase() === label.toLowerCase();
519
- })[0];
520
- activateOption(options, selectedOption);
521
- }
522
- },
523
- 'click': function (e){
524
- e.stopPropagation();
525
- }
526
- });
527
-
528
- $newSelect.on('blur', function() {
529
- if (!multiple) {
530
- $(this).trigger('close');
531
- }
532
- options.find('li.selected').removeClass('selected');
533
- });
534
-
535
- options.hover(function() {
536
- optionsHover = true;
537
- }, function () {
538
- optionsHover = false;
539
- });
540
-
541
- $(window).on({
542
- 'click': function () {
543
- multiple && (optionsHover || $newSelect.trigger('close'));
544
- }
545
- });
546
-
547
- // Add initial multiple selections.
548
- if (multiple) {
549
- $select.find("option:selected:not(:disabled)").each(function () {
550
- var index = $(this).index();
551
-
552
- toggleEntryFromArray(valuesSelected, index, $select);
553
- options.find("li").eq(index).find(":checkbox").prop("checked", true);
554
- });
555
- }
556
-
557
- // Make option as selected and scroll to selected position
558
- var activateOption = function(collection, newOption) {
559
- if (newOption) {
560
- collection.find('li.selected').removeClass('selected');
561
- var option = $(newOption);
562
- option.addClass('selected');
563
- options.scrollTo(option);
564
- }
565
- };
566
-
567
- // Allow user to search by typing
568
- // this array is cleared after 1 second
569
- var filterQuery = [],
570
- onKeyDown = function(e){
571
- // TAB - switch to another input
572
- if(e.which == 9){
573
- $newSelect.trigger('close');
574
- return;
575
- }
576
-
577
- // ARROW DOWN WHEN SELECT IS CLOSED - open select options
578
- if(e.which == 40 && !options.is(':visible')){
579
- $newSelect.trigger('open');
580
- return;
581
- }
582
-
583
- // ENTER WHEN SELECT IS CLOSED - submit form
584
- if(e.which == 13 && !options.is(':visible')){
585
- return;
586
- }
587
-
588
- e.preventDefault();
589
-
590
- // CASE WHEN USER TYPE LETTERS
591
- var letter = String.fromCharCode(e.which).toLowerCase(),
592
- nonLetters = [9,13,27,38,40];
593
- if (letter && (nonLetters.indexOf(e.which) === -1)) {
594
- filterQuery.push(letter);
595
-
596
- var string = filterQuery.join(''),
597
- newOption = options.find('li').filter(function() {
598
- return $(this).text().toLowerCase().indexOf(string) === 0;
599
- })[0];
600
-
601
- if (newOption) {
602
- activateOption(options, newOption);
603
- }
604
- }
605
-
606
- // ENTER - select option and close when select options are opened
607
- if (e.which == 13) {
608
- var activeOption = options.find('li.selected:not(.disabled)')[0];
609
- if(activeOption){
610
- $(activeOption).trigger('click');
611
- if (!multiple) {
612
- $newSelect.trigger('close');
613
- }
614
- }
615
- }
616
-
617
- // ARROW DOWN - move to next not disabled option
618
- if (e.which == 40) {
619
- if (options.find('li.selected').length) {
620
- newOption = options.find('li.selected').next('li:not(.disabled)')[0];
621
- } else {
622
- newOption = options.find('li:not(.disabled)')[0];
623
- }
624
- activateOption(options, newOption);
625
- }
626
-
627
- // ESC - close options
628
- if (e.which == 27) {
629
- $newSelect.trigger('close');
630
- }
631
-
632
- // ARROW UP - move to previous not disabled option
633
- if (e.which == 38) {
634
- newOption = options.find('li.selected').prev('li:not(.disabled)')[0];
635
- if(newOption)
636
- activateOption(options, newOption);
637
- }
638
-
639
- // Automaticaly clean filter query so user can search again by starting letters
640
- setTimeout(function(){ filterQuery = []; }, 1000);
641
- };
642
-
643
- $newSelect.on('keydown', onKeyDown);
644
- });
645
-
646
- function toggleEntryFromArray(entriesArray, entryIndex, select) {
647
- var index = entriesArray.indexOf(entryIndex),
648
- notAdded = index === -1;
649
-
650
- if (notAdded) {
651
- entriesArray.push(entryIndex);
652
- } else {
653
- entriesArray.splice(index, 1);
654
- }
655
-
656
- select.siblings('ul.dropdown-content').find('li').eq(entryIndex).toggleClass('active');
657
-
658
- // use notAdded instead of true (to detect if the option is selected or not)
659
- select.find('option').eq(entryIndex).prop('selected', notAdded);
660
- setValueToInput(entriesArray, select);
661
-
662
- return notAdded;
663
- }
664
-
665
- function setValueToInput(entriesArray, select) {
666
- var value = '';
667
-
668
- for (var i = 0, count = entriesArray.length; i < count; i++) {
669
- var text = select.find('option').eq(entriesArray[i]).text();
670
-
671
- i === 0 ? value += text : value += ', ' + text;
672
- }
673
-
674
- if (value === '') {
675
- value = select.find('option:disabled').eq(0).text();
676
- }
677
-
678
- select.siblings('input.select-dropdown').val(value);
679
- }
680
- };
681
-
682
- }( jQuery ));