diff --git a/hypha/apply/dashboard/static/js/django_select2-checkboxes.js b/hypha/apply/dashboard/static/js/django_select2-checkboxes.js index a024d320e07b3437ce0572680ab76b26f97c5dc9..c6b0a68f4971ec59c00dee173406a21218d01bab 100644 --- a/hypha/apply/dashboard/static/js/django_select2-checkboxes.js +++ b/hypha/apply/dashboard/static/js/django_select2-checkboxes.js @@ -1,23 +1,31 @@ -(function ($) { - var init = function ($element) { - options = { - placeholder: $element.data('placeholder'), - templateSelection: function(selected, total) { - let filterType = this.placeholder; - if ( !selected.length ) { - return filterType; - } else if ( selected.length===total ) { - return 'All ' + filterType + ' selected'; - } - return selected.length + ' of ' + total + ' ' + filterType + ' selected'; - } - }; - $element.select2MultiCheckboxes(options); - }; - $(function () { +(function($) { + $.fn.select2.amd.require( + [ + 'select2/multi-checkboxes/selection', + 'select2/multi-checkboxes/results' + ], + function(SelectionAdapter, ResultsAdapter) { + + $(function () { $('.django-select2-checkboxes').each(function (i, element) { - var $element = $(element); - init($element); + var $element = $(element); + $element.select2({ + placeholder: $element.data('placeholder'), + closeOnSelect: false, + templateSelection: function(data) { + let filterType = $element.data('placeholder'); + + if (!data.selected.length) { + return filterType + } else if (data.selected.length == data.all.length) { + return 'All ' + filterType + ' selected'; + } + return data.selected.length + ' of ' + data.all.length + ' ' + filterType + ' selected'; + }, + selectionAdapter: SelectionAdapter, + returnesultsAdapter: ResultsAdapter + }); }); + }); }); -}(this.jQuery)); +}(this.jQuery)); \ No newline at end of file diff --git a/hypha/apply/dashboard/static/js/select2.multi-checkboxes.js b/hypha/apply/dashboard/static/js/select2.multi-checkboxes.js index ec6182afb5654175c7aeb51643c9329943f315fc..815268be46a8d18945b295f22fbac4c39da6cf2a 100644 --- a/hypha/apply/dashboard/static/js/select2.multi-checkboxes.js +++ b/hypha/apply/dashboard/static/js/select2.multi-checkboxes.js @@ -3,77 +3,124 @@ * - allow to select multi values via normal dropdown control * * author : wasikuss - * repo : https://github.com/wasikuss/select2-multi-checkboxes + * repo : https://github.com/wasikuss/select2-multi-checkboxes/tree/amd * inspired by : https://github.com/select2/select2/issues/411 * License : MIT */ -(function($) { - var S2MultiCheckboxes = function(options, element) { - var self = this; - self.options = options; - self.$element = $(element); - var values = self.$element.val(); - self.$element.removeAttr('multiple'); - self.select2 = self.$element.select2({ - allowClear: true, - minimumResultsForSearch: options.minimumResultsForSearch, - placeholder: options.placeholder, - closeOnSelect: false, - templateSelection: function() { - return self.options.templateSelection(self.$element.val() || [], $('option', self.$element).length); - }, - templateResult: function(result) { - if (result.loading !== undefined) - return result.text; - return $('<div>').text(result.text).addClass(self.options.wrapClass); - }, - matcher: function(params, data) { - var original_matcher = $.fn.select2.defaults.defaults.matcher; - var result = original_matcher(params, data); - if (result && self.options.searchMatchOptGroups && data.children && result.children && data.children.length != result.children.length) { - result.children = data.children; - } - return result; - } - }).data('select2'); - self.select2.$results.off("mouseup").on("mouseup", ".select2-results__option[aria-selected]", (function(self) { - return function(evt) { - var $this = $(this); - - var data = $this.data('data'); - - if ($this.attr('aria-selected') === 'true') { - self.trigger('unselect', { - originalEvent: evt, - data: data - }); - return; - } - - self.trigger('select', { - originalEvent: evt, - data: data - }); - } - })(self.select2)); - self.$element.attr('multiple', 'multiple').val(values).trigger('change.select2'); + +/* global define jQuery */ +(function(factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else { + // Browser globals + factory(jQuery); + } +}(function(jQuery) { + if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) { + define = jQuery.fn.select2.amd.define; } + var define; - $.fn.extend({ - select2MultiCheckboxes: function() { - var options = $.extend({ - placeholder: 'Choose elements', - templateSelection: function(selected, total) { - return selected.length + ' > ' + total + ' total'; - }, - wrapClass: 'wrap', - minimumResultsForSearch: -1, - searchMatchOptGroups: true - }, arguments[0]); - - this.each(function() { - new S2MultiCheckboxes(options, this); - }); + /* global define */ + define('select2/multi-checkboxes/dropdown', [ + 'select2/utils', + 'select2/dropdown', + 'select2/dropdown/search', + 'select2/dropdown/attachBody' + ], + function(Utils, Dropdown, DropdownSearch, AttachBody) { + return Utils.Decorate( + Utils.Decorate( + Dropdown, + DropdownSearch + ), + AttachBody + ); + }); + + + /* global define */ + define('select2/multi-checkboxes/results', [ + 'jquery', + 'select2/utils', + 'select2/results' + ], + function($, Utils, _Results) { + function Results() { + Results.__super__.constructor.apply(this, arguments); } + Utils.Extend(Results, _Results); + + Results.prototype.highlightFirstItem = function() { + this.ensureHighlightVisible(); + }; + + Results.prototype.bind = function(container) { + container.on('open', function() { + var $options = this.$results.find('.select2-results__option[aria-selected]'); + var $selected = $options.filter('[aria-selected=true]'); + var $optionToScrollTo = ($selected.length > 0 ? $selected : $selected).first(); + $optionToScrollTo.trigger('mouseenter'); + }); + Results.__super__.bind.apply(this, arguments); + }; + + Results.prototype.template = function(result, container) { + var template = this.options.get('templateResult'); + var escapeMarkup = this.options.get('escapeMarkup'); + + var content = template(result, container); + $(container).addClass('multi-checkboxes_wrap'); + + if (content == null) { + container.style.display = 'none'; + } else if (typeof content === 'string') { + container.innerHTML = escapeMarkup(content); + } else { + $(container).append(content); + } + }; + + return Results; + }); + + + /* global define */ + define('select2/multi-checkboxes/selection', [ + 'select2/utils', + 'select2/selection/multiple', + 'select2/selection/placeholder', + 'select2/selection/single', + 'select2/selection/eventRelay' + ], + function(Utils, MultipleSelection, Placeholder, SingleSelection, EventRelay) { + var adapter = Utils.Decorate(MultipleSelection, Placeholder); + adapter = Utils.Decorate(adapter, EventRelay); + + adapter.prototype.render = function() { + return SingleSelection.prototype.render.call(this); + }; + + adapter.prototype.update = function(data) { + var $rendered = this.$selection.find('.select2-selection__rendered'); + var formatted = ''; + + if (data.length === 0) { + formatted = this.options.get('placeholder') || ''; + } else { + var itemsData = { + selected: data || [], + all: this.$element.find('option') || [] + }; + formatted = this.display(itemsData, $rendered); + } + + $rendered.empty().append(formatted); + $rendered.prop('title', formatted); + }; + + return adapter; }); -})(jQuery); +}) +); diff --git a/hypha/static_src/src/sass/apply/components/_select2.scss b/hypha/static_src/src/sass/apply/components/_select2.scss index dff4cdb83d084a81fd0bb1c4f5c18685167da01c..024fda44cd97191d2fd68755a487f7a68792a76c 100644 --- a/hypha/static_src/src/sass/apply/components/_select2.scss +++ b/hypha/static_src/src/sass/apply/components/_select2.scss @@ -68,30 +68,24 @@ $dropdown-height: 45px; } .select2-results__option { - padding: 0; - - &[aria-selected='true'] { - .wrap { - &::before { - background: url('./../../images/tick.svg') $color--dark-blue center no-repeat; - background-size: 12px; - border: 1px solid $color--dark-blue; - content: ''; - } - } + display: flex; + align-items: center; + padding: 6px; + + &::before { + min-width: 20px; + height: 20px; + margin-right: 10px; + background: $color--white; + border: 1px solid $color--mid-grey; + content: ''; } - .wrap { - display: flex; - align-items: center; - padding: 6px; - + &[aria-selected='true'] { &::before { - min-width: 20px; - height: 20px; - margin-right: 10px; - background: $color--white; - border: 1px solid $color--mid-grey; + background: url('./../../images/tick.svg') $color--dark-blue center no-repeat; + background-size: 12px; + border: 1px solid $color--dark-blue; content: ''; } } diff --git a/hypha/static_src/src/sass/public/components/_select2.scss b/hypha/static_src/src/sass/public/components/_select2.scss index 54147955936b9ec77cc96fd6bab97db832395664..024fda44cd97191d2fd68755a487f7a68792a76c 100644 --- a/hypha/static_src/src/sass/public/components/_select2.scss +++ b/hypha/static_src/src/sass/public/components/_select2.scss @@ -1,3 +1,5 @@ +$dropdown-height: 45px; + .select2 { &-container { z-index: 99995; // to override any modals @@ -8,7 +10,7 @@ width: 100% !important; // sass-lint:disable-line no-important .select2-selection--single { - height: 55px; + height: $dropdown-height; border: 1px solid $color--mid-grey; border-radius: 0; @@ -18,27 +20,22 @@ } .select2-selection__clear { - position: absolute; - right: 35px; display: none; - float: none; - - @include media-query(small-tablet) { - display: block; - } } .select2-selection__rendered { padding-left: 15px; - line-height: 55px; + padding-right: 30px; + line-height: $dropdown-height; } .select2-selection__arrow { right: 15px; - height: 53px; + height: $dropdown-height; pointer-events: none; background: url('./../../images/dropdown.svg') transparent no-repeat 95% center; background-size: 8px; + width: 8px; b[role='presentation'] { display: none; @@ -71,30 +68,24 @@ } .select2-results__option { - padding: 0; - - &[aria-selected='true'] { - .wrap { - &::before { - background: url('./../../images/tick.svg') $color--dark-blue center no-repeat; - background-size: 12px; - border: 1px solid $color--dark-blue; - content: ''; - } - } + display: flex; + align-items: center; + padding: 6px; + + &::before { + min-width: 20px; + height: 20px; + margin-right: 10px; + background: $color--white; + border: 1px solid $color--mid-grey; + content: ''; } - .wrap { - display: flex; - align-items: center; - padding: 6px; - + &[aria-selected='true'] { &::before { - width: 20px; - height: 20px; - margin-right: 10px; - background: $color--white; - border: 1px solid $color--mid-grey; + background: url('./../../images/tick.svg') $color--dark-blue center no-repeat; + background-size: 12px; + border: 1px solid $color--dark-blue; content: ''; } } diff --git a/requirements.txt b/requirements.txt index 17af6dd3ebb694b7c21a4cbfe963a6f9f3e04fde..7344c3046ef41eb1fe115efd98ad69ec1653cd65 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,7 +25,7 @@ django-tables2==1.21.2 django-tinymce4-lite==1.7.5 django-two-factor-auth==1.9.1 django-webpack-loader==0.6.0 -django_select2==7.1.1 +django_select2==7.2.2 djangorestframework==3.9.2 djangorestframework-api-key==1.4.1 django==2.2.11