multi-select-rails 0.8.0.1 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ .DS_Store
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Multiselect for Rails asset pipeline
2
2
 
3
- [multi-select](https://github.com/lou/multi-select) is a tiny jQuery plugin to customize selects with the multiple attribute.
3
+ [multi-select](https://github.com/lou/multi-select) is a tiny jQuery plugin to customize selects with the multiple attribute.
4
4
 
5
5
  The `multi-select-rails` gem integrates `multi-select` with the Rails asset pipeline.
6
6
 
@@ -14,13 +14,13 @@ Include `multi-select-rails` in Gemfile
14
14
 
15
15
  Then run `bundle install`
16
16
 
17
- ### Include multiselect javascript assets
17
+ ### Include multiselect javascript
18
18
 
19
19
  Add to your `app/assets/javascripts/application.js`
20
20
 
21
21
  //= require multi-select
22
22
 
23
- ### Include multiselect stylesheet assets
23
+ ### Include multiselect stylesheet
24
24
 
25
25
  Add to your `app/assets/stylesheets/application.css`
26
26
 
@@ -1,5 +1,5 @@
1
1
  module MultiSelectRails
2
2
  module Rails
3
- VERSION = "0.8.0.1"
3
+ VERSION = "0.9.1"
4
4
  end
5
5
  end
File without changes
@@ -1,5 +1,5 @@
1
1
  /*
2
- * MultiSelect v0.8
2
+ * MultiSelect v0.9.1
3
3
  * Copyright (c) 2012 Louis Cuny
4
4
  *
5
5
  * This program is free software. It comes without any warranty, to
@@ -9,326 +9,390 @@
9
9
  * http://sam.zoy.org/wtfpl/COPYING for more details.
10
10
  */
11
11
 
12
- (function($){
13
- var msMethods = {
14
- 'init' : function(options){
15
- this.settings = {
16
- disabledClass : 'disabled',
17
- selectCallbackOnInit: false,
18
- keepOrder : false,
19
- dblClick : false
20
- };
21
- if(options) {
22
- this.settings = $.extend(this.settings, options);
23
- }
24
- var multiSelects = this;
25
- multiSelects.css('position', 'absolute').css('left', '-9999px');
26
- return multiSelects.each(function(){
27
- var ms = $(this);
28
-
29
- if (ms.next('.ms-container').length == 0){
30
- ms.attr('id', ms.attr('id') ? ms.attr('id') : 'ms-'+Math.ceil(Math.random()*1000));
31
- var container = $('<div id="ms-'+ms.attr('id')+'" class="ms-container"></div>'),
32
- selectableContainer = $('<div class="ms-selectable"></div>'),
33
- selectedContainer = $('<div class="ms-selection"></div>'),
34
- selectableUl = $('<ul class="ms-list"></ul>'),
35
- selectedUl = $('<ul class="ms-list"></ul>');
36
-
37
- ms.data('settings', multiSelects.settings);
38
-
39
- var optgroupLabel = null,
40
- optgroupId = null,
41
- optgroupCpt = 0,
42
- scroll = 0;
43
- ms.find('optgroup,option').each(function(){
44
- if ($(this).is('optgroup')){
45
- optgroupLabel = $(this).attr('label');
46
- optgroupId = 'ms-'+ms.attr('id')+'-optgroup-'+optgroupCpt;
47
- selectableUl.append($('<li class="ms-optgroup-container" id="'+
48
- optgroupId+'"><ul class="ms-optgroup"><li class="ms-optgroup-label">'+
49
- optgroupLabel+'</li></ul></li>'));
50
- optgroupCpt++;
51
- } else {
52
- var klass = $(this).attr('class') ? ' '+$(this).attr('class') : '';
53
- var selectableLi = $('<li class="ms-elem-selectable'+klass+'" ms-value="'+$(this).val()+'">'+$(this).text()+'</li>');
54
-
55
- if ($(this).attr('title'))
56
- selectableLi.attr('title', $(this).attr('title'));
57
- if ($(this).attr('disabled') || ms.attr('disabled')){
58
- selectableLi.attr('disabled', 'disabled');
59
- selectableLi.addClass(multiSelects.settings.disabledClass);
60
- }
61
- if(multiSelects.settings.dblClick) {
62
- selectableLi.dblclick(function(){
63
- ms.multiSelect('select', $(this).attr('ms-value'));
64
- });
65
- } else {
66
- selectableLi.click(function(){
67
- ms.multiSelect('select', $(this).attr('ms-value'));
68
- });
12
+ !function ($) {
13
+
14
+ "use strict"; // jshint ;_;
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 id="ms-'+this.$element.attr('id')+'" class="ms-container"></div>');
24
+ this.$selectableContainer = $('<div class="ms-selectable"></div>');
25
+ this.$selectionContainer = $('<div class="ms-selection"></div>');
26
+ this.$selectableUl = $('<ul class="ms-list"></ul>');
27
+ this.$selectionUl = $('<ul class="ms-list"></ul>');
28
+ this.scrollTo = 0;
29
+ }
30
+
31
+ MultiSelect.prototype = {
32
+ constructor: MultiSelect,
33
+
34
+ init: function(){
35
+ var that = this,
36
+ ms = this.$element;
37
+
38
+ if (ms.next('.ms-container').length == 0){
39
+ ms.css({ position: 'absolute', left: '-9999px' });
40
+ ms.attr('id', ms.attr('id') ? ms.attr('id') : 'ms-'+Math.ceil(Math.random()*1000));
41
+
42
+
43
+
44
+ var optgroupLabel = null,
45
+ optgroupId = null,
46
+ optgroupCpt = 0,
47
+ scroll = 0;
48
+
49
+
50
+ ms.find('optgroup, option').each(function(){
51
+ if ($(this).is('optgroup')){
52
+ optgroupLabel = $(this).attr('label');
53
+ optgroupId = 'ms-'+ms.attr('id')+'-optgroup-'+optgroupCpt;
54
+
55
+ that.$selectableUl.append(
56
+ '<li class="ms-optgroup-container" id="'+optgroupId+'-selectable">\
57
+ <ul class="ms-optgroup">\
58
+ <li class="ms-optgroup-label"><span>'+optgroupLabel+'</span></li>\
59
+ </ul>\
60
+ </li>');
61
+ that.$selectionUl.append(
62
+ '<li class="ms-optgroup-container" id="'+optgroupId+'-selection">\
63
+ <ul class="ms-optgroup">\
64
+ <li class="ms-optgroup-label"><span>'+optgroupLabel+'</span></li>\
65
+ </ul>\
66
+ </li>');
67
+ optgroupCpt++;
68
+ } else {
69
+
70
+ var attributes = "";
71
+
72
+ for (var cpt = 0; cpt < this.attributes.length; cpt++){
73
+ var attr = this.attributes[cpt];
74
+
75
+ if(that.isDomNode(attr.name)){
76
+ attributes += attr.name+'="'+attr.value+'" ';
69
77
  }
70
- var container = optgroupId ? selectableUl.children('#'+optgroupId).find('ul').first() : selectableUl;
71
- container.append(selectableLi);
72
78
  }
73
- });
74
- if (multiSelects.settings.selectableHeader){
75
- selectableContainer.append(multiSelects.settings.selectableHeader);
76
- }
77
- selectableContainer.append(selectableUl);
78
- if (multiSelects.settings.selectedHeader){
79
- selectedContainer.append(multiSelects.settings.selectedHeader);
80
- }
81
- selectedContainer.append(selectedUl);
82
- container.append(selectableContainer);
83
- container.append(selectedContainer);
84
- ms.after(container);
85
- ms.find('option:selected').each(function(){
86
- ms.multiSelect('select', $(this).val(), 'init');
87
- });
79
+ var selectableLi = $('<li '+attributes+'><span>'+$(this).text()+'</span></li>'),
80
+ selectedLi = selectableLi.clone();
88
81
 
89
- $('.ms-elem-selectable', selectableUl).on('mouseenter', function(){
90
- $('li', container).removeClass('ms-hover');
91
- $(this).addClass('ms-hover');
92
- }).on('mouseout', function(){
93
- $('li', container).removeClass('ms-hover');
94
- });
82
+ var value = $(this).val();
83
+ selectableLi.addClass('ms-elem-selectable').attr('id', value+'-selectable');
84
+ selectedLi.addClass('ms-elem-selection').attr('id', value+'-selection').hide();
95
85
 
86
+ that.$selectionUl.find('.ms-optgroup-label').hide();
96
87
 
88
+ if ($(this).prop('disabled') || ms.prop('disabled')){
89
+ selectableLi.prop('disabled', true);
90
+ selectableLi.addClass(that.options.disabledClass);
91
+ }
97
92
 
98
- selectableUl.on('focusin', function(){
99
- $(this).addClass('ms-focus');
100
- selectedUl.focusout();
101
- }).on('focusout', function(){
102
- $(this).removeClass('ms-focus');
103
- $('li', container).removeClass('ms-hover');
104
- });
93
+ if (optgroupId){
94
+ that.$selectableUl.children('#'+optgroupId+'-selectable').find('ul').first().append(selectableLi);
95
+ that.$selectionUl.children('#'+optgroupId+'-selection').find('ul').first().append(selectedLi);
96
+ } else {
97
+ that.$selectableUl.append(selectableLi);
98
+ that.$selectionUl.append(selectedLi);
99
+ }
100
+ }
101
+ });
105
102
 
106
- selectedUl.on('focusin', function(){
107
- $(this).addClass('ms-focus');
108
- }).on('focusout', function(){
109
- $(this).removeClass('ms-focus');
110
- $('li', container).removeClass('ms-hover');
111
- });
103
+ if (that.options.selectableHeader){
104
+ that.$selectableContainer.append(that.options.selectableHeader);
105
+ }
106
+ that.$selectableContainer.append(that.$selectableUl);
107
+
108
+ if (that.options.selectionHeader){
109
+ that.$selectionContainer.append(that.options.selectionHeader);
110
+ }
111
+ this.$selectionContainer.append(that.$selectionUl);
112
112
 
113
- ms.on('focusin', function(){
114
- selectableUl.focus();
115
- }).on('focusout', function(){
116
- selectableUl.removeClass('ms-focus');
117
- selectedUl.removeClass('ms-focus');
113
+ that.$container.append(that.$selectableContainer);
114
+ that.$container.append(that.$selectionContainer);
115
+ ms.after(that.$container);
116
+ that.$selectableUl.on('mouseenter', '.ms-elem-selectable', function(){
117
+ $('li', that.$container).removeClass('ms-hover');
118
+ $(this).addClass('ms-hover');
119
+ }).on('mouseleave', function(){
120
+ $('li', that.$container).removeClass('ms-hover');
121
+ });
122
+
123
+ if(that.options.dblClick) {
124
+ that.$selectableUl.on('dblclick', '.ms-elem-selectable', function(){
125
+ that.select($(this).attr('id').replace(/-selectable/, ''));
126
+ });
127
+ that.$selectionUl.on('dblclick', '.ms-elem-selection', function(){
128
+ that.deselect($(this).attr('id').replace(/-selection/, ''));
129
+ });
130
+ } else {
131
+ that.$selectableUl.on('click', '.ms-elem-selectable', function(){
132
+ that.select($(this).attr('id').replace(/-selectable/, ''));
133
+ });
134
+ that.$selectionUl.on('click', '.ms-elem-selection', function(){
135
+ that.deselect($(this).attr('id').replace(/-selection/, ''));
118
136
  });
137
+ }
119
138
 
120
- ms.onKeyDown = function(e, keyContainer){
121
- var selectables = $('.'+keyContainer+' li:visible:not(.ms-optgroup-label, .ms-optgroup-container)', container),
122
- selectablesLength = selectables.length,
123
- selectableFocused = $('.'+keyContainer+' li.ms-hover', container),
124
- selectableFocusedIndex = $('.'+keyContainer+' li:visible:not(.ms-optgroup-label, .ms-optgroup-container)', container).index(selectableFocused),
125
- liHeight = selectables.first().outerHeight(),
126
- numberOfItemsDisplayed = Math.ceil(container.outerHeight()/liHeight),
127
- scrollStart = Math.ceil(numberOfItemsDisplayed/4);
128
-
129
- selectables.removeClass('ms-hover');
130
- if (e.keyCode == 32){ // space
131
- var method = keyContainer == 'ms-selectable' ? 'select' : 'deselect';
132
- ms.multiSelect(method, selectableFocused.first().attr('ms-value'));
133
139
 
134
- } else if (e.keyCode == 40){ // Down
135
- var nextIndex = (selectableFocusedIndex+1 != selectablesLength) ? selectableFocusedIndex+1 : 0,
136
- nextSelectableLi = selectables.eq(nextIndex);
140
+ that.$selectionUl.on('mouseenter', '.ms-elem-selection', function(){
141
+ $('li', that.$selectionUl).removeClass('ms-hover');
142
+ $(this).addClass('ms-hover');
143
+ }).on('mouseleave', function(){
144
+ $('li', that.$selectionUl).removeClass('ms-hover');
145
+ });
137
146
 
138
- nextSelectableLi.addClass('ms-hover');
139
- if (nextIndex > scrollStart){
140
- scroll += liHeight;
141
- } else if (nextIndex == 0){
142
- scroll = 0;
143
- }
144
- $('.'+keyContainer+' ul', container).scrollTop(scroll);
145
- } else if (e.keyCode == 38){ // Up
146
- var prevIndex = (selectableFocusedIndex-1 >= 0) ? selectableFocusedIndex-1 : selectablesLength-1,
147
- prevSelectableLi = selectables.eq(prevIndex);
148
- selectables.removeClass('ms-hover');
149
- prevSelectableLi.addClass('ms-hover');
150
- if (selectablesLength-prevIndex+1 < scrollStart){
151
- scroll = liHeight*(selectablesLength-scrollStart);
147
+ that.$selectableUl.on('focusin', function(){
148
+ $(this).addClass('ms-focus');
149
+ that.$selectionUl.focusout();
150
+ }).on('focusout', function(){
151
+ $(this).removeClass('ms-focus');
152
+ $('li', that.$container).removeClass('ms-hover');
153
+ });
154
+
155
+ that.$selectionUl.on('focusin', function(){
156
+ $(this).addClass('ms-focus');
157
+ }).on('focusout', function(){
158
+ $(this).removeClass('ms-focus');
159
+ $('li', that.$container).removeClass('ms-hover');
160
+ });
161
+
162
+ ms.on('focusin', function(){
163
+ ms.focusout();
164
+ that.$selectableUl.focusin();
165
+ }).on('focusout', function(){
166
+ that.$selectableUl.removeClass('ms-focus');
167
+ that.$selectionUl.removeClass('ms-focus');
168
+ });
169
+
170
+ ms.onKeyDown = function(e, keyContainer){
171
+ var ul = that.$container.find('.'+keyContainer).find('.ms-list'),
172
+ lis = ul.find('li:visible:not(.ms-optgroup-label, .ms-optgroup-container)'),
173
+ lisNumber = lis.length,
174
+ liFocused = ul.find('li.ms-hover'),
175
+ liFocusedIndex = liFocused.length > 0 ? lis.index(liFocused) : -1,
176
+ ulHeight = ul.innerHeight(),
177
+ liHeight = lis.first().outerHeight(true),
178
+ numberOfLisDisplayed = Math.floor(ulHeight / liHeight);
179
+
180
+ if (e.keyCode == 32){ // space
181
+ if (liFocused.length >0){
182
+ var method = keyContainer == 'ms-selectable' ? 'select' : 'deselect';
183
+ if (keyContainer == 'ms-selectable'){
184
+ that.select(liFocused.attr('id').replace('-selectable', ''));
152
185
  } else {
153
- scroll -= liHeight;
186
+ that.deselect(liFocused.attr('id').replace('-selection', ''));
154
187
  }
155
- $('.'+keyContainer+' ul', container).scrollTop(scroll);
156
- } else if (e.keyCode == 37 || e.keyCode == 39){ // Right and Left
157
- if (selectableUl.hasClass('ms-focus')){
158
- selectableUl.focusout();
159
- selectedUl.focusin();
160
- } else {
161
- selectableUl.focusin();
162
- selectedUl.focusout();
188
+ lis.removeClass('ms-hover');
189
+ that.scrollTo = 0;
190
+ ul.scrollTop(that.scrollTo);
191
+ }
192
+ } else if (e.keyCode == 40){ // Down
193
+ if (lis.length > 0){
194
+ var nextLiIndex = liFocusedIndex+1,
195
+ nextLi = (lisNumber != nextLiIndex) ? lis.eq(nextLiIndex) : lis.first(),
196
+ ulPosition = ul.position().top,
197
+ nextLiPosition = nextLi.position().top;
198
+
199
+ lis.removeClass('ms-hover');
200
+ nextLi.addClass('ms-hover');
201
+
202
+ if (lisNumber == nextLiIndex){
203
+ that.scrollTo = 0;
204
+ } else if (nextLiPosition >= (ulPosition + (numberOfLisDisplayed * liHeight))){
205
+ that.scrollTo += liHeight;
163
206
  }
207
+ ul.scrollTop(that.scrollTo);
164
208
  }
165
- }
209
+ } else if (e.keyCode == 38){ // Up
210
+ if (lis.length > 0){
211
+ var prevLiIndex = Math.max(liFocusedIndex-1, -1),
212
+ prevLi = lis.eq(prevLiIndex),
213
+ ulPosition = ul.position().top,
214
+ prevLiPosition = prevLi.position().top;
166
215
 
167
- ms.on('keydown', function(e){
168
- if (ms.is(':focus')){
169
- var keyContainer = selectableUl.hasClass('ms-focus') ? 'ms-selectable' : 'ms-selection';
170
- ms.onKeyDown(e, keyContainer);
216
+ lis.removeClass('ms-hover');
217
+ prevLi.addClass('ms-hover');
218
+ if (prevLiPosition <= ulPosition){
219
+ that.scrollTo -= liHeight;
220
+ } else if (prevLiIndex < 0){
221
+ that.scrollTo = (lisNumber - numberOfLisDisplayed) * liHeight;
222
+ }
223
+ ul.scrollTop(that.scrollTo);
171
224
  }
172
- });
225
+ } else if (e.keyCode == 37 || e.keyCode == 39){
226
+ if (that.$selectableUl.hasClass('ms-focus')){
227
+ that.$selectableUl.focusout();
228
+ that.$selectionUl.focusin();
229
+ } else {
230
+ that.$selectableUl.focusin();
231
+ that.$selectionUl.focusout();
232
+ }
233
+ }
173
234
  }
174
- });
235
+
236
+ ms.on('keydown', function(e){
237
+ if (ms.is(':focus')){
238
+ var keyContainer = that.$selectableUl.hasClass('ms-focus') ? 'ms-selectable' : 'ms-selection';
239
+ ms.onKeyDown(e, keyContainer);
240
+ }
241
+ });
242
+ }
243
+
244
+ var selectedValues = ms.find('option:selected').map(function(){ return $(this).val() }).get();
245
+ that.select(selectedValues, 'init')
246
+
247
+ if (typeof that.options.afterInit == 'function') {
248
+ that.options.afterInit.call(this, this.$container);
249
+ }
175
250
  },
176
251
  'refresh' : function() {
177
- $("#ms-"+$(this).attr("id")).remove();
178
- $(this).multiSelect("init", $(this).data("settings"));
252
+ $("#ms-"+this.$element.attr("id")).remove();
253
+ this.init(this.options);
179
254
  },
180
255
  'select' : function(value, method){
181
- var ms = this,
182
- selectedOption = ms.find('option[value="'+value +'"]'),
183
- text = selectedOption.text(),
184
- klass = selectedOption.attr('class'),
185
- titleAttr = selectedOption.attr('title');
186
-
187
- var selectedLi = $('<li class="ms-elem-selected'+(klass ? ' '+klass : '')+'" ms-value="'+value+'">'+text+'</li>'),
188
- selectableUl = $('#ms-'+ms.attr('id')+' .ms-selectable ul'),
189
- selectedUl = $('#ms-'+ms.attr('id')+' .ms-selection ul'),
190
- selectableLi = selectableUl.children('li[ms-value="'+value+'"]'),
191
- haveToSelect = null;
192
-
193
- if (method == 'init'){
194
- haveToSelect = !selectableLi.hasClass(ms.data('settings').disabledClass) && selectedOption.prop('selected');
195
- } else {
196
- haveToSelect = !selectableLi.hasClass(ms.data('settings').disabledClass);
197
- ms.focus();
198
- }
199
- if (haveToSelect && selectedUl.children('li[ms-value="'+value+'"]').length == 0){
200
- var parentOptgroup = selectableLi.parent('.ms-optgroup');
201
- if (parentOptgroup.length > 0)
202
- if (parentOptgroup.children('.ms-elem-selectable:not(:hidden)').length == 1)
203
- parentOptgroup.children('.ms-optgroup-label').hide();
204
- selectableLi.addClass('ms-selected');
205
- selectableLi.hide();
206
- selectedOption.prop('selected', true);
207
- if(titleAttr){
208
- selectedLi.attr('title', titleAttr)
209
- }
210
- if (selectableLi.hasClass(ms.data('settings').disabledClass)){
211
- selectedLi.addClass(ms.data('settings').disabledClass);
212
- } else {
213
- if(ms.data('settings').dblClick) {
214
- selectedLi.dblclick(function(){
215
- ms.multiSelect('deselect', $(this).attr('ms-value'));
216
- });
217
- } else {
218
- selectedLi.click(function(){
219
- ms.multiSelect('deselect', $(this).attr('ms-value'));
220
- });
221
- }
222
- }
256
+ if (typeof value == 'string')
257
+ value = [value]
258
+ var that = this,
259
+ ms = this.$element,
260
+ selectables = this.$selectableUl.find('#' + value.join('-selectable, #')+'-selectable').filter(':not(.'+that.options.disabledClass+')'),
261
+ selections = this.$selectionUl.find('#' + value.join('-selection, #') + '-selection'),
262
+ options = ms.find('option').filter(function(index){ return($.inArray(this.value, value) > -1) });
223
263
 
224
- var selectedUlLis = selectedUl.children('.ms-elem-selected');
225
- if (method != 'init' && ms.data('settings').keepOrder && selectedUlLis.length > 0) {
264
+ if (selectables.length > 0){
265
+ selectables.addClass('ms-selected').hide();
266
+ selections.addClass('ms-selected').show();
267
+ options.prop('selected', true);
226
268
 
227
- var getIndexOf = function(value) {
228
- elems = selectableUl.children('.ms-elem-selectable');
229
- return(elems.index(elems.closest('[ms-value="'+value+'"]')));
230
- }
269
+ var selectableOptgroups = that.$selectableUl.children('.ms-optgroup-container');
270
+ if (selectableOptgroups.length > 0){
271
+ selectableOptgroups.each(function(){
272
+ var selectablesLi = $(this).find('.ms-elem-selectable');
273
+ if (selectablesLi.length == selectablesLi.filter('.ms-selected').length){
274
+ $(this).find('.ms-optgroup-label').hide();
275
+ }
276
+ });
231
277
 
232
- var index = getIndexOf(selectedLi.attr('ms-value'));
233
- if (index == 0)
234
- selectedUl.prepend(selectedLi);
235
- else {
236
- for (i = index - 1; i >= 0; i--){
237
- if (selectedUlLis[i] && getIndexOf($(selectedUlLis[i]).attr('ms-value')) < index) {
238
- $(selectedUlLis[i]).after(selectedLi);
239
- break;
240
- } else if (i == 0) {
241
- $(selectedUlLis[i]).before(selectedLi);
242
- }
278
+ var selectionOptgroups = that.$selectionUl.children('.ms-optgroup-container');
279
+ selectionOptgroups.each(function(){
280
+ var selectionsLi = $(this).find('.ms-elem-selection');
281
+ if (selectionsLi.filter('.ms-selected').length > 0){
282
+ $(this).find('.ms-optgroup-label').show();
243
283
  }
244
- }
245
- } else {
246
- selectedUl.append(selectedLi);
247
- }
248
- selectedLi.on('mouseenter', function(){
249
- $('li', selectedUl).removeClass('ms-hover');
250
- $(this).addClass('ms-hover');
251
- }).on('mouseout', function(){
252
- $('li', selectedUl).removeClass('ms-hover');
253
- });
254
- if (method == "select_all" && parentOptgroup.children('.ms-elem-selectable').length > 0){
255
- parentOptgroup.children('.ms-optgroup-label').hide();
284
+ });
256
285
  }
257
- if(method != 'init' || ms.data('settings').selectCallbackOnInit){
286
+ if (method != 'init'){
287
+ that.$selectionUl.focusout();
288
+ that.$selectableUl.focusin();
258
289
  ms.trigger('change');
259
- selectedUl.trigger('change');
260
- selectableUl.trigger('change');
261
- if (typeof ms.data('settings').afterSelect == 'function' &&
262
- (method != 'init' || ms.data('settings').selectCallbackOnInit)) {
263
- ms.data('settings').afterSelect.call(this, value, text);
290
+ if (typeof that.options.afterSelect == 'function') {
291
+ that.options.afterSelect.call(this, value);
264
292
  }
265
293
  }
266
294
  }
267
295
  },
268
296
  'deselect' : function(value){
269
- var ms = this,
270
- selectedUl = $('#ms-'+ms.attr('id')+' .ms-selection ul'),
271
- selectedOption = ms.find('option[value="'+value +'"]'),
272
- selectedLi = selectedUl.children('li[ms-value="'+value+'"]');
273
-
274
- if(selectedLi){
275
- selectedUl.focusin();
276
- var selectableUl = $('#ms-'+ms.attr('id')+' .ms-selectable ul'),
277
- selectedUl = $('#ms-'+ms.attr('id')+' .ms-selection ul'),
278
- selectableLi = selectableUl.children('li[ms-value="'+value+'"]'),
279
- selectedLi = selectedUl.children('li[ms-value="'+value+'"]');
280
-
281
- var parentOptgroup = selectableLi.parent('.ms-optgroup');
282
- if (parentOptgroup.length > 0){
283
- parentOptgroup.children('.ms-optgroup-label').addClass('ms-collapse').show();
284
- parentOptgroup.children('.ms-elem-selectable:not(.ms-selected)').show();
297
+ if (typeof value == 'string')
298
+ value = [value]
299
+ var that = this,
300
+ ms = this.$element,
301
+ selectables = this.$selectableUl.find('#' + value.join('-selectable, #')+'-selectable'),
302
+ selections = this.$selectionUl.find('#' + value.join('-selection, #')+'-selection').filter('.ms-selected'),
303
+ options = ms.find('option').filter(function(index){ return($.inArray(this.value, value) > -1) });
304
+
305
+ if (selections.length > 0){
306
+ selectables.removeClass('ms-selected').show();
307
+ selections.removeClass('ms-selected').hide();
308
+ options.prop('selected', false);
309
+
310
+ var selectableOptgroups = that.$selectableUl.children('.ms-optgroup-container');
311
+ if (selectableOptgroups.length > 0){
312
+ selectableOptgroups.each(function(){
313
+ var selectablesLi = $(this).find('.ms-elem-selectable');
314
+ if (selectablesLi.filter(':not(.ms-selected)').length > 0){
315
+ $(this).find('.ms-optgroup-label').show();
316
+ }
317
+ });
318
+
319
+ var selectionOptgroups = that.$selectionUl.children('.ms-optgroup-container');
320
+ selectionOptgroups.each(function(){
321
+ var selectionsLi = $(this).find('.ms-elem-selection');
322
+ if (selectionsLi.filter('.ms-selected').length == 0){
323
+ $(this).find('.ms-optgroup-label').hide();
324
+ }
325
+ });
285
326
  }
286
- selectedOption.prop('selected', false);
287
- selectableLi.show();
288
- selectableLi.removeClass('ms-selected');
289
- selectedLi.remove();
290
- selectedUl.trigger('change');
291
- selectableUl.trigger('change');
327
+ this.$selectableUl.focusout();
328
+ this.$selectionUl.focusin();
292
329
  ms.trigger('change');
293
- if (typeof ms.data('settings').afterDeselect == 'function') {
294
- ms.data('settings').afterDeselect.call(this, value, selectedLi.text());
330
+ if (typeof that.options.afterDeselect == 'function') {
331
+ that.options.afterDeselect.call(this, value);
295
332
  }
296
333
  }
297
334
  },
298
- 'select_all' : function(visible){
299
- var ms = this,
300
- selectableUl = $('#ms-'+ms.attr('id')+' .ms-selectable ul');
301
-
302
- ms.find("option:not(:selected)").each(function(){
303
- var value = $(this).val();
304
- if (visible){
305
- var selectableLi = selectableUl.children('li[ms-value="'+value+'"]');
306
- if (selectableLi.filter(':visible').length > 0){
307
- ms.multiSelect('select', value, 'select_all');
308
- }
309
- } else {
310
- ms.multiSelect('select', value, 'select_all');
311
- }
312
- });
335
+ 'select_all' : function(){
336
+ var ms = this.$element;
337
+
338
+ ms.find('option').prop('selected', true);
339
+ this.$selectableUl.find('.ms-elem-selectable').addClass('ms-selected').hide();
340
+ this.$selectionUl.find('.ms-optgroup-label').show();
341
+ this.$selectableUl.find('.ms-optgroup-label').hide();
342
+ this.$selectionUl.find('.ms-elem-selection').addClass('ms-selected').show();
343
+ this.$selectionUl.focusin();
344
+ this.$selectableUl.focusout();
345
+ ms.trigger('change');
313
346
  },
314
347
  'deselect_all' : function(){
315
- var ms = this,
316
- selectedUl = $('#ms-'+ms.attr('id')+' .ms-selection ul');
348
+ var ms = this.$element;
317
349
 
318
- ms.find("option:selected").each(function(){
319
- ms.multiSelect('deselect', $(this).val(), 'deselect_all');
320
- });
321
- }
322
- };
323
-
324
- $.fn.multiSelect = function(method){
325
- if ( msMethods[method] ) {
326
- return msMethods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
327
- } else if ( typeof method === 'object' || ! method ) {
328
- return msMethods.init.apply( this, arguments );
329
- } else {
330
- if(console.log) console.log( 'Method ' + method + ' does not exist on jquery.multiSelect' );
350
+ ms.find('option').prop('selected', false);
351
+ this.$selectableUl.find('.ms-elem-selectable').removeClass('ms-selected').show();
352
+ this.$selectionUl.find('.ms-optgroup-label').hide();
353
+ this.$selectableUl.find('.ms-optgroup-label').show();
354
+ this.$selectionUl.find('.ms-elem-selection').removeClass('ms-selected').hide();
355
+ this.$selectableUl.focusin();
356
+ this.$selectionUl.focusout();
357
+ ms.trigger('change');
358
+ },
359
+ isDomNode: function (attr){
360
+ return (
361
+ attr &&
362
+ typeof attr === "object" &&
363
+ typeof attr.nodeType === "number" &&
364
+ typeof attr.nodeName === "string"
365
+ );
331
366
  }
332
- return false;
333
- };
334
- })(jQuery);
367
+ }
368
+
369
+ /* MULTISELECT PLUGIN DEFINITION
370
+ * ======================= */
371
+
372
+ $.fn.multiSelect = function () {
373
+ var option = arguments[0],
374
+ args = arguments;
375
+
376
+ return this.each(function () {
377
+ var $this = $(this),
378
+ data = $this.data('multiselect'),
379
+ options = $.extend({}, $.fn.multiSelect.defaults, $this.data(), typeof option == 'object' && option);
380
+
381
+ if (!data) $this.data('multiselect', (data = new MultiSelect(this, options)))
382
+
383
+ if (typeof option == 'string'){
384
+ data[option](args[1])
385
+ } else {
386
+ data.init();
387
+ }
388
+ })
389
+ }
390
+
391
+ $.fn.multiSelect.defaults = {
392
+ disabledClass : 'disabled',
393
+ dblClick : false
394
+ }
395
+
396
+ $.fn.multiSelect.Constructor = MultiSelect
397
+
398
+ }(window.jQuery);
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multi-select-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0.1
4
+ version: 0.9.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-23 00:00:00.000000000 Z
12
+ date: 2012-12-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: railties