Topic: Is there a generic way to execute JavaScript when the user changes the value of any component in a form?

ikan_nak priority asked 1 week ago


I have a search form that can contain anywhere from 3 to almost 30 components, and which should execute an asynchronous server side search operation when one of the components has the value updated. These components can be text fields, single value selects, inputs with an autocomplete, datetimepickers or multivalue selects.

I'm trying to figure out a way to generically attach eventListeners to each of the right events for each of these components, but I'm struggling. I've found from an earlier question that not all of these components trigger the "change" event of the form, and that some of these components trigger a specific valueChanged or other event. But if I read the documentation correctly, this valueChanged event has a different signature for each component type, and on top of that each component type has a different way to get a specific instance of that component.

This makes development more complicated because while I can define a list of components as a dataset property of my form and iterate over them to add the eventListener to the right event, I'd have to add an additional property to my list of components to determine whether I need to do a getInstance, and what module I need to call that getInstance for.

So I'm wondering: is there a component-agnostic way to execute this javascript, either by doing a getInstance on a different module that works regardless of component type I'm trying to get the Instance of, or by listening to a different event that always triggers regardless of what component has the value updated?

var searchForms = document.querySelectorAll(".js-kobee-search-form");
searchForms.forEach(initSearch);

function initSearch(/** DomNode */ searchForm) {
    var formComponents = JSON.parse(searchForm.dataset.kobeeFormComponents);
    formComponents.forEach((component) => {
        searchForm.querySelector(component.selector).addEventListener(component.eventHandler, execSearch);
    });
    searchForm.addEventListener('reset', resetSearch);
    searchForm.addEventListener('submit', formSubmit);
    search(searchForm);
}

Kamila Pieńkowska staff answered 1 week ago


Unfortunately, there is no shortcut here.

From form inputs values you can be accesed/changed without accessing instance. Datepicker, Timepicke, Autocomplete and Select require adding listeners to their specific events, but if you only need to access those values you don't need to access instance. Value will be in the information about trigger event for most (beside timepicker). Alternatively you can access value of the event.target.

If you need to change values for pickers method depends on the component.


ikan_nak priority commented 1 week ago

I don't need to access the values of specific inputs. The current implementation basically just does a fetch with body: new FormData(event.target.form). I just need a way to listen to the trigger events that gets triggered by each relevant component.


Kamila Pieńkowska staff commented 1 week ago

There isn't a simple shortcut for this. You need to add listeners for specific events for each type of picker to catch selections made via the picker. Additionally, you need to listen for the input event to catch any input in regular input fields and pickers if the user types in the value directly, without using the picker.



Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue

  • ForumUser: Priority
  • Premium support: Yes
  • Technology: MDB Standard
  • MDB Version: MDB5 7.3.0
  • Device: Desktop computer
  • Browser: Edge
  • OS: Windows 11
  • Provided sample code: No
  • Provided link: No