diff options
Diffstat (limited to 'web/js/jquery.multi-select.js')
-rw-r--r-- | web/js/jquery.multi-select.js | 182 |
1 files changed, 131 insertions, 51 deletions
diff --git a/web/js/jquery.multi-select.js b/web/js/jquery.multi-select.js index a41190e9c..6f3ae8de7 100644 --- a/web/js/jquery.multi-select.js +++ b/web/js/jquery.multi-select.js @@ -11,10 +11,13 @@ containerHTML: '<div class="multi-select-container">', menuHTML: '<div class="multi-select-menu">', buttonHTML: '<span class="multi-select-button">', + menuItemsHTML: '<div class="multi-select-menuitems">', menuItemHTML: '<label class="multi-select-menuitem">', + presetsHTML: '<div class="multi-select-presets">', activeClass: 'multi-select-container--open', noneText: '-- Select --', allText: undefined, + presets: undefined, positionedMenuClass: 'multi-select-container--positioned', positionMenuWithin: undefined }; @@ -28,6 +31,23 @@ this.init(); } + function arraysAreEqual(array1, array2) { + if ( array1.length != array2.length ){ + return false; + } + + array1.sort(); + array2.sort(); + + for ( var i = 0; i < array1.length; i++ ){ + if ( array1[i] !== array2[i] ){ + return false; + } + } + + return true; + } + $.extend(Plugin.prototype, { init: function() { @@ -77,17 +97,40 @@ } }).on('click.multiselect', function(e) { _this.menuToggle(); - }); + }) + .appendTo(this.$container); this.$element.on('change.multiselect', function() { _this.updateButtonContents(); }); - this.$container.append(this.$button); - this.updateButtonContents(); }, + updateButtonContents: function() { + var _this = this; + var options = []; + var selected = []; + + this.$element.children('option').each(function() { + var text = $(this).text(); + options.push(text); + if ($(this).is(':selected')) { + selected.push( $.trim(text) ); + } + }); + + this.$button.empty(); + + if (selected.length == 0) { + this.$button.text( this.settings.noneText ); + } else if ( (selected.length === options.length) && this.settings.allText) { + this.$button.text( this.settings.allText ); + } else { + this.$button.text( selected.join(', ') ); + } + }, + constructMenu: function() { var _this = this; @@ -100,55 +143,91 @@ if (key === escapeKey) { _this.menuHide(); } - }); + }) + .appendTo(this.$container); - this.$menu.on('change.multiselect', function() { - _this.updateButtonContents(); - }); + this.constructMenuItems(); + + if ( this.settings.presets ) { + this.constructPresets(); + } + }, + + constructMenuItems: function() { + var _this = this; + + this.$menuItems = $(this.settings.menuItemsHTML); + this.$menu.append(this.$menuItems); this.$element.on('change.multiselect', function(e, internal) { - // Don't need to update the menu contents if this + // Don't need to update the menu items if this // change event was fired by our tickbox handler. if(internal !== true){ - _this.updateMenuContents(); + _this.updateMenuItems(); } }); - this.$container.append(this.$menu); - - this.updateMenuContents(); + this.updateMenuItems(); }, - setUpBodyClickListener: function() { + updateMenuItems: function() { var _this = this; + this.$menuItems.empty(); - // Hide the $menu when you click outside of it. - $('html').on('click.multiselect', function(){ - _this.menuHide(); - }); - - // Stop click events from inside the $button or $menu from - // bubbling up to the body and closing the menu! - this.$container.on('click.multiselect', function(e){ - e.stopPropagation(); + this.$element.children('option').each(function(option_index, option) { + var $item = _this.constructMenuItem($(option), option_index); + _this.$menuItems.append($item); }); }, - setUpLabelsClickListener: function() { + constructPresets: function() { var _this = this; - this.$labels.on('click.multiselect', function(e) { - e.preventDefault(); - e.stopPropagation(); - _this.menuToggle(); + this.$presets = $(this.settings.presetsHTML); + this.$menu.prepend(this.$presets); + + $.each(this.settings.presets, function(i, preset){ + var unique_id = _this.$element.attr('name') + '_preset_' + i; + var $item = $(_this.settings.menuItemHTML) + .attr({ + 'for': unique_id, + 'role': 'menuitem' + }) + .text(' ' + preset.name) + .appendTo(_this.$presets); + + var $input = $('<input>') + .attr({ + 'type': 'radio', + 'name': _this.$element.attr('name') + '_presets', + 'id': unique_id + }) + .prependTo($item); + + $input.on('change.multiselect', function(){ + _this.$element.val(preset.options); + _this.$element.trigger('change'); + }); + }); + + this.$element.on('change.multiselect', function() { + _this.updatePresets(); }); + + this.updatePresets(); }, - updateMenuContents: function() { + updatePresets: function() { var _this = this; - this.$menu.empty(); - this.$element.children('option').each(function(option_index, option) { - var $item = _this.constructMenuItem($(option), option_index); - _this.$menu.append($item); + + $.each(this.settings.presets, function(i, preset){ + var unique_id = _this.$element.attr('name') + '_preset_' + i; + var $input = _this.$presets.find('#' + unique_id); + + if ( arraysAreEqual(preset.options || [], _this.$element.val() || []) ){ + $input.prop('checked', true); + } else { + $input.prop('checked', false); + } }); }, @@ -166,7 +245,9 @@ 'type': 'checkbox', 'id': unique_id, 'value': $option.val() - }); + }) + .prependTo($item); + if ( $option.is(':disabled') ) { $input.attr('disabled', 'disabled'); } @@ -186,32 +267,31 @@ $option.trigger('change', [true]); }); - $item.prepend($input); return $item; }, - updateButtonContents: function() { + setUpBodyClickListener: function() { var _this = this; - var options = []; - var selected = []; - this.$element.children('option').each(function() { - var text = $(this).text(); - options.push(text); - if ($(this).is(':selected')) { - selected.push( $.trim(text) ); - } + // Hide the $menu when you click outside of it. + $('html').on('click.multiselect', function(){ + _this.menuHide(); }); - this.$button.empty(); + // Stop click events from inside the $button or $menu from + // bubbling up to the body and closing the menu! + this.$container.on('click.multiselect', function(e){ + e.stopPropagation(); + }); + }, - if (selected.length == 0) { - this.$button.text( this.settings.noneText ); - } else if ( (selected.length === options.length) && this.settings.allText) { - this.$button.text( this.settings.allText ); - } else { - this.$button.text( selected.join(', ') ); - } + setUpLabelsClickListener: function() { + var _this = this; + this.$labels.on('click.multiselect', function(e) { + e.preventDefault(); + e.stopPropagation(); + _this.menuToggle(); + }); }, menuShow: function() { |