summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--js/jquery.multi-select.js472
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