From 30d7c96d2bdc8cd23d9e9785e41aa56c238cc7a1 Mon Sep 17 00:00:00 2001 From: Aaron Contreras Date: Thu, 8 Aug 2024 15:54:33 -0500 Subject: [PATCH] Auto-register event listeners at the stimulus controller level This makes sure that the DOM can remain agnostic of this behavior of auto-submitting and we can rely on the Stimulus controller taking care of most of this logic which in the end, pretty much relies on that end of the spectrum. --- app/views/filters/_autocomplete.html.erb | 8 ++- .../dynamic/filter/filters-form.controller.ts | 54 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/app/views/filters/_autocomplete.html.erb b/app/views/filters/_autocomplete.html.erb index c33e527e4d3c..e10bec695b7b 100644 --- a/app/views/filters/_autocomplete.html.erb +++ b/app/views/filters/_autocomplete.html.erb @@ -4,7 +4,13 @@ inputName: 'value', multiple: true, multipleAsSeparateInputs: false, - inputValue: filter.values + inputValue: filter.values, + hiddenFieldAction: "change->filter--filters-form#sendForm" + # Set on the template as there is a timing issue where the + # angular component is not yet ready in the DOM and hence + # the action can't be registered on the input field at the time + # of the #connect lifecycle hook of the filter--filters-form + # Stimulus controller. }.merge(autocomplete_options.except(:component)), class: 'form--field', data: { diff --git a/frontend/src/stimulus/controllers/dynamic/filter/filters-form.controller.ts b/frontend/src/stimulus/controllers/dynamic/filter/filters-form.controller.ts index 4339650433ef..23c7ae1e68d4 100644 --- a/frontend/src/stimulus/controllers/dynamic/filter/filters-form.controller.ts +++ b/frontend/src/stimulus/controllers/dynamic/filter/filters-form.controller.ts @@ -78,6 +78,56 @@ export default class FiltersFormController extends Controller { connect() { const urlParams = new URLSearchParams(window.location.search); this.displayFiltersValue = urlParams.has('filters'); + + this.simpleValueTargets.forEach((simpleValue) => { + simpleValue.addEventListener('change', this.sendForm.bind(this)); + }); + + this.operatorTargets.forEach((operator) => { + operator.addEventListener('change', this.sendForm.bind(this)); + }); + + this.filterValueSelectTargets.forEach((select) => { + select.addEventListener('change', this.sendForm.bind(this)); + }); + + this.filterValueContainerTargets.forEach((container) => { + container.addEventListener('change', this.sendForm.bind(this)); + }); + + this.singleDayTargets.forEach((singleDay) => { + singleDay.addEventListener('change', this.sendForm.bind(this)); + }); + + this.daysTargets.forEach((days) => { + days.addEventListener('change', this.sendForm.bind(this)); + }); + } + + disconnect() { + this.simpleValueTargets.forEach((simpleValue) => { + simpleValue.removeEventListener('change', this.sendForm.bind(this)); + }); + + this.operatorTargets.forEach((operator) => { + operator.removeEventListener('change', this.sendForm.bind(this)); + }); + + this.filterValueSelectTargets.forEach((select) => { + select.removeEventListener('change', this.sendForm.bind(this)); + }); + + this.filterValueContainerTargets.forEach((container) => { + container.removeEventListener('change', this.sendForm.bind(this)); + }); + + this.singleDayTargets.forEach((singleDay) => { + singleDay.removeEventListener('change', this.sendForm.bind(this)); + }); + + this.daysTargets.forEach((days) => { + days.removeEventListener('change', this.sendForm.bind(this)); + }); } toggleDisplayFilters() { @@ -136,6 +186,8 @@ export default class FiltersFormController extends Controller { this.disableSelection(); this.reselectPlaceholderOption(); this.setSpacerVisibility(); + + this.sendForm(); } private disableSelection() { @@ -154,6 +206,8 @@ export default class FiltersFormController extends Controller { const removedFilterOption = selectOptions.find((option) => option.value === filterName); removedFilterOption?.removeAttribute('disabled'); this.setSpacerVisibility(); + + this.sendForm(); } private setSpacerVisibility() {