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 +7 -0
- data/README.md +48 -0
- data/lib/jquery/selectric/rails.rb +11 -0
- data/lib/jquery/selectric/rails/version.rb +7 -0
- data/vendor/assets/javascripts/jquery.selectric.js +5 -0
- data/vendor/assets/javascripts/lib/jquery.selectric.js +538 -0
- data/vendor/assets/stylesheets/jquery.selectric.css +191 -0
- data/vendor/assets/stylesheets/jquery.selectric.css.scss +208 -0
- metadata +111 -0
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,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">▾</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: []
|