diff options
author | lou <louiscuny@gmail.com> | 2012-11-30 22:59:21 +0100 |
---|---|---|
committer | lou <louiscuny@gmail.com> | 2012-11-30 22:59:21 +0100 |
commit | 21ea55f196acb6f0e609d0ea9323ab85773d7bb5 (patch) | |
tree | 25ba07346337ef94161ce15f8b1166f95c575852 | |
parent | a1c1bece008ba57cf9d29f35130cb3b68040680c (diff) | |
download | multi-select-21ea55f196acb6f0e609d0ea9323ab85773d7bb5.zip multi-select-21ea55f196acb6f0e609d0ea9323ab85773d7bb5.tar.gz multi-select-21ea55f196acb6f0e609d0ea9323ab85773d7bb5.tar.bz2 |
use Bootstrap style plugin instead of jQuery UI style
-rw-r--r-- | js/jquery.multi-select.js | 472 |
1 files changed, 250 insertions, 222 deletions
diff --git a/js/jquery.multi-select.js b/js/jquery.multi-select.js index 2f909b7..01435ab 100644 --- a/js/jquery.multi-select.js +++ b/js/jquery.multi-select.js @@ -9,240 +9,251 @@ * http://sam.zoy.org/wtfpl/COPYING for more details. */ -(function($){ - var msMethods = { - 'init' : function(options){ - this.settings = { - disabledClass : 'disabled', - dblClick : false - }; - if(options) { - this.settings = $.extend(this.settings, options); - } - var multiSelects = this; - multiSelects.css('position', 'absolute').css('left', '-9999px'); - return multiSelects.each(function(){ - var ms = $(this), - container, - selectableContainer, - selectionContainer, - selectableUl, - selectionUl; - - if (ms.next('.ms-container').length == 0){ - ms.attr('id', ms.attr('id') ? ms.attr('id') : 'ms-'+Math.ceil(Math.random()*1000)); - container = $('<div id="ms-'+ms.attr('id')+'" class="ms-container"></div>'), - selectableContainer = $('<div class="ms-selectable"></div>'), - selectionContainer = $('<div class="ms-selection"></div>'), - selectableUl = $('<ul class="ms-list"></ul>'), - selectionUl = $('<ul class="ms-list"></ul>'); - - ms.data('settings', multiSelects.settings); - - var optgroupLabel = null, - optgroupId = null, - optgroupCpt = 0, - scroll = 0; +!function ($) { + + "use strict"; // jshint ;_; + + + /* MULTISELECT CLASS DEFINITION + * ====================== */ + + var MultiSelect = function (element, options) { + this.options = options; + this.$element = $(element); + this.init(); + } + + MultiSelect.prototype = { + constructor: MultiSelect, + + init: function(){ + + var that = this, + ms = this.$element, + container, + selectableContainer, + selectionContainer, + selectableUl, + selectionUl; + + if (ms.next('.ms-container').length == 0){ + ms.css({ position: 'absolute', left: '-9999px' }); + ms.attr('id', ms.attr('id') ? ms.attr('id') : 'ms-'+Math.ceil(Math.random()*1000)); + container = $('<div id="ms-'+ms.attr('id')+'" class="ms-container"></div>'), + selectableContainer = $('<div class="ms-selectable"></div>'), + selectionContainer = $('<div class="ms-selection"></div>'), + selectableUl = $('<ul class="ms-list"></ul>'), + selectionUl = $('<ul class="ms-list"></ul>'); + + var optgroupLabel = null, + optgroupId = null, + optgroupCpt = 0, + scroll = 0; + + + ms.find('optgroup, option').each(function(){ + if ($(this).is('optgroup')){ + optgroupLabel = $(this).attr('label'); + optgroupId = 'ms-'+ms.attr('id')+'-optgroup-'+optgroupCpt; + + selectableUl.append( + '<li class="ms-optgroup-container" id="'+optgroupId+'-selectable">\ + <ul class="ms-optgroup">\ + <li class="ms-optgroup-label"><span>'+optgroupLabel+'</span></li>\ + </ul>\ + </li>'); + selectionUl.append( + '<li class="ms-optgroup-container" id="'+optgroupId+'-selection">\ + <ul class="ms-optgroup">\ + <li class="ms-optgroup-label"><span>'+optgroupLabel+'</span></li>\ + </ul>\ + </li>'); + optgroupCpt++; + } else { + var attributes = ""; - ms.find('optgroup, option').each(function(){ - if ($(this).is('optgroup')){ - optgroupLabel = $(this).attr('label'); - optgroupId = 'ms-'+ms.attr('id')+'-optgroup-'+optgroupCpt; - - selectableUl.append( - '<li class="ms-optgroup-container" id="'+optgroupId+'-selectable">\ - <ul class="ms-optgroup">\ - <li class="ms-optgroup-label"><span>'+optgroupLabel+'</span></li>\ - </ul>\ - </li>'); - selectionUl.append( - '<li class="ms-optgroup-container" id="'+optgroupId+'-selection">\ - <ul class="ms-optgroup">\ - <li class="ms-optgroup-label"><span>'+optgroupLabel+'</span></li>\ - </ul>\ - </li>'); - optgroupCpt++; - } else { + for (var cpt = 0; cpt < this.attributes.length; cpt++){ + var attr = this.attributes[cpt], + name = (attr.name == 'value') ? 'ms-value' : attr.name; - var attributes = ""; - - for (var cpt = 0; cpt < this.attributes.length; cpt++){ - var attr = this.attributes[cpt], - name = (attr.name == 'value') ? 'ms-value' : attr.name; - - attributes += name+'="'+attr.value+'" '; - } - var selectableLi = $('<li '+attributes+'><span>'+$(this).text()+'</span></li>'), - selectedLi = selectableLi.clone(); - - selectableLi.addClass('ms-elem-selectable'); - selectedLi.addClass('ms-elem-selection').hide(); - selectionUl.find('.ms-optgroup-label').hide(); - - if ($(this).prop('disabled') || ms.prop('disabled')){ - selectableLi.prop('disabled', true); - selectableLi.addClass(multiSelects.settings.disabledClass); - } - - if (optgroupId){ - selectableUl.children('#'+optgroupId+'-selectable').find('ul').first().append(selectableLi); - selectionUl.children('#'+optgroupId+'-selection').find('ul').first().append(selectedLi); - } else { - selectableUl.append(selectableLi); - selectionUl.append(selectedLi); - } + attributes += name+'="'+attr.value+'" '; } - }); + var selectableLi = $('<li '+attributes+'><span>'+$(this).text()+'</span></li>'), + selectedLi = selectableLi.clone(); - if (multiSelects.settings.selectableHeader){ - selectableContainer.append(multiSelects.settings.selectableHeader); - } - selectableContainer.append(selectableUl); - - if (multiSelects.settings.selectionHeader){ - selectionContainer.append(multiSelects.settings.selectionHeader); + selectableLi.addClass('ms-elem-selectable'); + selectedLi.addClass('ms-elem-selection').hide(); + selectionUl.find('.ms-optgroup-label').hide(); + + if ($(this).prop('disabled') || ms.prop('disabled')){ + selectableLi.prop('disabled', true); + selectableLi.addClass(that.options.disabledClass); + } + + if (optgroupId){ + selectableUl.children('#'+optgroupId+'-selectable').find('ul').first().append(selectableLi); + selectionUl.children('#'+optgroupId+'-selection').find('ul').first().append(selectedLi); + } else { + selectableUl.append(selectableLi); + selectionUl.append(selectedLi); + } } - selectionContainer.append(selectionUl); + }); - container.append(selectableContainer); - container.append(selectionContainer); + if (that.options.selectableHeader){ + selectableContainer.append(that.options.selectableHeader); + } + selectableContainer.append(selectableUl); + + if (that.options.selectionHeader){ + selectionContainer.append(that.options.selectionHeader); + } + selectionContainer.append(selectionUl); - ms.after(container); + container.append(selectableContainer); + container.append(selectionContainer); - ms.find('option:selected').each(function(){ - ms.multiSelect('select', $(this).val(), 'init'); - }); + ms.after(container); - selectableUl.on('mouseenter', '.ms-elem-selectable', function(){ - $('li', container).removeClass('ms-hover'); - $(this).addClass('ms-hover'); - }).on('mouseout', function(){ - $('li', container).removeClass('ms-hover'); - }); + ms.find('option:selected').each(function(){ + that.select($(this).val(), 'init'); + }); - if(multiSelects.settings.dblClick) { - selectableUl.on('dblclick', '.ms-elem-selectable', function(){ - ms.multiSelect('select', $(this).attr('ms-value')); - }); - selectionUl.on('dblclick', '.ms-elem-selection', function(){ - ms.multiSelect('deselect', $(this).attr('ms-value')); - }); - } else { - selectableUl.on('click', '.ms-elem-selectable', function(){ - ms.multiSelect('select', $(this).attr('ms-value')); - }); - selectionUl.on('click', '.ms-elem-selection', function(){ - ms.multiSelect('deselect', $(this).attr('ms-value')); - }); - } + selectableUl.on('mouseenter', '.ms-elem-selectable', function(){ + $('li', container).removeClass('ms-hover'); + $(this).addClass('ms-hover'); + }).on('mouseout', function(){ + $('li', container).removeClass('ms-hover'); + }); - selectionUl.on('mouseenter', '.ms-elem-selection', function(){ - $('li', selectionUl).removeClass('ms-hover'); - $(this).addClass('ms-hover'); - }).on('mouseout', function(){ - $('li', selectionUl).removeClass('ms-hover'); + if(that.options.dblClick) { + selectableUl.on('dblclick', '.ms-elem-selectable', function(){ + that.select($(this).attr('ms-value')); }); - - selectableUl.on('focusin', function(){ - $(this).addClass('ms-focus'); - selectionUl.focusout(); - }).on('focusout', function(){ - $(this).removeClass('ms-focus'); - $('li', container).removeClass('ms-hover'); + selectionUl.on('dblclick', '.ms-elem-selection', function(){ + that.deselect($(this).attr('ms-value')); }); - - selectionUl.on('focusin', function(){ - $(this).addClass('ms-focus'); - }).on('focusout', function(){ - $(this).removeClass('ms-focus'); - $('li', container).removeClass('ms-hover'); + } else { + selectableUl.on('click', '.ms-elem-selectable', function(){ + that.select($(this).attr('ms-value')); }); - - ms.on('focusin', function(){ - selectableUl.focus(); - }).on('focusout', function(){ - selectableUl.removeClass('ms-focus'); - selectionUl.removeClass('ms-focus'); + selectionUl.on('click', '.ms-elem-selection', function(){ + that.deselect($(this).attr('ms-value')); }); + } - ms.onKeyDown = function(e, keyContainer){ - var selectables = $('.'+keyContainer+' li:visible:not(.ms-optgroup-label, .ms-optgroup-container)', container), - selectablesLength = selectables.length, - selectableFocused = $('.'+keyContainer+' li.ms-hover', container), - selectableFocusedIndex = $('.'+keyContainer+' li:visible:not(.ms-optgroup-label, .ms-optgroup-container)', container).index(selectableFocused), - liHeight = selectables.first().outerHeight(), - numberOfItemsDisplayed = Math.ceil(container.outerHeight()/liHeight), - scrollStart = Math.ceil(numberOfItemsDisplayed/4); + selectionUl.on('mouseenter', '.ms-elem-selection', function(){ + $('li', selectionUl).removeClass('ms-hover'); + $(this).addClass('ms-hover'); + }).on('mouseout', function(){ + $('li', selectionUl).removeClass('ms-hover'); + }); + + selectableUl.on('focusin', function(){ + $(this).addClass('ms-focus'); + selectionUl.focusout(); + }).on('focusout', function(){ + $(this).removeClass('ms-focus'); + $('li', container).removeClass('ms-hover'); + }); + + selectionUl.on('focusin', function(){ + $(this).addClass('ms-focus'); + }).on('focusout', function(){ + $(this).removeClass('ms-focus'); + $('li', container).removeClass('ms-hover'); + }); + + ms.on('focusin', function(){ + selectableUl.focus(); + }).on('focusout', function(){ + selectableUl.removeClass('ms-focus'); + selectionUl.removeClass('ms-focus'); + }); + + ms.onKeyDown = function(e, keyContainer){ + var selectables = $('.'+keyContainer+' li:visible:not(.ms-optgroup-label, .ms-optgroup-container)', container), + selectablesLength = selectables.length, + selectableFocused = $('.'+keyContainer+' li.ms-hover', container), + selectableFocusedIndex = $('.'+keyContainer+' li:visible:not(.ms-optgroup-label, .ms-optgroup-container)', container).index(selectableFocused), + liHeight = selectables.first().outerHeight(), + numberOfItemsDisplayed = Math.ceil(container.outerHeight()/liHeight), + scrollStart = Math.ceil(numberOfItemsDisplayed/4); + + selectables.removeClass('ms-hover'); + if (e.keyCode == 32){ // space + var method = keyContainer == 'ms-selectable' ? 'select' : 'deselect'; + if (keyContainer == 'ms-selectable'){ + that.select(selectableFocused.first().attr('ms-value')); + } else { + that.deselect(selectableFocused.first().attr('ms-value')); + } + + } else if (e.keyCode == 40){ // Down + var nextIndex = (selectableFocusedIndex+1 != selectablesLength) ? selectableFocusedIndex+1 : 0, + nextSelectableLi = selectables.eq(nextIndex); + nextSelectableLi.addClass('ms-hover'); + if (nextIndex > scrollStart){ + scroll += liHeight; + } else if (nextIndex == 0){ + scroll = 0; + } + $('.'+keyContainer+' ul', container).scrollTop(scroll); + } else if (e.keyCode == 38){ // Up + var prevIndex = (selectableFocusedIndex-1 >= 0) ? selectableFocusedIndex-1 : selectablesLength-1, + prevSelectableLi = selectables.eq(prevIndex); selectables.removeClass('ms-hover'); - if (e.keyCode == 32){ // space - var method = keyContainer == 'ms-selectable' ? 'select' : 'deselect'; - ms.multiSelect(method, selectableFocused.first().attr('ms-value')); - - } else if (e.keyCode == 40){ // Down - var nextIndex = (selectableFocusedIndex+1 != selectablesLength) ? selectableFocusedIndex+1 : 0, - nextSelectableLi = selectables.eq(nextIndex); - - nextSelectableLi.addClass('ms-hover'); - if (nextIndex > scrollStart){ - scroll += liHeight; - } else if (nextIndex == 0){ - scroll = 0; - } - $('.'+keyContainer+' ul', container).scrollTop(scroll); - } else if (e.keyCode == 38){ // Up - var prevIndex = (selectableFocusedIndex-1 >= 0) ? selectableFocusedIndex-1 : selectablesLength-1, - prevSelectableLi = selectables.eq(prevIndex); - selectables.removeClass('ms-hover'); - prevSelectableLi.addClass('ms-hover'); - if (selectablesLength-prevIndex+1 < scrollStart){ - scroll = liHeight*(selectablesLength-scrollStart); - } else { - scroll -= liHeight; - } - $('.'+keyContainer+' ul', container).scrollTop(scroll); - } else if (e.keyCode == 37 || e.keyCode == 39){ // Right and Left - if (selectableUl.hasClass('ms-focus')){ - selectableUl.focusout(); - selectionUl.focusin(); - } else { - selectableUl.focusin(); - selectionUl.focusout(); - } + prevSelectableLi.addClass('ms-hover'); + if (selectablesLength-prevIndex+1 < scrollStart){ + scroll = liHeight*(selectablesLength-scrollStart); + } else { + scroll -= liHeight; } - } - - ms.on('keydown', function(e){ - if (ms.is(':focus')){ - var keyContainer = selectableUl.hasClass('ms-focus') ? 'ms-selectable' : 'ms-selection'; - ms.onKeyDown(e, keyContainer); + $('.'+keyContainer+' ul', container).scrollTop(scroll); + } else if (e.keyCode == 37 || e.keyCode == 39){ // Right and Left + if (selectableUl.hasClass('ms-focus')){ + selectableUl.focusout(); + selectionUl.focusin(); + } else { + selectableUl.focusin(); + selectionUl.focusout(); } - }); - } - if (typeof ms.data('settings').afterInit == 'function') { - ms.data('settings').afterInit.call(this, container); + } } - }); + + ms.on('keydown', function(e){ + if (ms.is(':focus')){ + var keyContainer = selectableUl.hasClass('ms-focus') ? 'ms-selectable' : 'ms-selection'; + ms.onKeyDown(e, keyContainer); + } + }); + } + if (typeof that.options.afterInit == 'function') { + that.options.afterInit.call(this, container); + } }, 'refresh' : function() { - $("#ms-"+$(this).attr("id")).remove(); - $(this).multiSelect("init", $(this).data("settings")); + $("#ms-"+this.$element.attr("id")).remove(); + this.init(this.options); }, 'select' : function(value, method){ - var ms = this; + var that = this, + ms = this.$element; if (typeof value == 'string'){ var selectableUl = $('#ms-'+ms.attr('id')+' .ms-selectable ul.ms-list'), selectionUl = $('#ms-'+ms.attr('id')+' .ms-selection ul.ms-list'), selectedOption = ms.find('option[value="'+value +'"]'), selectedLi = selectionUl.find('li[ms-value="'+value+'"]'), - selectableLi = selectableUl.find('li[ms-value="'+value+'"]'); + selectableLi = selectableUl.find('li[ms-value="'+value+'"]'), + haveToSelect; if (method == 'init'){ - haveToSelect = !selectableLi.hasClass(ms.data('settings').disabledClass) && selectedOption.prop('selected'); + haveToSelect = !selectableLi.hasClass(that.options.disabledClass) && selectedOption.prop('selected'); } else { - haveToSelect = !selectableLi.hasClass(ms.data('settings').disabledClass); + haveToSelect = !selectableLi.hasClass(that.options.disabledClass); ms.focus(); } @@ -262,8 +273,8 @@ selectedLi.addClass('ms-selected').show(); if (method != 'init'){ ms.trigger('change'); - if (typeof ms.data('settings').afterSelect == 'function') { - ms.data('settings').afterSelect.call(this, value, selectedOption.text()); + if (typeof that.options.afterSelect == 'function') { + that.options.afterSelect.call(this, value, selectedOption.text()); } } } @@ -271,12 +282,13 @@ var ms = this; for (var cpt = 0; cpt < value.length; cpt++){ - ms.multiSelect('select', value[cpt]); + that.select(value[cpt]); } } }, 'deselect' : function(value){ - var ms = this; + var that = this, + ms = this.$element; if (typeof value == 'string'){ var selectableUl = $('#ms-'+ms.attr('id')+' .ms-selectable ul.ms-list'), @@ -306,20 +318,20 @@ ms.trigger('change'); - if (typeof ms.data('settings').afterDeselect == 'function') { - ms.data('settings').afterDeselect.call(this, value, selectedLi.text()); + if (typeof that.options.afterDeselect == 'function') { + that.options.afterDeselect.call(this, value, selectedLi.text()); } } } else { // Array var ms = this; for (var cpt = 0; cpt < value.length; cpt++){ - ms.multiSelect('deselect', value[cpt]); + that.deselect(value[cpt]); } } }, - 'select_all' : function(visible){ - var ms = this, + 'select_all' : function(){ + var ms = this.$element, selectableUl = $('#ms-'+ms.attr('id')+' .ms-selectable ul.ms-list'), selectionUl = $('#ms-'+ms.attr('id')+' .ms-selection ul.ms-list'); @@ -330,7 +342,7 @@ selectionUl.find('.ms-elem-selection').addClass('ms-selected').show(); }, 'deselect_all' : function(){ - var ms = this, + var ms = this.$element, selectableUl = $('#ms-'+ms.attr('id')+' .ms-selectable ul'), selectionUl = $('#ms-'+ms.attr('id')+' .ms-selection ul'); @@ -340,16 +352,32 @@ selectableUl.find('.ms-optgroup-label').show(); selectionUl.find('.ms-elem-selection').removeClass('ms-selected').hide(); } - }; - - $.fn.multiSelect = function(method){ - if ( msMethods[method] ) { - return msMethods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); - } else if ( typeof method === 'object' || ! method ) { - return msMethods.init.apply( this, arguments ); - } else { - if(console.log) console.log( 'Method ' + method + ' does not exist on jquery.multiSelect' ); - } - return false; - }; -})(jQuery);
\ No newline at end of file + } + + /* MULTISELECT PLUGIN DEFINITION + * ======================= */ + + $.fn.multiSelect = function () { + var option = arguments[0], + args = arguments; + + return this.each(function () { + var $this = $(this), + options = $.extend({}, $.fn.multiSelect.defaults, $this.data(), typeof option == 'object' && option), + data = new MultiSelect(this, options); + + + if (typeof option == 'string'){ + data[option](args[1]) + } + }) + } + + $.fn.multiSelect.defaults = { + disabledClass : 'disabled', + dblClick : false + } + + $.fn.multiSelect.Constructor = MultiSelect + +}(window.jQuery);
\ No newline at end of file |