diff --git a/hypha/apply/categories/blocks.py b/hypha/apply/categories/blocks.py index 0b053b04f3..f4f041e9f5 100644 --- a/hypha/apply/categories/blocks.py +++ b/hypha/apply/categories/blocks.py @@ -1,7 +1,6 @@ from django import forms from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ -from django_select2.forms import Select2MultipleWidget from wagtail.blocks import BooleanBlock, CharBlock, ChoiceBlock, TextBlock from wagtail.coreutils import resolve_model_string @@ -73,7 +72,9 @@ def get_widget(self, struct_value): if category_size < 32: return forms.CheckboxSelectMultiple else: - return Select2MultipleWidget + from hypha.apply.funds.tables import MultiCheckboxesWidget + + return MultiCheckboxesWidget else: return forms.RadioSelect diff --git a/hypha/apply/dashboard/static/js/django_select2-checkboxes.js b/hypha/apply/dashboard/static/js/django_select2-checkboxes.js deleted file mode 100644 index 376d189207..0000000000 --- a/hypha/apply/dashboard/static/js/django_select2-checkboxes.js +++ /dev/null @@ -1,34 +0,0 @@ -(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); - $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 - ); - }, - selectionAdapter: SelectionAdapter, - returnesultsAdapter: ResultsAdapter, - }); - }); - }); - } - ); -})(this.jQuery); diff --git a/hypha/apply/dashboard/static/js/select2.multi-checkboxes.js b/hypha/apply/dashboard/static/js/select2.multi-checkboxes.js deleted file mode 100644 index 6821ab8b30..0000000000 --- a/hypha/apply/dashboard/static/js/select2.multi-checkboxes.js +++ /dev/null @@ -1,124 +0,0 @@ -/** - * jQuery Select2 Multi checkboxes - * - allow to select multi values via normal dropdown control - * - * author : wasikuss - * repo : https://github.com/wasikuss/select2-multi-checkboxes/tree/amd - * inspired by : https://github.com/select2/select2/issues/411 - * License : MIT - */ - -/* 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; - - /* 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; - }); -}); diff --git a/hypha/apply/funds/forms.py b/hypha/apply/funds/forms.py index cdfc781206..3e3bf483cd 100644 --- a/hypha/apply/funds/forms.py +++ b/hypha/apply/funds/forms.py @@ -21,7 +21,7 @@ ) from .permissions import can_change_external_reviewers from .utils import model_form_initial, render_icon -from .widgets import MetaTermSelect2Widget, Select2MultiCheckboxesWidget +from .widgets import MetaTermWidget, MultiCheckboxesWidget class ApplicationSubmissionModelForm(forms.ModelForm): @@ -234,7 +234,7 @@ class BatchUpdateReviewersForm(forms.Form): ) external_reviewers = forms.ModelMultipleChoiceField( queryset=User.objects.reviewers().only("pk", "full_name"), - widget=Select2MultiCheckboxesWidget(attrs={"data-placeholder": "Select..."}), + widget=MultiCheckboxesWidget(attrs={"data-placeholder": "Select..."}), label=_("External Reviewers"), required=False, ) @@ -398,7 +398,9 @@ def label_from_instance(self, obj): class UpdateMetaTermsForm(ApplicationSubmissionModelForm): meta_terms = GroupedModelMultipleChoiceField( queryset=None, # updated in init method - widget=MetaTermSelect2Widget(attrs={"data-placeholder": "Select..."}), + widget=MetaTermWidget( + attrs={"data-placeholder": "Select...", "data-js-choices": ""} + ), label=_("Meta terms"), choices_groupby="get_parent", required=False, diff --git a/hypha/apply/funds/tables.py b/hypha/apply/funds/tables.py index 8e14f452d8..21da0286ba 100644 --- a/hypha/apply/funds/tables.py +++ b/hypha/apply/funds/tables.py @@ -22,7 +22,7 @@ from hypha.images.models import CustomImage from .models import ApplicationSubmission, Round, ScreeningStatus -from .widgets import Select2MultiCheckboxesWidget +from .widgets import MultiCheckboxesWidget from .workflows import STATUSES, get_review_active_statuses User = get_user_model() @@ -290,28 +290,26 @@ def get_meta_terms_from_dataset(dataset): ).distinct() -class Select2CheckboxWidgetMixin(filters.Filter): +class MultiCheckboxesMixin(filters.Filter): def __init__(self, *args, **kwargs): label = kwargs.get("label") kwargs.setdefault( - "widget", Select2MultiCheckboxesWidget(attrs={"data-placeholder": label}) + "widget", MultiCheckboxesWidget(attrs={"data-placeholder": label}) ) super().__init__(*args, **kwargs) -class Select2MultipleChoiceFilter( - Select2CheckboxWidgetMixin, filters.MultipleChoiceFilter -): +class MultipleChoiceFilter(MultiCheckboxesMixin, filters.MultipleChoiceFilter): pass -class Select2ModelMultipleChoiceFilter( - Select2MultipleChoiceFilter, filters.ModelMultipleChoiceFilter +class ModelMultipleChoiceFilter( + MultipleChoiceFilter, filters.ModelMultipleChoiceFilter ): pass -class StatusMultipleChoiceFilter(Select2MultipleChoiceFilter): +class StatusMultipleChoiceFilter(MultipleChoiceFilter): def __init__(self, limit_to, *args, **kwargs): choices = [ (slugify(name), name) @@ -337,25 +335,21 @@ def get_filter_predicate(self, v): class SubmissionFilter(filters.FilterSet): - fund = Select2ModelMultipleChoiceFilter( + fund = ModelMultipleChoiceFilter( field_name="page", queryset=get_used_funds, label=_("Funds") ) - round = Select2ModelMultipleChoiceFilter( - queryset=get_used_rounds, label=_("Rounds") - ) - lead = Select2ModelMultipleChoiceFilter(queryset=get_round_leads, label=_("Leads")) - screening_statuses = Select2ModelMultipleChoiceFilter( + round = ModelMultipleChoiceFilter(queryset=get_used_rounds, label=_("Rounds")) + lead = ModelMultipleChoiceFilter(queryset=get_round_leads, label=_("Leads")) + screening_statuses = ModelMultipleChoiceFilter( queryset=get_screening_statuses, label=_("Screening"), null_label=_("No Status") ) - reviewers = Select2ModelMultipleChoiceFilter( + reviewers = ModelMultipleChoiceFilter( queryset=get_all_reviewers, label=_("Reviewers") ) - category_options = Select2MultipleChoiceFilter( + category_options = MultipleChoiceFilter( choices=[], label=_("Category"), method="filter_category_options" ) - meta_terms = Select2ModelMultipleChoiceFilter( - queryset=get_meta_terms, label=_("Terms") - ) + meta_terms = ModelMultipleChoiceFilter(queryset=get_meta_terms, label=_("Terms")) class Meta: model = ApplicationSubmission @@ -455,10 +449,8 @@ def filter_archived(self, queryset, name, value): class SubmissionDashboardFilter(filters.FilterSet): - round = Select2ModelMultipleChoiceFilter( - queryset=get_used_rounds, label=_("Rounds") - ) - fund = Select2ModelMultipleChoiceFilter( + round = ModelMultipleChoiceFilter(queryset=get_used_rounds, label=_("Rounds")) + fund = ModelMultipleChoiceFilter( field_name="page", queryset=get_used_funds, label=_("Funds") ) @@ -528,7 +520,7 @@ def get_column_class_names(self, classes_set, bound_column): return classes_set -class ActiveRoundFilter(Select2MultipleChoiceFilter): +class ActiveRoundFilter(MultipleChoiceFilter): def __init__(self, *args, **kwargs): super().__init__( self, @@ -548,7 +540,7 @@ def filter(self, qs, value): return qs.inactive() -class OpenRoundFilter(Select2MultipleChoiceFilter): +class OpenRoundFilter(MultipleChoiceFilter): def __init__(self, *args, **kwargs): super().__init__( self, @@ -571,8 +563,8 @@ def filter(self, qs, value): class RoundsFilter(filters.FilterSet): - fund = Select2ModelMultipleChoiceFilter(queryset=get_used_funds, label=_("Funds")) - lead = Select2ModelMultipleChoiceFilter(queryset=get_round_leads, label=_("Leads")) + fund = ModelMultipleChoiceFilter(queryset=get_used_funds, label=_("Funds")) + lead = ModelMultipleChoiceFilter(queryset=get_round_leads, label=_("Leads")) active = ActiveRoundFilter(label=_("Active")) round_state = OpenRoundFilter(label=_("Open")) @@ -601,17 +593,17 @@ class ReviewerLeaderboardFilter(filters.FilterSet): field_name="full_name", lookup_expr="icontains", widget=forms.HiddenInput ) - reviewer = Select2ModelMultipleChoiceFilter( + reviewer = ModelMultipleChoiceFilter( field_name="pk", label=_("Reviewers"), queryset=get_all_reviewers, ) - funds = Select2ModelMultipleChoiceFilter( + funds = ModelMultipleChoiceFilter( field_name="applicationsubmission__page", label=_("Funds"), queryset=get_used_funds, ) - rounds = Select2ModelMultipleChoiceFilter( + rounds = ModelMultipleChoiceFilter( field_name="applicationsubmission__round", label=_("Rounds"), queryset=get_used_rounds, diff --git a/hypha/apply/funds/templates/funds/includes/table_filter_and_search.html b/hypha/apply/funds/templates/funds/includes/table_filter_and_search.html index a7e5ebfd25..73d50ee68a 100644 --- a/hypha/apply/funds/templates/funds/includes/table_filter_and_search.html +++ b/hypha/apply/funds/templates/funds/includes/table_filter_and_search.html @@ -97,7 +97,7 @@