My heart is bleeding each time a developer starts working with Drupal and adds code to a Drupal site that doesn't take advantage of its features.
When using JavaScript with Drupal, please ALWAYS familiarize yourself with the concept of libraries (to manage JavaScript dependencies and inclusion to your site), as well as the relatively simple but powerful Drupal JavaScript behaviors (and while you're at it, the once feature, as you'll very often use it as well).
In brief, a Drupal JavaScript behavior is a JavaScript object provided by your module or theme JavaScript that features an attach
and/or a detach
method. Attach is called whenever a page load completed. That is the initial page load, as well as after dynamically loading page content using AJAX requests. It receives a context parameter that holds the wrapper DOM element of the changed part.
That said, your JavaScript didn't fire for dynamically added content, because you didn't use Drupal behaviors and thus the change event handler won't be bound to dynamically added page content.
The "workaround" you posted in your own answer on the other hand will cause the updateValues
callback to fire on every change of a select element of your site. Regardless of whether it's part of your webform or not.
A solution that works better and conforms with the Drupal JavaScript API (for simplicity of code, I kept your jQuery dependency):
js/my-update-values.js:
(function (Drupal, $, once) {
'use strict';
Drupal.behaviors.myUpdateValues = {
attach: function (context) {
// Apply once to all required select elements within the
// current context.
once('myUpdateValues', 'select.form-select[required]', context)).forEach(function (element) {
var $element = $(element);
// Ensure the select element is part of the custom webform.
// A CSS class selector would be better here.
if ($element.closest('table[data-drupal-selector|="edit-product-list-items"]').length === 0) {
return;
}
// Bind the change handler.
$element.on('change.myUpdateValues', updateValues);
});
},
detach: function (context) {
// Process all required select elements of the detaching context
// that where previously processed by our attach function, and
// unbind the change handler.
$(once.remove('myUpdateValues', 'select.form-select[required]', context)).off('change.myUpdateValues');
}
};
function updateValues(event) {
// Your code here.
}
}(Drupal, jQuery, once));
This example depends on the Drupal 9.2+, jQuery and Drupal once libraries. So your library definition may look as such:
libraries.yml:
myUpdateValues:
js:
js/my-update-values.js: {}
dependencies:
- core/drupal
- core/jquery
- core/once
On older versions of Drupal, you may have to use jquery.once
instead.