jquery-selectric-rails 1.9.3

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 550481339156e1e8f2043e57f5207e7be844abf8
4
+ data.tar.gz: c9d9451249cbbba393119388261b2a261f568aa0
5
+ SHA512:
6
+ metadata.gz: 6874fdd45dc68f1eeb4c29afe4b4fadd9a40c0bcd4c0d3f985f75404766a8f9817c274c9424b7ea9314125143248f5297fe2918424e94ccaced2c814ad899aa8
7
+ data.tar.gz: dc9da3bb34206a0c48cbaec2cb3194b604cd27a723319ed4a9449b8a0f598a42ad12fa59c08c57a574bcc2afd6e6c829bf465ba9fd7223af06061f41ddb9fd9c
data/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # jQuery::Selectric::Rails
2
+
3
+ This gem provides [jQuery Selectric](https://github.com/lcdsantos/jQuery-Selectric) plugin for your Rails application.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'jquery-selectric-rails'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install jquery-selectric-rails
18
+
19
+ ## Usage
20
+
21
+ ### Include the Redactor assets
22
+
23
+ Add to your `application.js`:
24
+
25
+ //= require jquery.selectric
26
+
27
+ Add to your `application.css`:
28
+
29
+ *= require jquery.selectric
30
+
31
+
32
+ Or if you are using SASS:
33
+
34
+ @import('jquery.selectric');
35
+
36
+ ### Initialize
37
+
38
+ For each select that you want to apply jQuery Selectric, add the "selectric" class and ensure it has a unique ID:
39
+
40
+ <%= select_tag :my_select, options_for_select(['option1', 'option2']), class: "selectric" %>
41
+
42
+ ## Contributing
43
+
44
+ 1. Fork it
45
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
46
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
47
+ 4. Push to the branch (`git push origin my-new-feature`)
48
+ 5. Create new Pull Request
@@ -0,0 +1,11 @@
1
+ require 'jquery/selectric/rails/version'
2
+
3
+ module Jquery
4
+ module Selectric
5
+ module Rails
6
+ class Engine < ::Rails::Engine
7
+
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module Jquery
2
+ module Selectric
3
+ module Rails
4
+ VERSION = '1.9.3'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ //= require lib/jquery.selectric
2
+ $(function() {
3
+ $('select.selectric').selectric();
4
+ });
5
+
@@ -0,0 +1,538 @@
1
+ ;(function($) {
2
+ 'use strict';
3
+
4
+ var pluginName = 'selectric',
5
+ classList = 'Input Items Open Disabled TempShow HideSelect Wrapper Hover Responsive Above Scroll Group GroupLabel',
6
+ bindSufix = '.sl',
7
+ defaults = {
8
+ onChange: function(elm) { $(elm).change(); },
9
+ maxHeight: 300,
10
+ keySearchTimeout: 500,
11
+ arrowButtonMarkup: '<b class="button">&#x25be;</b>',
12
+ disableOnMobile: true,
13
+ openOnHover: false,
14
+ hoverIntentTimeout: 500,
15
+ expandToItemText: false,
16
+ responsive: false,
17
+ preventWindowScroll: true,
18
+ inheritOriginalWidth: false,
19
+ allowWrap: true,
20
+ customClass: {
21
+ prefix: pluginName,
22
+ camelCase: false,
23
+ overwrite: true
24
+ },
25
+ optionsItemBuilder: '{text}', // function(itemData, element, index)
26
+ labelBuilder: '{text}' // function(currItem)
27
+ },
28
+ hooks = {
29
+ add: function(callbackName, hookName, fn) {
30
+ if ( !this[callbackName] )
31
+ this[callbackName] = {};
32
+
33
+ this[callbackName][hookName] = fn;
34
+ },
35
+ remove: function(callbackName, hookName) {
36
+ delete this[callbackName][hookName];
37
+ }
38
+ },
39
+ _utils = {
40
+ // Replace diacritics
41
+ replaceDiacritics: function(s) {
42
+ // /[\340-\346]/g, // a
43
+ // /[\350-\353]/g, // e
44
+ // /[\354-\357]/g, // i
45
+ // /[\362-\370]/g, // o
46
+ // /[\371-\374]/g, // u
47
+ // /[\361]/g, // n
48
+ // /[\347]/g, // c
49
+ // /[\377]/g // y
50
+ var d = '40-46 50-53 54-57 62-70 71-74 61 47 77'.replace(/\d+/g, '\\3$&').split(' '),
51
+ k = d.length;
52
+
53
+ while (k--)
54
+ s = s.toLowerCase().replace(RegExp('[' + d[k] + ']', 'g'), 'aeiouncy'.charAt(k));
55
+
56
+ return s;
57
+ },
58
+ // https://gist.github.com/atesgoral/984375
59
+ format: function(f) {var a=arguments;return(""+f).replace(/{(\d+|(\w+))}/g,function(s,i,p) {return p&&a[1]?a[1][p]:a[i]})},
60
+ nextEnabledItem: function(selectItems, selected) {
61
+ while ( selectItems[ selected = (selected + 1) % selectItems.length ].disabled ) {}
62
+ return selected;
63
+ },
64
+ previousEnabledItem: function(selectItems, selected) {
65
+ while ( selectItems[ selected = (selected > 0 ? selected : selectItems.length) - 1 ].disabled ) {}
66
+ return selected;
67
+ },
68
+ toDash: function(str) {
69
+ return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
70
+ },
71
+ triggerCallback: function(fn, scope) {
72
+ var elm = scope.element,
73
+ func = scope.options['on' + fn];
74
+
75
+ if ( $.isFunction(func) )
76
+ func.call(elm, elm, scope);
77
+
78
+ if ( hooks[fn] ) {
79
+ $.each(hooks[fn], function() {
80
+ this.call(elm, elm, scope);
81
+ });
82
+ }
83
+
84
+ $(elm).trigger(pluginName + '-' + _utils.toDash(fn), scope);
85
+ }
86
+ },
87
+ $doc = $(document),
88
+ $win = $(window),
89
+ Selectric = function(element, opts) {
90
+ var _this = this,
91
+ $original = $(element),
92
+ $input, $items, $itemsScroll, $wrapper, $label, $outerWrapper, $li,
93
+ isOpen = false,
94
+ isEnabled = false,
95
+ selected,
96
+ currValue,
97
+ itemsHeight,
98
+ itemsInnerHeight,
99
+ finalWidth,
100
+ optionsLength,
101
+ eventTriggers,
102
+ isMobile = /android|ip(hone|od|ad)/i.test(navigator.userAgent),
103
+ tabindex = $original.prop('tabindex'),
104
+ labelBuilder;
105
+
106
+ function _init(opts) {
107
+ _this.options = $.extend(true, {}, defaults, _this.options, opts);
108
+ _this.classes = {};
109
+ _this.element = element;
110
+
111
+ _utils.triggerCallback('BeforeInit', _this);
112
+
113
+ // Disable on mobile browsers
114
+ if ( _this.options.disableOnMobile && isMobile ) {
115
+ _this.disableOnMobile = true;
116
+ return;
117
+ }
118
+
119
+ // Preserve data
120
+ _destroy(true);
121
+
122
+ // Generate classNames for elements
123
+ var customClass = _this.options.customClass,
124
+ postfixes = classList.split(' '),
125
+ originalWidth = $original.width();
126
+
127
+ $.each(postfixes, function(i, currClass) {
128
+ var c = customClass.prefix + '-' + currClass;
129
+ _this.classes[currClass.toLowerCase()] = customClass.camelCase ? c : _utils.toDash(c);
130
+ });
131
+
132
+ $input = $('<input/>', { 'class': _this.classes.input, 'readonly': isMobile });
133
+ $items = $('<div/>', { 'class': _this.classes.items, 'tabindex': -1 });
134
+ $itemsScroll = $('<div/>', { 'class': _this.classes.scroll });
135
+ $wrapper = $('<div/>', { 'class': customClass.prefix, 'html': _this.options.arrowButtonMarkup });
136
+ $label = $('<p class="label"/>');
137
+ $outerWrapper = $original.wrap('<div>').parent().append($wrapper.prepend($label), $items, $input);
138
+
139
+ eventTriggers = {
140
+ open : _open,
141
+ close : _close,
142
+ destroy : _destroy,
143
+ refresh : _refresh,
144
+ init : _init
145
+ };
146
+
147
+ $original.on(eventTriggers).wrap('<div class="' + _this.classes.hideselect + '">');
148
+ $.extend(_this, eventTriggers);
149
+
150
+ labelBuilder = _this.options.labelBuilder;
151
+
152
+ if ( _this.options.inheritOriginalWidth && originalWidth > 0 )
153
+ $outerWrapper.width(originalWidth);
154
+
155
+ _populate();
156
+ }
157
+
158
+ // Generate options markup and event binds
159
+ function _populate() {
160
+ _this.items = [];
161
+
162
+ var $options = $original.children(),
163
+ _$li = '<ul>',
164
+ $justOptions = $original.find('option'),
165
+ selectedIndex = $justOptions.index($justOptions.filter(':selected')),
166
+ currIndex = 0;
167
+
168
+ currValue = (selected = ~selectedIndex ? selectedIndex : 0);
169
+
170
+ if ( optionsLength = $options.length ) {
171
+ // Build options markup
172
+ $options.each(function() {
173
+ var $elm = $(this);
174
+
175
+ if ( $elm.is('optgroup') ) {
176
+ var groupDisabled = $elm.prop('disabled'),
177
+ $children = $elm.children();
178
+
179
+ _$li += _utils.format('<ul class="{1}"><li class="{2}">{3}</li>',
180
+ $.trim([_this.classes.group, groupDisabled ? 'disabled' : '', $elm.prop('class')].join(' ')),
181
+ _this.classes.grouplabel,
182
+ $elm.prop('label')
183
+ );
184
+
185
+ if ( groupDisabled ) {
186
+ $children.prop('disabled', true);
187
+ }
188
+
189
+ $children.each(buildOption);
190
+
191
+ _$li += '</ul>';
192
+ } else {
193
+ buildOption.call($elm);
194
+ }
195
+
196
+ function buildOption() {
197
+ var $elm = $(this),
198
+ optionText = $elm.html(),
199
+ selectDisabled = $elm.prop('disabled'),
200
+ itemBuilder = _this.options.optionsItemBuilder;
201
+
202
+ _this.items[currIndex] = {
203
+ element : $elm,
204
+ value : $elm.val(),
205
+ text : optionText,
206
+ slug : _utils.replaceDiacritics(optionText),
207
+ disabled : selectDisabled
208
+ };
209
+
210
+ _$li += _utils.format('<li data-index="{1}" class="{2}">{3}</li>',
211
+ currIndex,
212
+ $.trim([currIndex == currValue ? 'selected' : '', currIndex == optionsLength - 1 ? 'last' : '', selectDisabled ? 'disabled' : ''].join(' ')),
213
+ $.isFunction(itemBuilder) ? itemBuilder(_this.items[currIndex], $elm, currIndex) : _utils.format(itemBuilder, _this.items[currIndex])
214
+ );
215
+
216
+ currIndex++;
217
+ }
218
+ });
219
+
220
+ $items.append( $itemsScroll.html(_$li + '</ul>') );
221
+
222
+ $label.html(
223
+ $.isFunction(labelBuilder) ? labelBuilder(_this.items[currValue]) : _utils.format(labelBuilder, _this.items[currValue])
224
+ )
225
+ }
226
+
227
+ $wrapper.add($original).add($outerWrapper).add($input).off(bindSufix);
228
+
229
+ $outerWrapper.prop('class', [
230
+ _this.classes.wrapper,
231
+ _this.options.customClass.overwrite ?
232
+ $original.prop('class').replace(/\S+/g, _this.options.customClass.prefix + '-$&') :
233
+ $original.prop('class'),
234
+ _this.options.responsive ? _this.classes.responsive : ''
235
+ ].join(' '));
236
+
237
+ if ( !$original.prop('disabled') ) {
238
+ isEnabled = true;
239
+
240
+ // Not disabled, so... Removing disabled class and bind hover
241
+ $outerWrapper.removeClass(_this.classes.disabled).on('mouseenter' + bindSufix + ' mouseleave' + bindSufix, function(e) {
242
+ $(this).toggleClass(_this.classes.hover);
243
+
244
+ // Delay close effect when openOnHover is true
245
+ if ( _this.options.openOnHover ) {
246
+ clearTimeout(_this.closeTimer);
247
+ e.type == 'mouseleave' ? _this.closeTimer = setTimeout(_close, _this.options.hoverIntentTimeout) : _open();
248
+ }
249
+ });
250
+
251
+ // Toggle open/close
252
+ $wrapper.on('click' + bindSufix, function(e) {
253
+ isOpen ? _close() : _open(e);
254
+ });
255
+
256
+ $input
257
+ .prop({
258
+ tabindex: tabindex,
259
+ disabled: false
260
+ })
261
+ .on('keypress' + bindSufix, _handleSystemKeys)
262
+ .on('keydown' + bindSufix, function(e) {
263
+ _handleSystemKeys(e);
264
+
265
+ // Clear search
266
+ clearTimeout(_this.resetStr);
267
+ _this.resetStr = setTimeout(function() {
268
+ $input.val('');
269
+ }, _this.options.keySearchTimeout);
270
+
271
+ var key = e.keyCode || e.which;
272
+
273
+ // If it's a directional key
274
+ // 37 => Left
275
+ // 38 => Up
276
+ // 39 => Right
277
+ // 40 => Down
278
+ if ( key > 36 && key < 41 ) {
279
+ if ( !_this.options.allowWrap ) {
280
+ if ( (key < 39 && selected == 0) || (key > 38 && (selected + 1) == _this.items.length) ) {
281
+ return;
282
+ }
283
+ }
284
+
285
+ _select(_utils[(key < 39 ? 'previous' : 'next') + 'EnabledItem'](_this.items, selected));
286
+ }
287
+ })
288
+ .on('focusin' + bindSufix, function(e) {
289
+ // Stupid, but necessary... Prevent the flicker when
290
+ // focusing out and back again in the browser window
291
+ $input.one('blur', function() {
292
+ $input.blur();
293
+ });
294
+
295
+ isOpen || _open(e);
296
+ })
297
+ .on('oninput' in $input[0] ? 'input' : 'keyup', function() {
298
+ if ( $input.val().length ) {
299
+ // Search in select options
300
+ $.each(_this.items, function(i, elm) {
301
+ if ( RegExp('^' + $input.val(), 'i').test(elm.slug) && !elm.disabled ) {
302
+ _select(i);
303
+ return false;
304
+ }
305
+ });
306
+ }
307
+ });
308
+
309
+ $original.prop('tabindex', false);
310
+
311
+ // Remove styles from items box
312
+ // Fix incorrect height when refreshed is triggered with fewer options
313
+ $li = $('li', $items.removeAttr('style')).on({
314
+ // Prevent <input> blur on Chrome
315
+ mousedown: function(e) {
316
+ e.preventDefault();
317
+ e.stopPropagation();
318
+ },
319
+ click: function() {
320
+ // The second parameter is to close the box after click
321
+ _select($(this).data('index'), true);
322
+
323
+ // Chrome doesn't close options box if select is wrapped with a label
324
+ // We need to 'return false' to avoid that
325
+ return false;
326
+ }
327
+ }).filter('[data-index]');
328
+ } else {
329
+ $outerWrapper.addClass(_this.classes.disabled);
330
+ $input.prop('disabled', true);
331
+ }
332
+
333
+ _utils.triggerCallback('Init', _this);
334
+ }
335
+
336
+ function _refresh() {
337
+ _utils.triggerCallback('Refresh', _this);
338
+ _populate();
339
+ }
340
+
341
+ // Behavior when system keys is pressed
342
+ function _handleSystemKeys(e) {
343
+ var key = e.keyCode || e.which;
344
+
345
+ if ( key == 13 ) {
346
+ e.preventDefault();
347
+ }
348
+
349
+ // Tab / Enter / ESC
350
+ if ( /^(9|13|27)$/.test(key) ) {
351
+ e.stopPropagation();
352
+ _select(selected, true);
353
+ }
354
+ }
355
+
356
+ // Set options box width/height
357
+ function _calculateOptionsDimensions() {
358
+ // Calculate options box height
359
+ // Set a temporary class on the hidden parent of the element
360
+ var hiddenChildren = $items.closest(':visible').children(':hidden').addClass(_this.classes.tempshow),
361
+ maxHeight = _this.options.maxHeight,
362
+ itemsWidth = $items.outerWidth(),
363
+ wrapperWidth = $wrapper.outerWidth() - (itemsWidth - $items.width());
364
+
365
+ // Set the dimensions, minimum is wrapper width, expand for long items if option is true
366
+ if ( !_this.options.expandToItemText || wrapperWidth > itemsWidth )
367
+ finalWidth = wrapperWidth;
368
+ else {
369
+ // Make sure the scrollbar width is included
370
+ $items.css('overflow', 'scroll');
371
+
372
+ // Set a really long width for $outerWrapper
373
+ $outerWrapper.width(9e4);
374
+ finalWidth = $items.width();
375
+ // Set scroll bar to auto
376
+ $items.css('overflow', '');
377
+ $outerWrapper.width('');
378
+ }
379
+
380
+ $items.width(finalWidth).height() > maxHeight && $items.height(maxHeight);
381
+
382
+ // Remove the temporary class
383
+ hiddenChildren.removeClass(_this.classes.tempshow);
384
+ }
385
+
386
+ // Open the select options box
387
+ function _open(e) {
388
+ _utils.triggerCallback('BeforeOpen', _this);
389
+
390
+ if ( e ) {
391
+ e.preventDefault();
392
+ e.stopPropagation();
393
+ }
394
+
395
+ if ( isEnabled ) {
396
+ _calculateOptionsDimensions();
397
+
398
+ // Find any other opened instances of select and close it
399
+ $('.' + _this.classes.hideselect, '.' + _this.classes.open).children()[pluginName]('close');
400
+
401
+ isOpen = true;
402
+ itemsHeight = $items.outerHeight();
403
+ itemsInnerHeight = $items.height();
404
+
405
+ // Toggle options box visibility
406
+ $outerWrapper.addClass(_this.classes.open);
407
+
408
+ // Give dummy input focus
409
+ $input.val('').is(':focus') || $input.focus();
410
+
411
+ $doc.on('click' + bindSufix, _close).on('scroll' + bindSufix, _isInViewport);
412
+ _isInViewport();
413
+
414
+ // Prevent window scroll when using mouse wheel inside items box
415
+ if ( _this.options.preventWindowScroll ) {
416
+ $doc.on('mousewheel' + bindSufix + ' DOMMouseScroll' + bindSufix, '.' + _this.classes.scroll, function(e) {
417
+ var orgEvent = e.originalEvent,
418
+ scrollTop = $(this).scrollTop(),
419
+ deltaY = 0;
420
+
421
+ if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
422
+ if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
423
+ if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
424
+ if ( 'deltaY' in orgEvent ) { deltaY = orgEvent.deltaY * -1; }
425
+
426
+ if ( scrollTop == (this.scrollHeight - itemsInnerHeight) && deltaY < 0 || scrollTop == 0 && deltaY > 0 ) {
427
+ e.preventDefault();
428
+ }
429
+ });
430
+ }
431
+
432
+ _detectItemVisibility(selected);
433
+
434
+ _utils.triggerCallback('Open', _this);
435
+ }
436
+ }
437
+
438
+ // Detect is the options box is inside the window
439
+ function _isInViewport() {
440
+ $outerWrapper.toggleClass(_this.classes.above, $outerWrapper.offset().top + $outerWrapper.outerHeight() + itemsHeight > $win.scrollTop() + $win.height());
441
+ }
442
+
443
+ // Close the select options box
444
+ function _close() {
445
+ _utils.triggerCallback('BeforeClose', _this);
446
+
447
+ if ( currValue != selected ) {
448
+ _utils.triggerCallback('BeforeChange', _this);
449
+
450
+ var text = _this.items[selected].text;
451
+
452
+ // Apply changed value to original select
453
+ $original
454
+ .prop('selectedIndex', currValue = selected)
455
+ .data('value', text);
456
+
457
+ // Change label text
458
+ $label.html(
459
+ $.isFunction(labelBuilder) ? labelBuilder(_this.items[selected]) : _utils.format(labelBuilder, _this.items[selected])
460
+ )
461
+
462
+ _utils.triggerCallback('Change', _this);
463
+ }
464
+
465
+ // Remove custom events on document
466
+ $doc.off(bindSufix);
467
+
468
+ // Remove visible class to hide options box
469
+ $outerWrapper.removeClass(_this.classes.open);
470
+
471
+ isOpen = false;
472
+
473
+ _utils.triggerCallback('Close', _this);
474
+ }
475
+
476
+ // Select option
477
+ function _select(index, close) {
478
+ // Parameter index is required
479
+ if ( index == undefined ) {
480
+ return;
481
+ }
482
+
483
+ // If element is disabled, can't select it
484
+ if ( !_this.items[index].disabled ) {
485
+ // If 'close' is false (default), the options box won't close after
486
+ // each selected item, this is necessary for keyboard navigation
487
+ $li
488
+ .removeClass('selected')
489
+ .eq(selected = index)
490
+ .addClass('selected');
491
+
492
+ _detectItemVisibility(index);
493
+ close && _close();
494
+ }
495
+ }
496
+
497
+ // Detect if currently selected option is visible and scroll the options box to show it
498
+ function _detectItemVisibility(index) {
499
+ var liHeight = $li.eq(index).outerHeight(),
500
+ liTop = $li[index].offsetTop,
501
+ itemsScrollTop = $itemsScroll.scrollTop(),
502
+ scrollT = liTop + liHeight * 2;
503
+
504
+ $itemsScroll.scrollTop(
505
+ scrollT > itemsScrollTop + itemsHeight ? scrollT - itemsHeight :
506
+ liTop - liHeight < itemsScrollTop ? liTop - liHeight :
507
+ itemsScrollTop
508
+ );
509
+ }
510
+
511
+ // Unbind and remove
512
+ function _destroy(preserveData) {
513
+ if ( isEnabled ) {
514
+ $items.add($wrapper).add($input).remove();
515
+ !preserveData && $original.removeData(pluginName).removeData('value');
516
+ $original.prop('tabindex', tabindex).off(bindSufix).off(eventTriggers).unwrap().unwrap();
517
+ isEnabled = false;
518
+ }
519
+ }
520
+
521
+ _init(opts);
522
+ };
523
+
524
+ // A really lightweight plugin wrapper around the constructor,
525
+ // preventing against multiple instantiations
526
+ $.fn[pluginName] = function(args) {
527
+ return this.each(function() {
528
+ var data = $.data(this, pluginName);
529
+
530
+ if ( data && !data.disableOnMobile )
531
+ (''+args === args && data[args]) ? data[args]() : data.init(args);
532
+ else
533
+ $.data(this, pluginName, new Selectric(this, args));
534
+ });
535
+ };
536
+
537
+ $.fn[pluginName].hooks = hooks;
538
+ }(jQuery));
@@ -0,0 +1,191 @@
1
+ /*======================================
2
+ Selectric v1.9.3
3
+ ======================================*/
4
+ .selectric-wrapper {
5
+ position: relative;
6
+ cursor: pointer;
7
+ }
8
+
9
+ .selectric-responsive {
10
+ width: 100%;
11
+ }
12
+
13
+ .selectric {
14
+ border: 1px solid #DDD;
15
+ background: #F8F8F8;
16
+ position: relative;
17
+ }
18
+ .selectric .label {
19
+ display: block;
20
+ white-space: nowrap;
21
+ overflow: hidden;
22
+ text-overflow: ellipsis;
23
+ margin: 0 38px 0 10px;
24
+ font-size: 12px;
25
+ line-height: 38px;
26
+ color: #444;
27
+ height: 38px;
28
+ }
29
+ .selectric .button {
30
+ display: block;
31
+ position: absolute;
32
+ right: 0;
33
+ top: 0;
34
+ width: 38px;
35
+ height: 38px;
36
+ color: #BBB;
37
+ text-align: center;
38
+ font: 0/0 a;
39
+ *font: 20px/38px Lucida Sans Unicode, Arial Unicode MS, Arial;
40
+ }
41
+ .selectric .button:after {
42
+ content: " ";
43
+ position: absolute;
44
+ top: 0;
45
+ right: 0;
46
+ bottom: 0;
47
+ left: 0;
48
+ margin: auto;
49
+ width: 0;
50
+ height: 0;
51
+ border: 4px solid transparent;
52
+ border-top-color: #BBB;
53
+ border-bottom: none;
54
+ }
55
+
56
+ .selectric-hover .selectric {
57
+ border-color: #C4C4C4;
58
+ }
59
+ .selectric-hover .selectric .button {
60
+ color: #A2A2A2;
61
+ }
62
+ .selectric-hover .selectric .button:after {
63
+ border-top-color: #A2A2A2;
64
+ }
65
+
66
+ .selectric-open {
67
+ z-index: 9999;
68
+ }
69
+ .selectric-open .selectric {
70
+ border-color: #C4C4C4;
71
+ }
72
+ .selectric-open .selectric-items {
73
+ display: block;
74
+ }
75
+
76
+ .selectric-disabled {
77
+ filter: alpha(opacity=50);
78
+ opacity: 0.5;
79
+ cursor: default;
80
+ -webkit-user-select: none;
81
+ -moz-user-select: none;
82
+ -ms-user-select: none;
83
+ user-select: none;
84
+ }
85
+
86
+ .selectric-hide-select {
87
+ position: relative;
88
+ overflow: hidden;
89
+ width: 0;
90
+ height: 0;
91
+ }
92
+ .selectric-hide-select select {
93
+ position: absolute;
94
+ left: -100%;
95
+ display: none;
96
+ }
97
+
98
+ .selectric-input {
99
+ position: absolute !important;
100
+ top: 0 !important;
101
+ left: 0 !important;
102
+ overflow: hidden !important;
103
+ clip: rect(0, 0, 0, 0) !important;
104
+ margin: 0 !important;
105
+ padding: 0 !important;
106
+ width: 1px !important;
107
+ height: 1px !important;
108
+ outline: none !important;
109
+ border: none !important;
110
+ *font: 0/0 a !important;
111
+ background: none !important;
112
+ }
113
+
114
+ .selectric-temp-show {
115
+ position: absolute !important;
116
+ visibility: hidden !important;
117
+ display: block !important;
118
+ }
119
+
120
+ /* Items box */
121
+ .selectric-items {
122
+ display: none;
123
+ position: absolute;
124
+ top: 100%;
125
+ left: 0;
126
+ background: #F8F8F8;
127
+ border: 1px solid #C4C4C4;
128
+ z-index: -1;
129
+ box-shadow: 0 0 10px -6px;
130
+ }
131
+ .selectric-items .selectric-scroll {
132
+ height: 100%;
133
+ overflow: auto;
134
+ }
135
+ .selectric-above .selectric-items {
136
+ top: auto;
137
+ bottom: 100%;
138
+ }
139
+ .selectric-items ul, .selectric-items li {
140
+ list-style: none;
141
+ padding: 0;
142
+ margin: 0;
143
+ font-size: 12px;
144
+ line-height: 20px;
145
+ min-height: 20px;
146
+ }
147
+ .selectric-items li {
148
+ display: block;
149
+ padding: 8px;
150
+ border-top: 1px solid #FFF;
151
+ border-bottom: 1px solid #EEE;
152
+ color: #666;
153
+ cursor: pointer;
154
+ }
155
+ .selectric-items li.selected {
156
+ background: #EFEFEF;
157
+ color: #444;
158
+ }
159
+ .selectric-items li:hover {
160
+ background: #F0F0F0;
161
+ color: #444;
162
+ }
163
+ .selectric-items .disabled {
164
+ filter: alpha(opacity=50);
165
+ opacity: 0.5;
166
+ cursor: default !important;
167
+ background: none !important;
168
+ color: #666 !important;
169
+ -webkit-user-select: none;
170
+ -moz-user-select: none;
171
+ -ms-user-select: none;
172
+ user-select: none;
173
+ }
174
+ .selectric-items .selectric-group .selectric-group-label {
175
+ font-weight: bold;
176
+ padding-left: 10px;
177
+ cursor: default;
178
+ -webkit-user-select: none;
179
+ -moz-user-select: none;
180
+ -ms-user-select: none;
181
+ user-select: none;
182
+ background: none;
183
+ color: #444;
184
+ }
185
+ .selectric-items .selectric-group.disabled li {
186
+ filter: alpha(opacity=100);
187
+ opacity: 1;
188
+ }
189
+ .selectric-items .selectric-group li {
190
+ padding-left: 25px;
191
+ }
@@ -0,0 +1,208 @@
1
+ $main-color: #DDD;
2
+ $secondary-color: #BBB;
3
+ $bg-color: #F8F8F8;
4
+ $text-color: #444;
5
+ $height: 40px;
6
+ $spacing: 10px;
7
+ $border-width: 1px;
8
+ $inner-height: $height - ($border-width * 2);
9
+
10
+ .selectric-wrapper {
11
+ position: relative;
12
+ cursor: pointer;
13
+ }
14
+
15
+ .selectric-responsive {
16
+ width: 100%;
17
+ }
18
+
19
+ .selectric {
20
+ border: $border-width solid $main-color;
21
+ background: $bg-color;
22
+ position: relative;
23
+
24
+ .label {
25
+ display: block;
26
+ white-space: nowrap;
27
+ overflow: hidden;
28
+ text-overflow: ellipsis;
29
+ margin: 0 $inner-height 0 $spacing;
30
+ font-size: 12px;
31
+ line-height: $inner-height;
32
+ color: $text-color;
33
+ height: $inner-height;
34
+ }
35
+
36
+ .button {
37
+ display: block;
38
+ position: absolute;
39
+ right: 0;
40
+ top: 0;
41
+ width: $inner-height;
42
+ height: $inner-height;
43
+ color: $secondary-color;
44
+ text-align: center;
45
+ font: 0/0 a;
46
+ *font: 20px/#{$inner-height} Lucida Sans Unicode, Arial Unicode MS, Arial;
47
+
48
+ &:after {
49
+ content: " ";
50
+ position: absolute;
51
+ top: 0;
52
+ right: 0;
53
+ bottom: 0;
54
+ left: 0;
55
+ margin: auto;
56
+ width: 0;
57
+ height: 0;
58
+ border: 4px solid transparent;
59
+ border-top-color: $secondary-color;
60
+ border-bottom: none;
61
+ }
62
+ }
63
+ }
64
+
65
+ .selectric-hover .selectric {
66
+ border-color: darken($main-color, 10%);
67
+
68
+ .button {
69
+ color: darken($secondary-color, 10%);
70
+
71
+ &:after {
72
+ border-top-color: darken($secondary-color, 10%);
73
+ }
74
+ }
75
+ }
76
+
77
+ .selectric-open {
78
+ z-index: 9999;
79
+
80
+ .selectric {
81
+ border-color: darken($main-color, 10%);
82
+ }
83
+
84
+ .selectric-items {
85
+ display: block;
86
+ }
87
+ }
88
+
89
+ .selectric-disabled {
90
+ filter: alpha(opacity=50);
91
+ opacity: 0.5;
92
+ cursor: default;
93
+ user-select: none;
94
+ }
95
+
96
+ .selectric-hide-select {
97
+ position: relative;
98
+ overflow: hidden;
99
+ width: 0;
100
+ height: 0;
101
+
102
+ select {
103
+ position: absolute;
104
+ left: -100%;
105
+ display: none;
106
+ }
107
+ }
108
+
109
+ .selectric-input {
110
+ position: absolute !important;
111
+ top: 0 !important;
112
+ left: 0 !important;
113
+ overflow: hidden !important;
114
+ clip: rect(0, 0, 0, 0) !important;
115
+ margin: 0 !important;
116
+ padding: 0 !important;
117
+ width: 1px !important;
118
+ height: 1px !important;
119
+ outline: none !important;
120
+ border: none !important;
121
+ *font: 0/0 a !important;
122
+ background: none !important;
123
+ }
124
+
125
+ .selectric-temp-show {
126
+ position: absolute !important;
127
+ visibility: hidden !important;
128
+ display: block !important;
129
+ }
130
+
131
+ /* Items box */
132
+ .selectric-items {
133
+ display: none;
134
+ position: absolute;
135
+ top: 100%;
136
+ left: 0;
137
+ background: $bg-color;
138
+ border: 1px solid darken($main-color, 10%);
139
+ z-index: -1;
140
+ box-shadow: 0 0 10px -6px;
141
+
142
+ .selectric-scroll {
143
+ height: 100%;
144
+ overflow: auto;
145
+ }
146
+
147
+ .selectric-above & {
148
+ top: auto;
149
+ bottom: 100%;
150
+ }
151
+
152
+ ul, li {
153
+ list-style: none;
154
+ padding: 0;
155
+ margin: 0;
156
+ font-size: 12px;
157
+ line-height: 20px;
158
+ min-height: 20px;
159
+ }
160
+
161
+ li {
162
+ display: block;
163
+ padding: 8px;
164
+ border-top: 1px solid #FFF;
165
+ border-bottom: 1px solid #EEE;
166
+ color: #666;
167
+ cursor: pointer;
168
+
169
+ &.selected {
170
+ background: #EFEFEF;
171
+ color: #444;
172
+ }
173
+
174
+ &:hover {
175
+ background: #F0F0F0;
176
+ color: #444;
177
+ }
178
+ }
179
+
180
+ .disabled {
181
+ filter: alpha(opacity=50);
182
+ opacity: 0.5;
183
+ cursor: default !important;
184
+ background: none !important;
185
+ color: #666 !important;
186
+ user-select: none;
187
+ }
188
+
189
+ .selectric-group {
190
+ .selectric-group-label {
191
+ font-weight: bold;
192
+ padding-left: 10px;
193
+ cursor: default;
194
+ user-select: none;
195
+ background: none;
196
+ color: #444;
197
+ }
198
+
199
+ &.disabled li {
200
+ filter: alpha(opacity=100);
201
+ opacity: 1;
202
+ }
203
+
204
+ li {
205
+ padding-left: 25px;
206
+ }
207
+ }
208
+ }
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jquery-selectric-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.9.3
5
+ platform: ruby
6
+ authors:
7
+ - Michael Johann
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ - - ">"
21
+ - !ruby/object:Gem::Version
22
+ version: '1.10'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.10'
30
+ - - ">"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.10'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '10.4'
40
+ - - ">"
41
+ - !ruby/object:Gem::Version
42
+ version: '10.4'
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '10.4'
50
+ - - ">"
51
+ - !ruby/object:Gem::Version
52
+ version: '10.4'
53
+ - !ruby/object:Gem::Dependency
54
+ name: railties
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '3.2'
60
+ - - ">"
61
+ - !ruby/object:Gem::Version
62
+ version: '3.2'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '3.2'
70
+ - - ">"
71
+ - !ruby/object:Gem::Version
72
+ version: '3.2'
73
+ description: This gem contains the jquery selectric plugin for Rails applications
74
+ email:
75
+ - mjohann@rails-experts.com
76
+ executables: []
77
+ extensions: []
78
+ extra_rdoc_files: []
79
+ files:
80
+ - README.md
81
+ - lib/jquery/selectric/rails.rb
82
+ - lib/jquery/selectric/rails/version.rb
83
+ - vendor/assets/javascripts/jquery.selectric.js
84
+ - vendor/assets/javascripts/lib/jquery.selectric.js
85
+ - vendor/assets/stylesheets/jquery.selectric.css
86
+ - vendor/assets/stylesheets/jquery.selectric.css.scss
87
+ homepage: https://github.com/malagant/jquery-selectric-rails
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.4.5
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: jQuery Selectric integrated into the asset pipeline
111
+ test_files: []