source: OpenRLabs-Git/deploy/rlabs-docker/web2py-rlabs/applications/admin/static/plugin_multiselect/jquery.multi-select.js

main
Last change on this file was 42bd667, checked in by David Fuertes <dfuertes@…>, 4 years ago

Historial Limpio

  • Property mode set to 100755
File size: 13.3 KB
Line 
1/*
2* MultiSelect v0.8
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  var msMethods = {
14    'init' : function(options){
15      this.settings = {
16        disabledClass : 'disabled',
17        selectCallbackOnInit: false,
18        keepOrder : false
19      };
20      if(options) {
21        this.settings = $.extend(this.settings, options);
22      }
23      var multiSelects = this;
24      multiSelects.css('position', 'absolute').css('left', '-9999px');
25      return multiSelects.each(function(){
26        var ms = $(this);
27
28        if (ms.next('.ms-container').length == 0){
29          ms.attr('id', ms.attr('id') ? ms.attr('id') : 'ms-'+Math.ceil(Math.random()*1000));
30          var container = $('<div id="ms-'+ms.attr('id')+'" class="ms-container"></div>'),
31              selectableContainer = $('<div class="ms-selectable"></div>'),
32              selectedContainer = $('<div class="ms-selection"></div>'),
33              selectableUl = $('<ul class="ms-list"></ul>'),
34              selectedUl = $('<ul class="ms-list"></ul>');
35         
36          ms.data('settings', multiSelects.settings);
37
38          var optgroupLabel = null,
39              optgroupId = null,
40              optgroupCpt = 0,
41              scroll = 0;
42          ms.find('optgroup,option').each(function(){
43            if ($(this).is('optgroup')){
44              optgroupLabel = $(this).attr('label');
45              optgroupId = 'ms-'+ms.attr('id')+'-optgroup-'+optgroupCpt;
46              selectableUl.append($('<li class="ms-optgroup-container" id="'+
47                                  optgroupId+'"><ul class="ms-optgroup"><li class="ms-optgroup-label">'+
48                                  optgroupLabel+'</li></ul></li>'));
49              optgroupCpt++;
50            } else {
51              var klass = $(this).attr('class') ? ' '+$(this).attr('class') : '';
52              var selectableLi = $('<li class="ms-elem-selectable'+klass+'" ms-value="'+$(this).val()+'">'+$(this).text()+'</li>');
53
54              if ($(this).attr('title'))
55                selectableLi.attr('title', $(this).attr('title'));
56              if ($(this).attr('disabled') || ms.attr('disabled')){
57                selectableLi.attr('disabled', 'disabled');
58                selectableLi.addClass(multiSelects.settings.disabledClass);
59              }
60              selectableLi.click(function(){
61                ms.multiSelect('select', $(this).attr('ms-value'));
62              });
63              var container = optgroupId ? selectableUl.children('#'+optgroupId).find('ul').first() : selectableUl;
64              container.append(selectableLi);
65            }
66          });
67          if (multiSelects.settings.selectableHeader){
68            selectableContainer.append(multiSelects.settings.selectableHeader);
69          }
70          selectableContainer.append(selectableUl);
71          if (multiSelects.settings.selectedHeader){
72            selectedContainer.append(multiSelects.settings.selectedHeader);
73          }
74          selectedContainer.append(selectedUl);
75          container.append(selectableContainer);
76          container.append(selectedContainer);
77          ms.after(container);
78          ms.find('option:selected').each(function(){
79            ms.multiSelect('select', $(this).val(), 'init');
80          });
81
82          $('.ms-elem-selectable', selectableUl).on('mouseenter', function(){
83            $('li', container).removeClass('ms-hover');
84            $(this).addClass('ms-hover');
85          }).on('mouseout', function(){
86            $('li', container).removeClass('ms-hover');
87          });
88
89
90
91          selectableUl.on('focusin', function(){
92            $(this).addClass('ms-focus');
93            selectedUl.focusout();
94          }).on('focusout', function(){
95            $(this).removeClass('ms-focus');
96            $('li', container).removeClass('ms-hover');
97          });
98
99          selectedUl.on('focusin', function(){
100            $(this).addClass('ms-focus');
101          }).on('focusout', function(){
102            $(this).removeClass('ms-focus');
103            $('li', container).removeClass('ms-hover');
104          });
105
106          ms.on('focusin', function(){
107            selectableUl.focus();
108          }).on('focusout', function(){
109            selectableUl.removeClass('ms-focus');
110            selectedUl.removeClass('ms-focus');
111          });
112
113          ms.onKeyDown = function(e, keyContainer){
114            var selectables = $('.'+keyContainer+' li:visible:not(.ms-optgroup-label, .ms-optgroup-container)', container),
115                selectablesLength = selectables.length,
116                selectableFocused = $('.'+keyContainer+' li.ms-hover', container),
117                selectableFocusedIndex = $('.'+keyContainer+' li:visible:not(.ms-optgroup-label, .ms-optgroup-container)', container).index(selectableFocused),
118                liHeight = selectables.first().outerHeight(),
119                numberOfItemsDisplayed = Math.ceil(container.outerHeight()/liHeight),
120                scrollStart = Math.ceil(numberOfItemsDisplayed/4);
121
122            selectables.removeClass('ms-hover');
123            if (e.keyCode == 32){ // space
124              var method = keyContainer == 'ms-selectable' ? 'select' : 'deselect';
125              ms.multiSelect(method, selectableFocused.first().attr('ms-value'));
126
127            } else if (e.keyCode == 40){ // Down
128              var nextIndex = (selectableFocusedIndex+1 != selectablesLength) ? selectableFocusedIndex+1 : 0,
129                  nextSelectableLi = selectables.eq(nextIndex);
130
131              nextSelectableLi.addClass('ms-hover');
132              if (nextIndex > scrollStart){
133                scroll += liHeight;
134              } else if (nextIndex == 0){
135                scroll = 0;
136              }
137              $('.'+keyContainer+' ul', container).scrollTop(scroll);
138            } else if (e.keyCode == 38){ // Up
139              var prevIndex = (selectableFocusedIndex-1 >= 0) ? selectableFocusedIndex-1 : selectablesLength-1,
140                  prevSelectableLi = selectables.eq(prevIndex);
141              selectables.removeClass('ms-hover');
142              prevSelectableLi.addClass('ms-hover');
143              if (selectablesLength-prevIndex+1 < scrollStart){
144                scroll = liHeight*(selectablesLength-scrollStart);
145              } else {
146                scroll -= liHeight;
147              }
148              $('.'+keyContainer+' ul', container).scrollTop(scroll);
149            } else if (e.keyCode == 37 || e.keyCode == 39){ // Right and Left
150              if (selectableUl.hasClass('ms-focus')){
151                selectableUl.focusout();
152                selectedUl.focusin();
153              } else {
154                selectableUl.focusin();
155                selectedUl.focusout();
156              }
157            }
158          }
159
160          ms.on('keydown', function(e){
161            if (ms.is(':focus')){
162              var keyContainer = selectableUl.hasClass('ms-focus') ? 'ms-selectable' : 'ms-selection';
163              ms.onKeyDown(e, keyContainer);
164            }
165          });
166        }
167      });
168    },
169    'refresh' : function() {
170      $("#ms-"+$(this).attr("id")).remove();
171      $(this).multiSelect("init", $(this).data("settings"));
172    },
173    'select' : function(value, method){
174      var ms = this,
175          selectedOption = ms.find('option[value="'+value +'"]'),
176          text = selectedOption.text(),
177          klass = selectedOption.attr('class'),
178          titleAttr = selectedOption.attr('title');
179
180      var selectedLi = $('<li class="ms-elem-selected'+(klass ? ' '+klass : '')+'" ms-value="'+value+'">'+text+'</li>'),
181          selectableUl = $('#ms-'+ms.attr('id')+' .ms-selectable ul'),
182          selectedUl = $('#ms-'+ms.attr('id')+' .ms-selection ul'),
183          selectableLi = selectableUl.children('li[ms-value="'+value+'"]'), 
184          haveToSelect = null;
185
186      if (method == 'init'){
187        haveToSelect = !selectableLi.hasClass(ms.data('settings').disabledClass) && selectedOption.prop('selected');
188      } else {
189        haveToSelect = !selectableLi.hasClass(ms.data('settings').disabledClass);
190        ms.focus();
191      }
192      if (haveToSelect && selectedUl.children('li[ms-value="'+value+'"]').length == 0){
193        var parentOptgroup = selectableLi.parent('.ms-optgroup');
194        if (parentOptgroup.length > 0)
195          if (parentOptgroup.children('.ms-elem-selectable:not(:hidden)').length == 1)
196            parentOptgroup.children('.ms-optgroup-label').hide();
197        selectableLi.addClass('ms-selected');
198        selectableLi.hide();
199        selectedOption.prop('selected', true);
200        if(titleAttr){
201          selectedLi.attr('title', titleAttr)
202        }
203        if (selectableLi.hasClass(ms.data('settings').disabledClass)){
204          selectedLi.addClass(ms.data('settings').disabledClass);
205        } else {
206          selectedLi.click(function(){
207            ms.multiSelect('deselect', $(this).attr('ms-value'));
208          });
209        }
210
211        var selectedUlLis = selectedUl.children('.ms-elem-selected');
212        if (method != 'init' && ms.data('settings').keepOrder && selectedUlLis.length > 0) {
213
214          var getIndexOf = function(value) {
215            elems = selectableUl.children('.ms-elem-selectable');
216            return(elems.index(elems.closest('[ms-value="'+value+'"]')));
217          }
218         
219          var index = getIndexOf(selectedLi.attr('ms-value'));
220          if (index == 0)
221            selectedUl.prepend(selectedLi);
222          else {
223            for (i = index - 1; i >= 0; i--){
224              if (selectedUlLis[i] && getIndexOf($(selectedUlLis[i]).attr('ms-value')) < index) {
225                $(selectedUlLis[i]).after(selectedLi);
226                break;
227              } else if (i == 0) {
228                $(selectedUlLis[i]).before(selectedLi);
229              }
230            }
231          }
232        } else {
233          selectedUl.append(selectedLi);
234        }
235        selectedLi.on('mouseenter', function(){
236          $('li', selectedUl).removeClass('ms-hover');
237          $(this).addClass('ms-hover');
238        }).on('mouseout', function(){
239          $('li', selectedUl).removeClass('ms-hover');
240        });
241        if (method == "select_all" && parentOptgroup.children('.ms-elem-selectable').length > 0){
242          parentOptgroup.children('.ms-optgroup-label').hide();
243        }
244        if(method != 'init' || ms.data('settings').selectCallbackOnInit){
245          ms.trigger('change');
246          selectedUl.trigger('change');
247          selectableUl.trigger('change');
248          if (typeof ms.data('settings').afterSelect == 'function' &&
249              (method != 'init' || ms.data('settings').selectCallbackOnInit)) {
250            ms.data('settings').afterSelect.call(this, value, text);
251          }
252        }
253      }
254    },
255    'deselect' : function(value){
256      var ms = this,
257          selectedUl = $('#ms-'+ms.attr('id')+' .ms-selection ul'),
258          selectedOption = ms.find('option[value="'+value +'"]'),
259          selectedLi = selectedUl.children('li[ms-value="'+value+'"]');
260     
261      if(selectedLi){
262        selectedUl.focusin();
263        var selectableUl = $('#ms-'+ms.attr('id')+' .ms-selectable ul'),
264            selectedUl = $('#ms-'+ms.attr('id')+' .ms-selection ul'),
265            selectableLi = selectableUl.children('li[ms-value="'+value+'"]'),
266            selectedLi = selectedUl.children('li[ms-value="'+value+'"]');
267       
268        var parentOptgroup = selectableLi.parent('.ms-optgroup');
269        if (parentOptgroup.length > 0){
270          parentOptgroup.children('.ms-optgroup-label').addClass('ms-collapse').show();
271          parentOptgroup.children('.ms-elem-selectable:not(.ms-selected)').show();
272        }
273        selectedOption.prop('selected', false);
274        selectableLi.show();
275        selectableLi.removeClass('ms-selected');
276        selectedLi.remove();
277        selectedUl.trigger('change');
278        selectableUl.trigger('change');
279        ms.trigger('change');
280        if (typeof ms.data('settings').afterDeselect == 'function') {
281          ms.data('settings').afterDeselect.call(this, value, selectedLi.text());
282        }
283      }
284    },
285    'select_all' : function(visible){
286      var ms = this,
287          selectableUl = $('#ms-'+ms.attr('id')+' .ms-selectable ul');
288
289      ms.find("option:not(:selected)").each(function(){
290        var value = $(this).val();
291        if (visible){
292          var selectableLi = selectableUl.children('li[ms-value="'+value+'"]');
293          if (selectableLi.filter(':visible').length > 0){
294            ms.multiSelect('select', value, 'select_all');
295          }
296        } else {
297          ms.multiSelect('select', value, 'select_all');
298        }
299      });
300    },
301    'deselect_all' : function(){
302      var ms = this,
303          selectedUl = $('#ms-'+ms.attr('id')+' .ms-selection ul');
304
305      ms.find("option:selected").each(function(){
306        ms.multiSelect('deselect', $(this).val(), 'deselect_all');
307      });
308    }
309  };
310
311  $.fn.multiSelect = function(method){
312    if ( msMethods[method] ) {
313      return msMethods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
314    } else if ( typeof method === 'object' || ! method ) {
315      return msMethods.init.apply( this, arguments );
316    } else {
317      if(console.log) console.log( 'Method ' +  method + ' does not exist on jquery.multiSelect' );
318    }
319    return false;
320  };
321})(jQuery);
Note: See TracBrowser for help on using the repository browser.