multiselect-rails 0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 49aba8a6921291de9400fbcb7a0a15e09576fbab
4
+ data.tar.gz: 6286f4e2aa1c3fa6a88a865bdc323f4e239d9b88
5
+ SHA512:
6
+ metadata.gz: f1e207f4dfe7d9e987593642c3c6980e58062abc27ae0a45d81bbcb42f0d35f24ef17cfaf172e72901d90c9271f38993ee01c433a9dcfc04f79503fe4478f6f0
7
+ data.tar.gz: 29ba5196a4f43ca3ecf2d3a2e640f43483cd8c7b72d481f3462932fbfe62e67fa2a604a5d6d800e2c7ac0c96295ecefbe973b55a9b68e32cd6bb0fe914ae9edd
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in multiselect-rails.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 esshka
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ # Multiselect::Rails
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'multiselect-rails'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install multiselect-rails
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/multiselect-rails/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,8 @@
1
+ require "multiselect/rails/version"
2
+
3
+ module Multiselect
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module Multiselect
2
+ module Rails
3
+ VERSION = "0.6"
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'multiselect/rails/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "multiselect-rails"
8
+ spec.version = Multiselect::Rails::VERSION
9
+ spec.authors = ["esshka"]
10
+ spec.email = ["esshka@gmail.com"]
11
+ spec.summary = "Multiselect rails plugin"
12
+ spec.description = "Multiselect rails plugin"
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ end
@@ -0,0 +1,532 @@
1
+ /*
2
+ * MultiSelect v0.9.11
3
+ * Copyright (c) 2012 Louis Cuny
4
+ *
5
+ * This program is free software. It comes without any warranty, to
6
+ * the extent permitted by applicable law. You can redistribute it
7
+ * and/or modify it under the terms of the Do What The Fuck You Want
8
+ * To Public License, Version 2, as published by Sam Hocevar. See
9
+ * http://sam.zoy.org/wtfpl/COPYING for more details.
10
+ */
11
+
12
+ !function ($) {
13
+
14
+ "use strict";
15
+
16
+
17
+ /* MULTISELECT CLASS DEFINITION
18
+ * ====================== */
19
+
20
+ var MultiSelect = function (element, options) {
21
+ this.options = options;
22
+ this.$element = $(element);
23
+ this.$container = $('<div/>', { 'class': "ms-container" });
24
+ this.$selectableContainer = $('<div/>', { 'class': 'ms-selectable' });
25
+ this.$selectionContainer = $('<div/>', { 'class': 'ms-selection' });
26
+ this.$selectableUl = $('<ul/>', { 'class': "ms-list", 'tabindex' : '-1' });
27
+ this.$selectionUl = $('<ul/>', { 'class': "ms-list", 'tabindex' : '-1' });
28
+ this.scrollTo = 0;
29
+ this.elemsSelector = 'li:visible:not(.ms-optgroup-label,.ms-optgroup-container,.'+options.disabledClass+')';
30
+ };
31
+
32
+ MultiSelect.prototype = {
33
+ constructor: MultiSelect,
34
+
35
+ init: function(){
36
+ var that = this,
37
+ ms = this.$element;
38
+
39
+ if (ms.next('.ms-container').length === 0){
40
+ ms.css({ position: 'absolute', left: '-9999px' });
41
+ ms.attr('id', ms.attr('id') ? ms.attr('id') : Math.ceil(Math.random()*1000)+'multiselect');
42
+ this.$container.attr('id', 'ms-'+ms.attr('id'));
43
+ this.$container.addClass(that.options.cssClass);
44
+ ms.find('option').each(function(){
45
+ that.generateLisFromOption(this);
46
+ });
47
+
48
+ this.$selectionUl.find('.ms-optgroup-label').hide();
49
+
50
+ if (that.options.selectableHeader){
51
+ that.$selectableContainer.append(that.options.selectableHeader);
52
+ }
53
+ that.$selectableContainer.append(that.$selectableUl);
54
+ if (that.options.selectableFooter){
55
+ that.$selectableContainer.append(that.options.selectableFooter);
56
+ }
57
+
58
+ if (that.options.selectionHeader){
59
+ that.$selectionContainer.append(that.options.selectionHeader);
60
+ }
61
+ that.$selectionContainer.append(that.$selectionUl);
62
+ if (that.options.selectionFooter){
63
+ that.$selectionContainer.append(that.options.selectionFooter);
64
+ }
65
+
66
+ that.$container.append(that.$selectableContainer);
67
+ that.$container.append(that.$selectionContainer);
68
+ ms.after(that.$container);
69
+
70
+ that.activeMouse(that.$selectableUl);
71
+ that.activeKeyboard(that.$selectableUl);
72
+
73
+ var action = that.options.dblClick ? 'dblclick' : 'click';
74
+
75
+ that.$selectableUl.on(action, '.ms-elem-selectable', function(){
76
+ that.select($(this).data('ms-value'));
77
+ });
78
+ that.$selectionUl.on(action, '.ms-elem-selection', function(){
79
+ that.deselect($(this).data('ms-value'));
80
+ });
81
+
82
+ that.activeMouse(that.$selectionUl);
83
+ that.activeKeyboard(that.$selectionUl);
84
+
85
+ ms.on('focus', function(){
86
+ that.$selectableUl.focus();
87
+ })
88
+ }
89
+
90
+ var selectedValues = ms.find('option:selected').map(function(){ return $(this).val(); }).get();
91
+ that.select(selectedValues, 'init');
92
+
93
+ if (typeof that.options.afterInit === 'function') {
94
+ that.options.afterInit.call(this, this.$container);
95
+ }
96
+ },
97
+
98
+ 'generateLisFromOption' : function(option, index, $container){
99
+ var that = this,
100
+ ms = that.$element,
101
+ attributes = "",
102
+ $option = $(option);
103
+
104
+ for (var cpt = 0; cpt < option.attributes.length; cpt++){
105
+ var attr = option.attributes[cpt];
106
+
107
+ if(attr.name !== 'value' && attr.name !== 'disabled'){
108
+ attributes += attr.name+'="'+attr.value+'" ';
109
+ }
110
+ }
111
+ var selectableLi = $('<li '+attributes+'><span>'+that.escapeHTML($option.text())+'</span></li>'),
112
+ selectedLi = selectableLi.clone(),
113
+ value = $option.val(),
114
+ elementId = that.sanitize(value);
115
+
116
+ selectableLi
117
+ .data('ms-value', value)
118
+ .addClass('ms-elem-selectable')
119
+ .attr('id', elementId+'-selectable');
120
+
121
+ selectedLi
122
+ .data('ms-value', value)
123
+ .addClass('ms-elem-selection')
124
+ .attr('id', elementId+'-selection')
125
+ .hide();
126
+
127
+ if ($option.prop('disabled') || ms.prop('disabled')){
128
+ selectedLi.addClass(that.options.disabledClass);
129
+ selectableLi.addClass(that.options.disabledClass);
130
+ }
131
+
132
+ var $optgroup = $option.parent('optgroup');
133
+
134
+ if ($optgroup.length > 0){
135
+ var optgroupLabel = $optgroup.attr('label'),
136
+ optgroupId = that.sanitize(optgroupLabel),
137
+ $selectableOptgroup = that.$selectableUl.find('#optgroup-selectable-'+optgroupId),
138
+ $selectionOptgroup = that.$selectionUl.find('#optgroup-selection-'+optgroupId);
139
+
140
+ if ($selectableOptgroup.length === 0){
141
+ var optgroupContainerTpl = '<li class="ms-optgroup-container"></li>',
142
+ optgroupTpl = '<ul class="ms-optgroup"><li class="ms-optgroup-label"><span>'+optgroupLabel+'</span></li></ul>';
143
+
144
+ $selectableOptgroup = $(optgroupContainerTpl);
145
+ $selectionOptgroup = $(optgroupContainerTpl);
146
+ $selectableOptgroup.attr('id', 'optgroup-selectable-'+optgroupId);
147
+ $selectionOptgroup.attr('id', 'optgroup-selection-'+optgroupId);
148
+ $selectableOptgroup.append($(optgroupTpl));
149
+ $selectionOptgroup.append($(optgroupTpl));
150
+ if (that.options.selectableOptgroup){
151
+ $selectableOptgroup.find('.ms-optgroup-label').on('click', function(){
152
+ var values = $optgroup.children(':not(:selected, :disabled)').map(function(){ return $(this).val() }).get();
153
+ that.select(values);
154
+ });
155
+ $selectionOptgroup.find('.ms-optgroup-label').on('click', function(){
156
+ var values = $optgroup.children(':selected:not(:disabled)').map(function(){ return $(this).val() }).get();
157
+ that.deselect(values);
158
+ });
159
+ }
160
+ that.$selectableUl.append($selectableOptgroup);
161
+ that.$selectionUl.append($selectionOptgroup);
162
+ }
163
+ index = index == undefined ? $selectableOptgroup.find('ul').children().length : index + 1;
164
+ selectableLi.insertAt(index, $selectableOptgroup.children());
165
+ selectedLi.insertAt(index, $selectionOptgroup.children());
166
+ } else {
167
+ index = index == undefined ? that.$selectableUl.children().length : index;
168
+
169
+ selectableLi.insertAt(index, that.$selectableUl);
170
+ selectedLi.insertAt(index, that.$selectionUl);
171
+ }
172
+ },
173
+
174
+ 'addOption' : function(options){
175
+ var that = this;
176
+
177
+ if (options.value) options = [options];
178
+ $.each(options, function(index, option){
179
+ if (option.value && that.$element.find("option[value='"+option.value+"']").length === 0){
180
+ var $option = $('<option value="'+option.value+'">'+option.text+'</option>'),
181
+ index = parseInt((typeof option.index === 'undefined' ? that.$element.children().length : option.index)),
182
+ $container = option.nested == undefined ? that.$element : $("optgroup[label='"+option.nested+"']")
183
+
184
+ $option.insertAt(index, $container);
185
+ that.generateLisFromOption($option.get(0), index, option.nested);
186
+ }
187
+ })
188
+ },
189
+
190
+ 'escapeHTML' : function(text){
191
+ return $("<div>").text(text).html();
192
+ },
193
+
194
+ 'activeKeyboard' : function($list){
195
+ var that = this;
196
+
197
+ $list.on('focus', function(){
198
+ $(this).addClass('ms-focus');
199
+ })
200
+ .on('blur', function(){
201
+ $(this).removeClass('ms-focus');
202
+ })
203
+ .on('keydown', function(e){
204
+ switch (e.which) {
205
+ case 40:
206
+ case 38:
207
+ e.preventDefault();
208
+ e.stopPropagation();
209
+ that.moveHighlight($(this), (e.which === 38) ? -1 : 1);
210
+ return;
211
+ case 37:
212
+ case 39:
213
+ e.preventDefault();
214
+ e.stopPropagation();
215
+ that.switchList($list);
216
+ return;
217
+ case 9:
218
+ if(that.$element.is('[tabindex]')){
219
+ e.preventDefault();
220
+ var tabindex = parseInt(that.$element.attr('tabindex'), 10);
221
+ tabindex = (e.shiftKey) ? tabindex-1 : tabindex+1;
222
+ $('[tabindex="'+(tabindex)+'"]').focus();
223
+ return;
224
+ }else{
225
+ if(e.shiftKey){
226
+ that.$element.trigger('focus');
227
+ }
228
+ }
229
+ }
230
+ if($.inArray(e.which, that.options.keySelect) > -1){
231
+ e.preventDefault();
232
+ e.stopPropagation();
233
+ that.selectHighlighted($list);
234
+ return;
235
+ }
236
+ });
237
+ },
238
+
239
+ 'moveHighlight': function($list, direction){
240
+ var $elems = $list.find(this.elemsSelector),
241
+ $currElem = $elems.filter('.ms-hover'),
242
+ $nextElem = null,
243
+ elemHeight = $elems.first().outerHeight(),
244
+ containerHeight = $list.height(),
245
+ containerSelector = '#'+this.$container.prop('id');
246
+
247
+ $elems.removeClass('ms-hover');
248
+ if (direction === 1){ // DOWN
249
+
250
+ $nextElem = $currElem.nextAll(this.elemsSelector).first();
251
+ if ($nextElem.length === 0){
252
+ var $optgroupUl = $currElem.parent();
253
+
254
+ if ($optgroupUl.hasClass('ms-optgroup')){
255
+ var $optgroupLi = $optgroupUl.parent(),
256
+ $nextOptgroupLi = $optgroupLi.next(':visible');
257
+
258
+ if ($nextOptgroupLi.length > 0){
259
+ $nextElem = $nextOptgroupLi.find(this.elemsSelector).first();
260
+ } else {
261
+ $nextElem = $elems.first();
262
+ }
263
+ } else {
264
+ $nextElem = $elems.first();
265
+ }
266
+ }
267
+ } else if (direction === -1){ // UP
268
+
269
+ $nextElem = $currElem.prevAll(this.elemsSelector).first();
270
+ if ($nextElem.length === 0){
271
+ var $optgroupUl = $currElem.parent();
272
+
273
+ if ($optgroupUl.hasClass('ms-optgroup')){
274
+ var $optgroupLi = $optgroupUl.parent(),
275
+ $prevOptgroupLi = $optgroupLi.prev(':visible');
276
+
277
+ if ($prevOptgroupLi.length > 0){
278
+ $nextElem = $prevOptgroupLi.find(this.elemsSelector).last();
279
+ } else {
280
+ $nextElem = $elems.last();
281
+ }
282
+ } else {
283
+ $nextElem = $elems.last();
284
+ }
285
+ }
286
+ }
287
+ if ($nextElem.length > 0){
288
+ $nextElem.addClass('ms-hover');
289
+ var scrollTo = $list.scrollTop() + $nextElem.position().top -
290
+ containerHeight / 2 + elemHeight / 2;
291
+
292
+ $list.scrollTop(scrollTo);
293
+ }
294
+ },
295
+
296
+ 'selectHighlighted' : function($list){
297
+ var $elems = $list.find(this.elemsSelector),
298
+ $highlightedElem = $elems.filter('.ms-hover').first();
299
+
300
+ if ($highlightedElem.length > 0){
301
+ if ($list.parent().hasClass('ms-selectable')){
302
+ this.select($highlightedElem.data('ms-value'));
303
+ } else {
304
+ this.deselect($highlightedElem.data('ms-value'));
305
+ }
306
+ $elems.removeClass('ms-hover');
307
+ }
308
+ },
309
+
310
+ 'switchList' : function($list){
311
+ $list.blur();
312
+ this.$container.find(this.elemsSelector).removeClass('ms-hover');
313
+ if ($list.parent().hasClass('ms-selectable')){
314
+ this.$selectionUl.focus();
315
+ } else {
316
+ this.$selectableUl.focus();
317
+ }
318
+ },
319
+
320
+ 'activeMouse' : function($list){
321
+ var that = this;
322
+
323
+ $('body').on('mouseenter', that.elemsSelector, function(){
324
+ $(this).parents('.ms-container').find(that.elemsSelector).removeClass('ms-hover');
325
+ $(this).addClass('ms-hover');
326
+ });
327
+
328
+ $('body').on('mouseleave', that.elemsSelector, function () {
329
+ $(this).parents('.ms-container').find(that.elemsSelector).removeClass('ms-hover');;
330
+ });
331
+ },
332
+
333
+ 'refresh' : function() {
334
+ this.destroy();
335
+ this.$element.multiSelect(this.options);
336
+ },
337
+
338
+ 'destroy' : function(){
339
+ $("#ms-"+this.$element.attr("id")).remove();
340
+ this.$element.css('position', '').css('left', '')
341
+ this.$element.removeData('multiselect');
342
+ },
343
+
344
+ 'select' : function(value, method){
345
+ if (typeof value === 'string'){ value = [value]; }
346
+
347
+ var that = this,
348
+ ms = this.$element,
349
+ msIds = $.map(value, function(val){ return(that.sanitize(val)); }),
350
+ selectables = this.$selectableUl.find('#' + msIds.join('-selectable, #')+'-selectable').filter(':not(.'+that.options.disabledClass+')'),
351
+ selections = this.$selectionUl.find('#' + msIds.join('-selection, #') + '-selection').filter(':not(.'+that.options.disabledClass+')'),
352
+ options = ms.find('option:not(:disabled)').filter(function(){ return($.inArray(this.value, value) > -1); });
353
+
354
+ if (method === 'init'){
355
+ selectables = this.$selectableUl.find('#' + msIds.join('-selectable, #')+'-selectable'),
356
+ selections = this.$selectionUl.find('#' + msIds.join('-selection, #') + '-selection');
357
+ }
358
+
359
+ if (selectables.length > 0){
360
+ selectables.addClass('ms-selected').hide();
361
+ selections.addClass('ms-selected').show();
362
+
363
+ options.prop('selected', true);
364
+
365
+ that.$container.find(that.elemsSelector).removeClass('ms-hover');
366
+
367
+ var selectableOptgroups = that.$selectableUl.children('.ms-optgroup-container');
368
+ if (selectableOptgroups.length > 0){
369
+ selectableOptgroups.each(function(){
370
+ var selectablesLi = $(this).find('.ms-elem-selectable');
371
+ if (selectablesLi.length === selectablesLi.filter('.ms-selected').length){
372
+ $(this).find('.ms-optgroup-label').hide();
373
+ }
374
+ });
375
+
376
+ var selectionOptgroups = that.$selectionUl.children('.ms-optgroup-container');
377
+ selectionOptgroups.each(function(){
378
+ var selectionsLi = $(this).find('.ms-elem-selection');
379
+ if (selectionsLi.filter('.ms-selected').length > 0){
380
+ $(this).find('.ms-optgroup-label').show();
381
+ }
382
+ });
383
+ } else {
384
+ if (that.options.keepOrder && method !== 'init'){
385
+ var selectionLiLast = that.$selectionUl.find('.ms-selected');
386
+ if((selectionLiLast.length > 1) && (selectionLiLast.last().get(0) != selections.get(0))) {
387
+ selections.insertAfter(selectionLiLast.last());
388
+ }
389
+ }
390
+ }
391
+ if (method !== 'init'){
392
+ ms.trigger('change');
393
+ if (typeof that.options.afterSelect === 'function') {
394
+ that.options.afterSelect.call(this, value);
395
+ }
396
+ }
397
+ }
398
+ },
399
+
400
+ 'deselect' : function(value){
401
+ if (typeof value === 'string'){ value = [value]; }
402
+
403
+ var that = this,
404
+ ms = this.$element,
405
+ msIds = $.map(value, function(val){ return(that.sanitize(val)); }),
406
+ selectables = this.$selectableUl.find('#' + msIds.join('-selectable, #')+'-selectable'),
407
+ selections = this.$selectionUl.find('#' + msIds.join('-selection, #')+'-selection').filter('.ms-selected').filter(':not(.'+that.options.disabledClass+')'),
408
+ options = ms.find('option').filter(function(){ return($.inArray(this.value, value) > -1); });
409
+
410
+ if (selections.length > 0){
411
+ selectables.removeClass('ms-selected').show();
412
+ selections.removeClass('ms-selected').hide();
413
+ options.prop('selected', false);
414
+
415
+ that.$container.find(that.elemsSelector).removeClass('ms-hover');
416
+
417
+ var selectableOptgroups = that.$selectableUl.children('.ms-optgroup-container');
418
+ if (selectableOptgroups.length > 0){
419
+ selectableOptgroups.each(function(){
420
+ var selectablesLi = $(this).find('.ms-elem-selectable');
421
+ if (selectablesLi.filter(':not(.ms-selected)').length > 0){
422
+ $(this).find('.ms-optgroup-label').show();
423
+ }
424
+ });
425
+
426
+ var selectionOptgroups = that.$selectionUl.children('.ms-optgroup-container');
427
+ selectionOptgroups.each(function(){
428
+ var selectionsLi = $(this).find('.ms-elem-selection');
429
+ if (selectionsLi.filter('.ms-selected').length === 0){
430
+ $(this).find('.ms-optgroup-label').hide();
431
+ }
432
+ });
433
+ }
434
+ ms.trigger('change');
435
+ if (typeof that.options.afterDeselect === 'function') {
436
+ that.options.afterDeselect.call(this, value);
437
+ }
438
+ }
439
+ },
440
+
441
+ 'select_all' : function(){
442
+ var ms = this.$element,
443
+ values = ms.val();
444
+
445
+ ms.find('option:not(":disabled")').prop('selected', true);
446
+ this.$selectableUl.find('.ms-elem-selectable').filter(':not(.'+this.options.disabledClass+')').addClass('ms-selected').hide();
447
+ this.$selectionUl.find('.ms-optgroup-label').show();
448
+ this.$selectableUl.find('.ms-optgroup-label').hide();
449
+ this.$selectionUl.find('.ms-elem-selection').filter(':not(.'+this.options.disabledClass+')').addClass('ms-selected').show();
450
+ this.$selectionUl.focus();
451
+ ms.trigger('change');
452
+ if (typeof this.options.afterSelect === 'function') {
453
+ var selectedValues = $.grep(ms.val(), function(item){
454
+ return $.inArray(item, values) < 0;
455
+ });
456
+ this.options.afterSelect.call(this, selectedValues);
457
+ }
458
+ },
459
+
460
+ 'deselect_all' : function(){
461
+ var ms = this.$element,
462
+ values = ms.val();
463
+
464
+ ms.find('option').prop('selected', false);
465
+ this.$selectableUl.find('.ms-elem-selectable').removeClass('ms-selected').show();
466
+ this.$selectionUl.find('.ms-optgroup-label').hide();
467
+ this.$selectableUl.find('.ms-optgroup-label').show();
468
+ this.$selectionUl.find('.ms-elem-selection').removeClass('ms-selected').hide();
469
+ this.$selectableUl.focus();
470
+ ms.trigger('change');
471
+ if (typeof this.options.afterDeselect === 'function') {
472
+ this.options.afterDeselect.call(this, values);
473
+ }
474
+ },
475
+
476
+ sanitize: function(value){
477
+ var hash = 0, i, character;
478
+ if (value.length == 0) return hash;
479
+ var ls = 0;
480
+ for (i = 0, ls = value.length; i < ls; i++) {
481
+ character = value.charCodeAt(i);
482
+ hash = ((hash<<5)-hash)+character;
483
+ hash |= 0; // Convert to 32bit integer
484
+ }
485
+ return hash;
486
+ }
487
+ };
488
+
489
+ /* MULTISELECT PLUGIN DEFINITION
490
+ * ======================= */
491
+
492
+ $.fn.multiSelect = function () {
493
+ var option = arguments[0],
494
+ args = arguments;
495
+
496
+ return this.each(function () {
497
+ var $this = $(this),
498
+ data = $this.data('multiselect'),
499
+ options = $.extend({}, $.fn.multiSelect.defaults, $this.data(), typeof option === 'object' && option);
500
+
501
+ if (!data){ $this.data('multiselect', (data = new MultiSelect(this, options))); }
502
+
503
+ if (typeof option === 'string'){
504
+ data[option](args[1]);
505
+ } else {
506
+ data.init();
507
+ }
508
+ });
509
+ };
510
+
511
+ $.fn.multiSelect.defaults = {
512
+ keySelect: [32],
513
+ selectableOptgroup: false,
514
+ disabledClass : 'disabled',
515
+ dblClick : false,
516
+ keepOrder: false,
517
+ cssClass: ''
518
+ };
519
+
520
+ $.fn.multiSelect.Constructor = MultiSelect;
521
+
522
+ $.fn.insertAt = function(index, $parent) {
523
+ return this.each(function() {
524
+ if (index === 0) {
525
+ $parent.prepend(this);
526
+ } else {
527
+ $parent.children().eq(index - 1).after(this);
528
+ }
529
+ });
530
+ }
531
+
532
+ }(window.jQuery);
@@ -0,0 +1,93 @@
1
+ .ms-container{
2
+ background: transparent url('switch.png') no-repeat 50% 50%;
3
+ width: 370px;
4
+ }
5
+
6
+ .ms-container:after{
7
+ content: ".";
8
+ display: block;
9
+ height: 0;
10
+ line-height: 0;
11
+ font-size: 0;
12
+ clear: both;
13
+ min-height: 0;
14
+ visibility: hidden;
15
+ }
16
+
17
+ .ms-container .ms-selectable, .ms-container .ms-selection{
18
+ background: #fff;
19
+ color: #555555;
20
+ float: left;
21
+ width: 45%;
22
+ }
23
+ .ms-container .ms-selection{
24
+ float: right;
25
+ }
26
+
27
+ .ms-container .ms-list{
28
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
29
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
30
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
31
+ -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
32
+ -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
33
+ -ms-transition: border linear 0.2s, box-shadow linear 0.2s;
34
+ -o-transition: border linear 0.2s, box-shadow linear 0.2s;
35
+ transition: border linear 0.2s, box-shadow linear 0.2s;
36
+ border: 1px solid #ccc;
37
+ -webkit-border-radius: 3px;
38
+ -moz-border-radius: 3px;
39
+ border-radius: 3px;
40
+ position: relative;
41
+ height: 200px;
42
+ padding: 0;
43
+ overflow-y: auto;
44
+ }
45
+
46
+ .ms-container .ms-list.ms-focus{
47
+ border-color: rgba(82, 168, 236, 0.8);
48
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
49
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
50
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
51
+ outline: 0;
52
+ outline: thin dotted \9;
53
+ }
54
+
55
+ .ms-container ul{
56
+ margin: 0;
57
+ list-style-type: none;
58
+ padding: 0;
59
+ }
60
+
61
+ .ms-container .ms-optgroup-container{
62
+ width: 100%;
63
+ }
64
+
65
+ .ms-container .ms-optgroup-label{
66
+ margin: 0;
67
+ padding: 5px 0px 0px 5px;
68
+ cursor: pointer;
69
+ color: #999;
70
+ }
71
+
72
+ .ms-container .ms-selectable li.ms-elem-selectable,
73
+ .ms-container .ms-selection li.ms-elem-selection{
74
+ border-bottom: 1px #eee solid;
75
+ padding: 2px 10px;
76
+ color: #555;
77
+ font-size: 14px;
78
+ }
79
+
80
+ .ms-container .ms-selectable li.ms-hover,
81
+ .ms-container .ms-selection li.ms-hover{
82
+ cursor: pointer;
83
+ color: #fff;
84
+ text-decoration: none;
85
+ background-color: #08c;
86
+ }
87
+
88
+ .ms-container .ms-selectable li.disabled,
89
+ .ms-container .ms-selection li.disabled{
90
+ background-color: #eee;
91
+ color: #aaa;
92
+ cursor: text;
93
+ }
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: multiselect-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.6'
5
+ platform: ruby
6
+ authors:
7
+ - esshka
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-22 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.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Multiselect rails plugin
42
+ email:
43
+ - esshka@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - lib/multiselect/rails.rb
54
+ - lib/multiselect/rails/version.rb
55
+ - multiselect-rails.gemspec
56
+ - vendor/assets/images/switch.png
57
+ - vendor/assets/javascripts/jquery.multi-select.js
58
+ - vendor/assets/stylesheets/multi-select.css
59
+ homepage: ''
60
+ licenses:
61
+ - MIT
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 2.2.2
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: Multiselect rails plugin
83
+ test_files: []