materialize-rails 0.97.5.custom1

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 (100) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +63 -0
  6. data/Rakefile +1 -0
  7. data/lib/materialize-rails.rb +25 -0
  8. data/lib/materialize-rails/engine.rb +14 -0
  9. data/lib/materialize-rails/version.rb +3 -0
  10. data/materialize-rails.gemspec +25 -0
  11. data/vendor/assets/fonts/materialize/material-design-icons/LICENSE.txt +428 -0
  12. data/vendor/assets/fonts/materialize/material-design-icons/Material-Design-Icons.eot +0 -0
  13. data/vendor/assets/fonts/materialize/material-design-icons/Material-Design-Icons.svg +769 -0
  14. data/vendor/assets/fonts/materialize/material-design-icons/Material-Design-Icons.ttf +0 -0
  15. data/vendor/assets/fonts/materialize/material-design-icons/Material-Design-Icons.woff +0 -0
  16. data/vendor/assets/fonts/materialize/material-design-icons/Material-Design-Icons.woff2 +0 -0
  17. data/vendor/assets/fonts/materialize/roboto/Roboto-Bold.eot +0 -0
  18. data/vendor/assets/fonts/materialize/roboto/Roboto-Bold.ttf +0 -0
  19. data/vendor/assets/fonts/materialize/roboto/Roboto-Bold.woff +0 -0
  20. data/vendor/assets/fonts/materialize/roboto/Roboto-Bold.woff2 +0 -0
  21. data/vendor/assets/fonts/materialize/roboto/Roboto-Light.eot +0 -0
  22. data/vendor/assets/fonts/materialize/roboto/Roboto-Light.ttf +0 -0
  23. data/vendor/assets/fonts/materialize/roboto/Roboto-Light.woff +0 -0
  24. data/vendor/assets/fonts/materialize/roboto/Roboto-Light.woff2 +0 -0
  25. data/vendor/assets/fonts/materialize/roboto/Roboto-Medium.eot +0 -0
  26. data/vendor/assets/fonts/materialize/roboto/Roboto-Medium.ttf +0 -0
  27. data/vendor/assets/fonts/materialize/roboto/Roboto-Medium.woff +0 -0
  28. data/vendor/assets/fonts/materialize/roboto/Roboto-Medium.woff2 +0 -0
  29. data/vendor/assets/fonts/materialize/roboto/Roboto-Regular.eot +0 -0
  30. data/vendor/assets/fonts/materialize/roboto/Roboto-Regular.ttf +0 -0
  31. data/vendor/assets/fonts/materialize/roboto/Roboto-Regular.woff +0 -0
  32. data/vendor/assets/fonts/materialize/roboto/Roboto-Regular.woff2 +0 -0
  33. data/vendor/assets/fonts/materialize/roboto/Roboto-Thin.eot +0 -0
  34. data/vendor/assets/fonts/materialize/roboto/Roboto-Thin.ttf +0 -0
  35. data/vendor/assets/fonts/materialize/roboto/Roboto-Thin.woff +0 -0
  36. data/vendor/assets/fonts/materialize/roboto/Roboto-Thin.woff2 +0 -0
  37. data/vendor/assets/javascripts/materialize.js +30 -0
  38. data/vendor/assets/javascripts/materialize/animation.js +9 -0
  39. data/vendor/assets/javascripts/materialize/buttons.js +91 -0
  40. data/vendor/assets/javascripts/materialize/cards.js +29 -0
  41. data/vendor/assets/javascripts/materialize/carousel.js +350 -0
  42. data/vendor/assets/javascripts/materialize/character_counter.js +59 -0
  43. data/vendor/assets/javascripts/materialize/chips.js +9 -0
  44. data/vendor/assets/javascripts/materialize/collapsible.js +137 -0
  45. data/vendor/assets/javascripts/materialize/date_picker/picker.date.js +1430 -0
  46. data/vendor/assets/javascripts/materialize/date_picker/picker.js +1123 -0
  47. data/vendor/assets/javascripts/materialize/dropdown.js +228 -0
  48. data/vendor/assets/javascripts/materialize/forms.js +581 -0
  49. data/vendor/assets/javascripts/materialize/global.js +45 -0
  50. data/vendor/assets/javascripts/materialize/hammer.min.js +1 -0
  51. data/vendor/assets/javascripts/materialize/initial.js +11 -0
  52. data/vendor/assets/javascripts/materialize/jquery.easing.1.3.js +205 -0
  53. data/vendor/assets/javascripts/materialize/jquery.hammer.js +33 -0
  54. data/vendor/assets/javascripts/materialize/leanModal.js +178 -0
  55. data/vendor/assets/javascripts/materialize/materialbox.js +269 -0
  56. data/vendor/assets/javascripts/materialize/parallax.js +58 -0
  57. data/vendor/assets/javascripts/materialize/pushpin.js +62 -0
  58. data/vendor/assets/javascripts/materialize/scrollFire.js +44 -0
  59. data/vendor/assets/javascripts/materialize/scrollspy.js +285 -0
  60. data/vendor/assets/javascripts/materialize/sideNav.js +315 -0
  61. data/vendor/assets/javascripts/materialize/slider.js +321 -0
  62. data/vendor/assets/javascripts/materialize/tabs.js +129 -0
  63. data/vendor/assets/javascripts/materialize/toasts.js +136 -0
  64. data/vendor/assets/javascripts/materialize/tooltip.js +203 -0
  65. data/vendor/assets/javascripts/materialize/transitions.js +154 -0
  66. data/vendor/assets/javascripts/materialize/velocity.min.js +5 -0
  67. data/vendor/assets/javascripts/materialize/waves.js +338 -0
  68. data/vendor/assets/stylesheets/components/_buttons.scss +181 -0
  69. data/vendor/assets/stylesheets/components/_cards.scss +134 -0
  70. data/vendor/assets/stylesheets/components/_carousel.scss +34 -0
  71. data/vendor/assets/stylesheets/components/_chips.scss +27 -0
  72. data/vendor/assets/stylesheets/components/_collapsible.scss +85 -0
  73. data/vendor/assets/stylesheets/components/_color.scss +412 -0
  74. data/vendor/assets/stylesheets/components/_dropdown.scss +57 -0
  75. data/vendor/assets/stylesheets/components/_form.scss +918 -0
  76. data/vendor/assets/stylesheets/components/_global.scss +766 -0
  77. data/vendor/assets/stylesheets/components/_grid.scss +146 -0
  78. data/vendor/assets/stylesheets/components/_icons-material-design.scss +3263 -0
  79. data/vendor/assets/stylesheets/components/_materialbox.scss +42 -0
  80. data/vendor/assets/stylesheets/components/_mixins.scss +5 -0
  81. data/vendor/assets/stylesheets/components/_modal.scss +90 -0
  82. data/vendor/assets/stylesheets/components/_navbar.scss +171 -0
  83. data/vendor/assets/stylesheets/components/_normalize.scss +427 -0
  84. data/vendor/assets/stylesheets/components/_prefixer.scss +384 -0
  85. data/vendor/assets/stylesheets/components/_preloader.scss +334 -0
  86. data/vendor/assets/stylesheets/components/_roboto.scss +49 -0
  87. data/vendor/assets/stylesheets/components/_sideNav.scss +112 -0
  88. data/vendor/assets/stylesheets/components/_slider.scss +92 -0
  89. data/vendor/assets/stylesheets/components/_table_of_contents.scss +33 -0
  90. data/vendor/assets/stylesheets/components/_tabs.scss +56 -0
  91. data/vendor/assets/stylesheets/components/_toast.scss +65 -0
  92. data/vendor/assets/stylesheets/components/_tooltip.scss +33 -0
  93. data/vendor/assets/stylesheets/components/_typography.scss +61 -0
  94. data/vendor/assets/stylesheets/components/_variables.scss +161 -0
  95. data/vendor/assets/stylesheets/components/_waves.scss +173 -0
  96. data/vendor/assets/stylesheets/components/date_picker/_default.date.scss +435 -0
  97. data/vendor/assets/stylesheets/components/date_picker/_default.scss +201 -0
  98. data/vendor/assets/stylesheets/components/date_picker/_default.time.scss +125 -0
  99. data/vendor/assets/stylesheets/materialize.scss +40 -0
  100. metadata +199 -0
