diff options
author | Matthew Somerville <matthew-github@dracos.co.uk> | 2016-10-25 16:33:52 +0100 |
---|---|---|
committer | Matthew Somerville <matthew-github@dracos.co.uk> | 2016-10-25 16:33:52 +0100 |
commit | eb4e1f1f98c3bfba73d12e192c4c6d5f9fb71710 (patch) | |
tree | 1f0b66b1c7b0c2fa878fc84c8fede174acd44d21 | |
parent | 2e8c2dcdb299e1c34e0c64120ad2b513ec980491 (diff) | |
parent | 79781cd7ac6e3dbbd323f1d2675bb2bbdcac0ef5 (diff) |
Merge branch 'issues/forcouncils/115-multi-select-clear'
-rw-r--r-- | templates/web/base/reports/_list-filters.html | 12 | ||||
-rw-r--r-- | web/cobrands/fixmystreet/fixmystreet.js | 6 | ||||
-rw-r--r-- | web/cobrands/sass/_multiselect.scss | 19 | ||||
-rw-r--r-- | web/js/jquery.multi-select.js | 182 |
4 files changed, 155 insertions, 64 deletions
diff --git a/templates/web/base/reports/_list-filters.html b/templates/web/base/reports/_list-filters.html index f4fbab042..cda5a3dc2 100644 --- a/templates/web/base/reports/_list-filters.html +++ b/templates/web/base/reports/_list-filters.html @@ -1,14 +1,14 @@ [% select_status = BLOCK %] - <select class="form-control" name="status" id="statuses" multiple data-all="[% loc('all reports') %]"> - <option value="open"[% ' selected' IF filter_status.open %]>[% loc('unfixed reports') %]</option> - <option value="closed"[% ' selected' IF filter_status.closed %]>[% loc('closed reports') %]</option> - <option value="fixed"[% ' selected' IF filter_status.fixed %]>[% loc('fixed reports') %]</option> + <select class="form-control" name="status" id="statuses" multiple data-all="[% loc('All reports') %]"> + <option value="open"[% ' selected' IF filter_status.open %]>[% loc('Unfixed reports') %]</option> + <option value="closed"[% ' selected' IF filter_status.closed %]>[% loc('Closed reports') %]</option> + <option value="fixed"[% ' selected' IF filter_status.fixed %]>[% loc('Fixed reports') %]</option> </select> [% END %] [% select_category = BLOCK %] [% IF filter_categories.size %] - <select class="form-control" name="filter_category" id="filter_categories" multiple data-all="[% loc('everything') %]"> + <select class="form-control" name="filter_category" id="filter_categories" multiple data-all="[% loc('Everything') %]"> [% FOR cat IN filter_categories %] <option value="[% cat | html %]"[% ' selected' IF filter_category.grep(cat).size %]> [% cat | html %] @@ -16,7 +16,7 @@ [% END %] </select> [% ELSE %] - [% loc('everything') %] + [% loc('Everything') %] [% END %] [% END %] diff --git a/web/cobrands/fixmystreet/fixmystreet.js b/web/cobrands/fixmystreet/fixmystreet.js index 53954f57a..9000d34e7 100644 --- a/web/cobrands/fixmystreet/fixmystreet.js +++ b/web/cobrands/fixmystreet/fixmystreet.js @@ -585,7 +585,11 @@ $.extend(fixmystreet.set_up, { $id.multiSelect({ allText: all, noneText: all, - positionMenuWithin: $('#side') + positionMenuWithin: $('#side'), + presets: [{ + name: all, + options: [] + }] }); } make_multi('statuses'); diff --git a/web/cobrands/sass/_multiselect.scss b/web/cobrands/sass/_multiselect.scss index 6760b2282..5ee15ead8 100644 --- a/web/cobrands/sass/_multiselect.scss +++ b/web/cobrands/sass/_multiselect.scss @@ -11,16 +11,19 @@ min-width: 100%; background: #fff; margin: 1em 0; - padding: 0.4em 0; border: 1px solid #aaa; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); display: none; +} - label { - display: block; - font-size: 0.875em; - padding: 0.3em 1em 0.3em 30px; - white-space: nowrap; +.multi-select-menuitem { + display: block; + font-size: 0.875em; + padding: 0.6em 1em 0.6em 30px; + white-space: nowrap; + + & + & { + padding-top: 0; } input { @@ -30,6 +33,10 @@ } } +.multi-select-presets { + border-bottom: 1px solid #ddd; +} + .multi-select-button { display: inline-block; font-size: 0.875em; 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() { |