@@ -0,0 +1,228 @@
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
+ alignment: 'left'
19
+ };
20
+
21
+ this.each(function(){
22
+ var origin = $(this);
23
+ var options = $.extend({}, defaults, option);
24
+ var isFocused = false;
25
+
26
+ // Dropdown menu
27
+ var activates = $("#"+ origin.attr('data-activates'));
28
+
29
+ function updateOptions() {
30
+ if (origin.data('induration') !== undefined)
31
+ options.inDuration = origin.data('inDuration');
32
+ if (origin.data('outduration') !== undefined)
33
+ options.outDuration = origin.data('outDuration');
34
+ if (origin.data('constrainwidth') !== undefined)
35
+ options.constrain_width = origin.data('constrainwidth');
36
+ if (origin.data('hover') !== undefined)
37
+ options.hover = origin.data('hover');
38
+ if (origin.data('gutter') !== undefined)
39
+ options.gutter = origin.data('gutter');
40
+ if (origin.data('beloworigin') !== undefined)
41
+ options.belowOrigin = origin.data('beloworigin');
42
+ if (origin.data('alignment') !== undefined)
43
+ options.alignment = origin.data('alignment');
44
+ }
45
+
46
+ updateOptions();
47
+
48
+ // Attach dropdown to its activator
49
+ origin.after(activates);
50
+
51
+ /*
52
+ Helper function to position and resize dropdown.
53
+ Used in hover and click handler.
54
+ */
55
+ function placeDropdown(eventType) {
56
+ // Check for simultaneous focus and click events.
57
+ if (eventType === 'focus') {
58
+ isFocused = true;
59
+ }
60
+
61
+ // Check html data attributes
62
+ updateOptions();
63
+
64
+ // Set Dropdown state
65
+ activates.addClass('active');
66
+ origin.addClass('active');
67
+
68
+ // Constrain width
69
+ if (options.constrain_width === true) {
70
+ activates.css('width', origin.outerWidth());
71
+
72
+ } else {
73
+ activates.css('white-space', 'nowrap');
74
+ }
75
+
76
+ // Offscreen detection
77
+ var windowHeight = window.innerHeight;
78
+ var originHeight = origin.innerHeight();
79
+ var offsetLeft = origin.offset().left;
80
+ var offsetTop = origin.offset().top - $(window).scrollTop();
81
+ var currAlignment = options.alignment;
82
+ var activatesLeft, gutterSpacing;
83
+
84
+ // Below Origin
85
+ var verticalOffset = 0;
86
+ if (options.belowOrigin === true) {
87
+ verticalOffset = originHeight;
88
+ }
89
+
90
+ if (offsetLeft + activates.innerWidth() > $(window).width()) {
91
+ // Dropdown goes past screen on right, force right alignment
92
+ currAlignment = 'right';
93
+
94
+ } else if (offsetLeft - activates.innerWidth() + origin.innerWidth() < 0) {
95
+ // Dropdown goes past screen on left, force left alignment
96
+ currAlignment = 'left';
97
+ }
98
+ // Vertical bottom offscreen detection
99
+ if (offsetTop + activates.innerHeight() > windowHeight) {
100
+ // If going upwards still goes offscreen, just crop height of dropdown.
101
+ if (offsetTop + originHeight - activates.innerHeight() < 0) {
102
+ var adjustedHeight = windowHeight - offsetTop - verticalOffset;
103
+ activates.css('max-height', adjustedHeight);
104
+ } else {
105
+ // Flow upwards.
106
+ if (!verticalOffset) {
107
+ verticalOffset += originHeight;
108
+ }
109
+ verticalOffset -= activates.innerHeight();
110
+ }
111
+ }
112
+
113
+ // Handle edge alignment
114
+ if (currAlignment === 'left') {
115
+ gutterSpacing = options.gutter;
116
+ leftPosition = origin.position().left + gutterSpacing;
117
+ }
118
+ else if (currAlignment === 'right') {
119
+ var offsetRight = origin.position().left + origin.outerWidth() - activates.outerWidth();
120
+ gutterSpacing = -options.gutter;
121
+ leftPosition = offsetRight + gutterSpacing;
122
+ }
123
+
124
+ // Position dropdown
125
+ activates.css({
126
+ position: 'absolute',
127
+ top: origin.position().top + verticalOffset,
128
+ left: leftPosition
129
+ });
130
+
131
+
132
+ // Show dropdown
133
+ activates.stop(true, true).css('opacity', 0)
134
+ .slideDown({
135
+ queue: false,
136
+ duration: options.inDuration,
137
+ easing: 'easeOutCubic',
138
+ complete: function() {
139
+ $(this).css('height', '');
140
+ }
141
+ })
142
+ .animate( {opacity: 1}, {queue: false, duration: options.inDuration, easing: 'easeOutSine'});
143
+ }
144
+
145
+ function hideDropdown() {
146
+ // Check for simultaneous focus and click events.
147
+ isFocused = false;
148
+ activates.fadeOut(options.outDuration);
149
+ activates.removeClass('active');
150
+ origin.removeClass('active');
151
+ setTimeout(function() { activates.css('max-height', ''); }, options.outDuration);
152
+ }
153
+
154
+ // Hover
155
+ if (options.hover) {
156
+ var open = false;
157
+ origin.unbind('click.' + origin.attr('id'));
158
+ // Hover handler to show dropdown
159
+ origin.on('mouseenter', function(e){ // Mouse over
160
+ if (open === false) {
161
+ placeDropdown();
162
+ open = true;
163
+ }
164
+ });
165
+ origin.on('mouseleave', function(e){
166
+ // If hover on origin then to something other than dropdown content, then close
167
+ var toEl = e.toElement || e.relatedTarget; // added browser compatibility for target element
168
+ if(!$(toEl).closest('.dropdown-content').is(activates)) {
169
+ activates.stop(true, true);
170
+ hideDropdown();
171
+ open = false;
172
+ }
173
+ });
174
+
175
+ activates.on('mouseleave', function(e){ // Mouse out
176
+ var toEl = e.toElement || e.relatedTarget;
177
+ if(!$(toEl).closest('.dropdown-button').is(origin)) {
178
+ activates.stop(true, true);
179
+ hideDropdown();
180
+ open = false;
181
+ }
182
+ });
183
+
184
+ // Click
185
+ } else {
186
+ // Click handler to show dropdown
187
+ origin.unbind('click.' + origin.attr('id'));
188
+ origin.bind('click.'+origin.attr('id'), function(e){
189
+ if (!isFocused) {
190
+ if ( origin[0] == e.currentTarget &&
191
+ !origin.hasClass('active') &&
192
+ ($(e.target).closest('.dropdown-content').length === 0)) {
193
+ e.preventDefault(); // Prevents button click from moving window
194
+ placeDropdown('click');
195
+ }
196
+ // If origin is clicked and menu is open, close menu
197
+ else if (origin.hasClass('active')) {
198
+ hideDropdown();
199
+ $(document).unbind('click.'+ activates.attr('id') + ' touchstart.' + activates.attr('id'));
200
+ }
201
+ // If menu open, add click close handler to document
202
+ if (activates.hasClass('active')) {
203
+ $(document).bind('click.'+ activates.attr('id') + ' touchstart.' + activates.attr('id'), function (e) {
204
+ if (!activates.is(e.target) && !origin.is(e.target) && (!origin.find(e.target).length) ) {
205
+ hideDropdown();
206
+ $(document).unbind('click.'+ activates.attr('id') + ' touchstart.' + activates.attr('id'));
207
+ }
208
+ });
209
+ }
210
+ }
211
+ });
212
+
213
+ } // End else
214
+
215
+ // Listen to open and close event - useful for select component
216
+ origin.on('open', function(e, eventType) {
217
+ placeDropdown(eventType);
218
+ });
219
+ origin.on('close', hideDropdown);
220
+
221
+
222
+ });
223
+ }; // End dropdown plugin
224
+
225
+ $(document).ready(function(){
226
+ $('.dropdown-button').dropdown();
227
+ });
228
+ }( jQuery ));
@@ -0,0 +1,581 @@
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 || element.autofocus ||$(this).attr('placeholder') !== undefined || $(element)[0].validity.badInput === true) {
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
+ // 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).ready(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, i').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, i').addClass('active');
55
+ });
56
+
57
+ $(document).on('blur', input_selector, function () {
58
+ var $inputElement = $(this);
59
+ if ($inputElement.val().length === 0 && $inputElement[0].validity.badInput !== true && $inputElement.attr('placeholder') === undefined) {
60
+ $inputElement.siblings('label, i').removeClass('active');
61
+ }
62
+
63
+ if ($inputElement.val().length === 0 && $inputElement[0].validity.badInput !== true && $inputElement.attr('placeholder') !== undefined) {
64
+ $inputElement.siblings('i').removeClass('active');
65
+ }
66
+ validate_field($inputElement);
67
+ });
68
+
69
+ window.validate_field = function(object) {
70
+ var hasLength = object.attr('length') !== undefined;
71
+ var lenAttr = parseInt(object.attr('length'));
72
+ var len = object.val().length;
73
+
74
+ if (object.val().length === 0 && object[0].validity.badInput === false) {
75
+ if (object.hasClass('validate')) {
76
+ object.removeClass('valid');
77
+ object.removeClass('invalid');
78
+ }
79
+ }
80
+ else {
81
+ if (object.hasClass('validate')) {
82
+ // Check for character counter attributes
83
+ if ((object.is(':valid') && hasLength && (len <= lenAttr)) || (object.is(':valid') && !hasLength)) {
84
+ object.removeClass('invalid');
85
+ object.addClass('valid');
86
+ }
87
+ else {
88
+ object.removeClass('valid');
89
+ object.addClass('invalid');
90
+ }
91
+ }
92
+ }
93
+ };
94
+
95
+
96
+ // Textarea Auto Resize
97
+ var hiddenDiv = $('.hiddendiv').first();
98
+ if (!hiddenDiv.length) {
99
+ hiddenDiv = $('<div class="hiddendiv common"></div>');
100
+ $('body').append(hiddenDiv);
101
+ }
102
+ var text_area_selector = '.materialize-textarea';
103
+
104
+ function textareaAutoResize($textarea) {
105
+ // Set font properties of hiddenDiv
106
+
107
+ var fontFamily = $textarea.css('font-family');
108
+ var fontSize = $textarea.css('font-size');
109
+
110
+ if (fontSize) { hiddenDiv.css('font-size', fontSize); }
111
+ if (fontFamily) { hiddenDiv.css('font-family', fontFamily); }
112
+
113
+ if ($textarea.attr('wrap') === "off") {
114
+ hiddenDiv.css('overflow-wrap', "normal")
115
+ .css('white-space', "pre");
116
+ }
117
+
118
+ hiddenDiv.text($textarea.val() + '\n');
119
+ var content = hiddenDiv.html().replace(/\n/g, '<br>');
120
+ hiddenDiv.html(content);
121
+
122
+
123
+ // When textarea is hidden, width goes crazy.
124
+ // Approximate with half of window size
125
+
126
+ if ($textarea.is(':visible')) {
127
+ hiddenDiv.css('width', $textarea.width());
128
+ }
129
+ else {
130
+ hiddenDiv.css('width', $(window).width()/2);
131
+ }
132
+
133
+ $textarea.css('height', hiddenDiv.height());
134
+ }
135
+
136
+ $(text_area_selector).each(function () {
137
+ var $textarea = $(this);
138
+ if ($textarea.val().length) {
139
+ textareaAutoResize($textarea);
140
+ }
141
+ });
142
+
143
+ $('body').on('keyup keydown autoresize', text_area_selector, function () {
144
+ textareaAutoResize($(this));
145
+ });
146
+
147
+ // File Input Path
148
+ $(document).on('change', '.file-field input[type="file"]', function () {
149
+ var file_field = $(this).closest('.file-field');
150
+ var path_input = file_field.find('input.file-path');
151
+ var files = $(this)[0].files;
152
+ var file_names = [];
153
+ for (var i = 0; i < files.length; i++) {
154
+ file_names.push(files[i].name);
155
+ }
156
+ path_input.val(file_names.join(", "));
157
+ path_input.trigger('change');
158
+ });
159
+
160
+ /****************
161
+ * Range Input *
162
+ ****************/
163
+
164
+ var range_type = 'input[type=range]';
165
+ var range_mousedown = false;
166
+ var left;
167
+
168
+ $(range_type).each(function () {
169
+ var thumb = $('<span class="thumb"><span class="value"></span></span>');
170
+ $(this).after(thumb);
171
+ });
172
+
173
+ var range_wrapper = '.range-field';
174
+ $(document).on('change', range_type, function(e) {
175
+ var thumb = $(this).siblings('.thumb');
176
+ thumb.find('.value').html($(this).val());
177
+ });
178
+
179
+ $(document).on('input mousedown touchstart', range_type, function(e) {
180
+ var thumb = $(this).siblings('.thumb');
181
+ var width = $(this).outerWidth();
182
+
183
+ // If thumb indicator does not exist yet, create it
184
+ if (thumb.length <= 0) {
185
+ thumb = $('<span class="thumb"><span class="value"></span></span>');
186
+ $(this).after(thumb);
187
+ }
188
+
189
+ // Set indicator value
190
+ thumb.find('.value').html($(this).val());
191
+
192
+ range_mousedown = true;
193
+ $(this).addClass('active');
194
+
195
+ if (!thumb.hasClass('active')) {
196
+ thumb.velocity({ height: "30px", width: "30px", top: "-20px", marginLeft: "-15px"}, { duration: 300, easing: 'easeOutExpo' });
197
+ }
198
+
199
+ if (e.type !== 'input') {
200
+ if(e.pageX === undefined || e.pageX === null){//mobile
201
+ left = e.originalEvent.touches[0].pageX - $(this).offset().left;
202
+ }
203
+ else{ // desktop
204
+ left = e.pageX - $(this).offset().left;
205
+ }
206
+ if (left < 0) {
207
+ left = 0;
208
+ }
209
+ else if (left > width) {
210
+ left = width;
211
+ }
212
+ thumb.addClass('active').css('left', left);
213
+ }
214
+
215
+ thumb.find('.value').html($(this).val());
216
+ });
217
+
218
+ $(document).on('mouseup touchend', range_wrapper, function() {
219
+ range_mousedown = false;
220
+ $(this).removeClass('active');
221
+ });
222
+
223
+ $(document).on('mousemove touchmove', range_wrapper, function(e) {
224
+ var thumb = $(this).children('.thumb');
225
+ var left;
226
+ if (range_mousedown) {
227
+ if (!thumb.hasClass('active')) {
228
+ thumb.velocity({ height: '30px', width: '30px', top: '-20px', marginLeft: '-15px'}, { duration: 300, easing: 'easeOutExpo' });
229
+ }
230
+ if (e.pageX === undefined || e.pageX === null) { //mobile
231
+ left = e.originalEvent.touches[0].pageX - $(this).offset().left;
232
+ }
233
+ else{ // desktop
234
+ left = e.pageX - $(this).offset().left;
235
+ }
236
+ var width = $(this).outerWidth();
237
+
238
+ if (left < 0) {
239
+ left = 0;
240
+ }
241
+ else if (left > width) {
242
+ left = width;
243
+ }
244
+ thumb.addClass('active').css('left', left);
245
+ thumb.find('.value').html(thumb.siblings(range_type).val());
246
+ }
247
+ });
248
+
249
+ $(document).on('mouseout touchleave', range_wrapper, function() {
250
+ if (!range_mousedown) {
251
+
252
+ var thumb = $(this).children('.thumb');
253
+
254
+ if (thumb.hasClass('active')) {
255
+ thumb.velocity({ height: '0', width: '0', top: '10px', marginLeft: '-6px'}, { duration: 100 });
256
+ }
257
+ thumb.removeClass('active');
258
+ }
259
+ });
260
+ }); // End of $(document).ready
261
+
262
+ /*******************
263
+ * Select Plugin *
264
+ ******************/
265
+ $.fn.material_select = function (callback) {
266
+ $(this).each(function(){
267
+ var $select = $(this);
268
+
269
+ if ($select.hasClass('browser-default')) {
270
+ return; // Continue to next (return false breaks out of entire loop)
271
+ }
272
+
273
+ var multiple = $select.attr('multiple') ? true : false,
274
+ lastID = $select.data('select-id'); // Tear down structure if Select needs to be rebuilt
275
+
276
+ if (lastID) {
277
+ $select.parent().find('span.caret').remove();
278
+ $select.parent().find('input').remove();
279
+
280
+ $select.unwrap();
281
+ $('ul#select-options-'+lastID).remove();
282
+ }
283
+
284
+ // If destroying the select, remove the selelct-id and reset it to it's uninitialized state.
285
+ if(callback === 'destroy') {
286
+ $select.data('select-id', null).removeClass('initialized');
287
+ return;
288
+ }
289
+
290
+ var uniqueID = Materialize.guid();
291
+ $select.data('select-id', uniqueID);
292
+ var wrapper = $('<div class="select-wrapper"></div>');
293
+ wrapper.addClass($select.attr('class'));
294
+ var options = $('<ul id="select-options-' + uniqueID +'" class="dropdown-content select-dropdown ' + (multiple ? 'multiple-select-dropdown' : '') + '"></ul>'),
295
+ selectChildren = $select.children('option, optgroup'),
296
+ valuesSelected = [],
297
+ optionsHover = false;
298
+
299
+ var label = $select.find('option:selected').html() || $select.find('option:first').html() || "";
300
+
301
+ // Function that renders and appends the option taking into
302
+ // account type and possible image icon.
303
+ var appendOptionWithIcon = function(select, option, type) {
304
+ // Add disabled attr if disabled
305
+ var disabledClass = (option.is(':disabled')) ? 'disabled ' : '';
306
+
307
+ // add icons
308
+ var icon_url = option.data('icon');
309
+ var classes = option.attr('class');
310
+ if (!!icon_url) {
311
+ var classString = '';
312
+ if (!!classes) classString = ' class="' + classes + '"';
313
+
314
+ // Check for multiple type.
315
+ if (type === 'multiple') {
316
+ options.append($('<li class="' + disabledClass + '"><img src="' + icon_url + '"' + classString + '><span><input type="checkbox"' + disabledClass + '/><label></label>' + option.html() + '</span></li>'));
317
+ } else {
318
+ options.append($('<li class="' + disabledClass + '"><img src="' + icon_url + '"' + classString + '><span>' + option.html() + '</span></li>'));
319
+ }
320
+ return true;
321
+ }
322
+
323
+ // Check for multiple type.
324
+ if (type === 'multiple') {
325
+ options.append($('<li class="' + disabledClass + '"><span><input type="checkbox"' + disabledClass + '/><label></label>' + option.html() + '</span></li>'));
326
+ } else {
327
+ options.append($('<li class="' + disabledClass + '"><span>' + option.html() + '</span></li>'));
328
+ }
329
+ };
330
+
331
+ /* Create dropdown structure. */
332
+ if (selectChildren.length) {
333
+ selectChildren.each(function() {
334
+ if ($(this).is('option')) {
335
+ // Direct descendant option.
336
+ if (multiple) {
337
+ appendOptionWithIcon($select, $(this), 'multiple');
338
+
339
+ } else {
340
+ appendOptionWithIcon($select, $(this));
341
+ }
342
+ } else if ($(this).is('optgroup')) {
343
+ // Optgroup.
344
+ var selectOptions = $(this).children('option');
345
+ options.append($('<li class="optgroup"><span>' + $(this).attr('label') + '</span></li>'));
346
+
347
+ selectOptions.each(function() {
348
+ appendOptionWithIcon($select, $(this));
349
+ });
350
+ }
351
+ });
352
+ }
353
+
354
+ options.find('li:not(.optgroup)').each(function (i) {
355
+ $(this).click(function (e) {
356
+ // Check if option element is disabled
357
+ if (!$(this).hasClass('disabled') && !$(this).hasClass('optgroup')) {
358
+ var selected = true;
359
+
360
+ if (multiple) {
361
+ $('input[type="checkbox"]', this).prop('checked', function(i, v) { return !v; });
362
+ selected = toggleEntryFromArray(valuesSelected, $(this).index(), $select);
363
+ $newSelect.trigger('focus');
364
+ } else {
365
+ options.find('li').removeClass('active');
366
+ $(this).toggleClass('active');
367
+ $newSelect.val($(this).text());
368
+ }
369
+
370
+ activateOption(options, $(this));
371
+ $select.find('option').eq(i).prop('selected', selected);
372
+ // Trigger onchange() event
373
+ $select.trigger('change');
374
+ if (typeof callback !== 'undefined') callback();
375
+ }
376
+
377
+ e.stopPropagation();
378
+ });
379
+ });
380
+
381
+ // Wrap Elements
382
+ $select.wrap(wrapper);
383
+ // Add Select Display Element
384
+ var dropdownIcon = $('<span class="caret">&#9660;</span>');
385
+ if ($select.is(':disabled'))
386
+ dropdownIcon.addClass('disabled');
387
+
388
+ // escape double quotes
389
+ var sanitizedLabelHtml = label.replace(/"/g, '&quot;');
390
+
391
+ var $newSelect = $('<input type="text" class="select-dropdown" readonly="true" ' + (($select.is(':disabled')) ? 'disabled' : '') + ' data-activates="select-options-' + uniqueID +'" value="'+ sanitizedLabelHtml +'"/>');
392
+ $select.before($newSelect);
393
+ $newSelect.before(dropdownIcon);
394
+
395
+ $newSelect.after(options);
396
+ // Check if section element is disabled
397
+ if (!$select.is(':disabled')) {
398
+ $newSelect.dropdown({'hover': false, 'closeOnClick': false});
399
+ }
400
+
401
+ // Copy tabindex
402
+ if ($select.attr('tabindex')) {
403
+ $($newSelect[0]).attr('tabindex', $select.attr('tabindex'));
404
+ }
405
+
406
+ $select.addClass('initialized');
407
+
408
+ $newSelect.on({
409
+ 'focus': function (){
410
+ if ($('ul.select-dropdown').not(options[0]).is(':visible')) {
411
+ $('input.select-dropdown').trigger('close');
412
+ }
413
+ if (!options.is(':visible')) {
414
+ $(this).trigger('open', ['focus']);
415
+ var label = $(this).val();
416
+ var selectedOption = options.find('li').filter(function() {
417
+ return $(this).text().toLowerCase() === label.toLowerCase();
418
+ })[0];
419
+ activateOption(options, selectedOption);
420
+ }
421
+ },
422
+ 'click': function (e){
423
+ e.stopPropagation();
424
+ }
425
+ });
426
+
427
+ $newSelect.on('blur', function() {
428
+ if (!multiple) {
429
+ $(this).trigger('close');
430
+ }
431
+ options.find('li.selected').removeClass('selected');
432
+ });
433
+
434
+ options.hover(function() {
435
+ optionsHover = true;
436
+ }, function () {
437
+ optionsHover = false;
438
+ });
439
+
440
+ $(window).on({
441
+ 'click': function () {
442
+ multiple && (optionsHover || $newSelect.trigger('close'));
443
+ }
444
+ });
445
+
446
+ // Add initial multiple selections.
447
+ if (multiple) {
448
+ $select.find("option:selected:not(:disabled)").each(function () {
449
+ var index = $(this).index();
450
+
451
+ toggleEntryFromArray(valuesSelected, index, $select);
452
+ options.find("li").eq(index).find(":checkbox").prop("checked", true);
453
+ });
454
+ }
455
+
456
+ // Make option as selected and scroll to selected position
457
+ activateOption = function(collection, newOption) {
458
+ if (newOption) {
459
+ collection.find('li.selected').removeClass('selected');
460
+ var option = $(newOption);
461
+ option.addClass('selected');
462
+ options.scrollTo(option);
463
+ }
464
+ };
465
+
466
+ // Allow user to search by typing
467
+ // this array is cleared after 1 second
468
+ var filterQuery = [],
469
+ onKeyDown = function(e){
470
+ // TAB - switch to another input
471
+ if(e.which == 9){
472
+ $newSelect.trigger('close');
473
+ return;
474
+ }
475
+
476
+ // ARROW DOWN WHEN SELECT IS CLOSED - open select options
477
+ if(e.which == 40 && !options.is(':visible')){
478
+ $newSelect.trigger('open');
479
+ return;
480
+ }
481
+
482
+ // ENTER WHEN SELECT IS CLOSED - submit form
483
+ if(e.which == 13 && !options.is(':visible')){
484
+ return;
485
+ }
486
+
487
+ e.preventDefault();
488
+
489
+ // CASE WHEN USER TYPE LETTERS
490
+ var letter = String.fromCharCode(e.which).toLowerCase(),
491
+ nonLetters = [9,13,27,38,40];
492
+ if (letter && (nonLetters.indexOf(e.which) === -1)) {
493
+ filterQuery.push(letter);
494
+
495
+ var string = filterQuery.join(''),
496
+ newOption = options.find('li').filter(function() {
497
+ return $(this).text().toLowerCase().indexOf(string) === 0;
498
+ })[0];
499
+
500
+ if (newOption) {
501
+ activateOption(options, newOption);
502
+ }
503
+ }
504
+
505
+ // ENTER - select option and close when select options are opened
506
+ if (e.which == 13) {
507
+ var activeOption = options.find('li.selected:not(.disabled)')[0];
508
+ if(activeOption){
509
+ $(activeOption).trigger('click');
510
+ if (!multiple) {
511
+ $newSelect.trigger('close');
512
+ }
513
+ }
514
+ }
515
+
516
+ // ARROW DOWN - move to next not disabled option
517
+ if (e.which == 40) {
518
+ if (options.find('li.selected').length) {
519
+ newOption = options.find('li.selected').next('li:not(.disabled)')[0];
520
+ } else {
521
+ newOption = options.find('li:not(.disabled)')[0];
522
+ }
523
+ activateOption(options, newOption);
524
+ }
525
+
526
+ // ESC - close options
527
+ if (e.which == 27) {
528
+ $newSelect.trigger('close');
529
+ }
530
+
531
+ // ARROW UP - move to previous not disabled option
532
+ if (e.which == 38) {
533
+ newOption = options.find('li.selected').prev('li:not(.disabled)')[0];
534
+ if(newOption)
535
+ activateOption(options, newOption);
536
+ }
537
+
538
+ // Automaticaly clean filter query so user can search again by starting letters
539
+ setTimeout(function(){ filterQuery = []; }, 1000);
540
+ };
541
+
542
+ $newSelect.on('keydown', onKeyDown);
543
+ });
544
+
545
+ function toggleEntryFromArray(entriesArray, entryIndex, select) {
546
+ var index = entriesArray.indexOf(entryIndex),
547
+ notAdded = index === -1;
548
+
549
+ if (notAdded) {
550
+ entriesArray.push(entryIndex);
551
+ } else {
552
+ entriesArray.splice(index, 1);
553
+ }
554
+
555
+ select.siblings('ul.dropdown-content').find('li').eq(entryIndex).toggleClass('active');
556
+
557
+ // use notAdded instead of true (to detect if the option is selected or not)
558
+ select.find('option').eq(entryIndex).prop('selected', notAdded);
559
+ setValueToInput(entriesArray, select);
560
+
561
+ return notAdded;
562
+ }
563
+
564
+ function setValueToInput(entriesArray, select) {
565
+ var value = '';
566
+
567
+ for (var i = 0, count = entriesArray.length; i < count; i++) {
568
+ var text = select.find('option').eq(entriesArray[i]).text();
569
+
570
+ i === 0 ? value += text : value += ', ' + text;
571
+ }
572
+
573
+ if (value === '') {
574
+ value = select.find('option:disabled').eq(0).text();
575
+ }
576
+
577
+ select.siblings('input.select-dropdown').val(value);
578
+ }
579
+ };
580
+
581
+ }( jQuery ));