Commit 34a95532 authored by catch's avatar catch

Issue #1636992 by nod_, Wim Leers: Form.js' formUpdated event is unreliable/incomplete.

parent b1128351
(function ($) {
(function ($, Drupal, debounce) {
"use strict";
......@@ -116,6 +116,82 @@ Drupal.behaviors.formSingleSubmit = {
}
};
/**
* Sends a 'formUpdated' event each time a form element is modified.
*/
function triggerFormUpdated (element) {
$(element).trigger('formUpdated');
}
/**
* Collects the IDs of all form fields in the given form.
*
* @param {HTMLFormElement} form
* @return {Array}
*/
function fieldsList (form) {
var $fieldList = $(form).find('[name]').map(function (index, element) {
// We use id to avoid name duplicates on radio fields and filter out
// elements with a name but no id.
return element.getAttribute('id');
});
// Return a true array.
return $.makeArray($fieldList);
}
/**
* Triggers the 'formUpdated' event on form elements when they are modified.
*/
Drupal.behaviors.formUpdated = {
attach: function (context) {
var $context = $(context);
var contextIsForm = $context.is('form');
var $forms = $context.find('form').once('form-updated');
if (contextIsForm) {
$forms = $context;
}
if ($forms.length) {
// Initialize form behaviors, use $.makeArray to be able to use native
// forEach array method and have the callback parameters in the right order.
$.makeArray($forms).forEach(function (form) {
var events = 'change.formUpdated keypress.formUpdated';
var eventHandler = debounce(function (event) { triggerFormUpdated(event.target); }, 300);
var formFields = fieldsList(form).join(',');
form.setAttribute('data-drupal-form-fields', formFields);
$(form).on(events, eventHandler);
});
}
// On ajax requests context is the form element.
if (contextIsForm) {
var formFields = fieldsList(context).join(',');
// @todo replace with form.getAttribute() when #1979468 is in.
var currentFields = $(context).attr('data-drupal-form-fields');
// if there has been a change in the fields or their order, trigger
// formUpdated.
if (formFields !== currentFields) {
triggerFormUpdated(context);
}
}
},
detach: function (context, settings, trigger) {
var $context = $(context);
if (trigger === 'unload') {
var $forms = $context.find('form').removeOnce('form-updated');
if ($forms.length) {
$.makeArray($forms).forEach(function (form) {
form.removeAttribute('data-drupal-form-fields');
$(form).off('.formUpdated');
});
}
}
}
};
/**
* Prepopulate form fields with information from the visitor cookie.
*/
......@@ -136,4 +212,4 @@ Drupal.behaviors.fillUserInfoFromCookie = {
}
};
})(jQuery);
})(jQuery, Drupal, Drupal.debounce);
......@@ -12,15 +12,22 @@
*/
Drupal.behaviors.filterGuidelines = {
attach: function (context) {
function updateFilterGuidelines (event) {
var $this = $(event.target);
var value = $this.val();
$this.closest('.filter-wrapper')
.find('.filter-guidelines-item').hide()
.filter('.filter-guidelines-' + value).show();
}
$(context).find('.filter-guidelines').once('filter-guidelines')
.find(':header').hide()
.closest('.filter-wrapper').find('select.filter-list')
.on('change', function () {
$(this).closest('.filter-wrapper')
.find('.filter-guidelines-item').hide()
.filter('.filter-guidelines-' + this.value).show();
})
.trigger('change');
.on('change.filterGuidelines', updateFilterGuidelines)
// Need to trigger the namespaced event to avoid triggering formUpdated
// when initializing the select.
.trigger('change.filterGuidelines');
}
};
......
......@@ -959,6 +959,7 @@ function system_library_info() {
'dependencies' => array(
array('system', 'jquery'),
array('system', 'drupal'),
array('system', 'drupal.debounce'),
array('system', 'jquery.cookie'),
array('system', 'jquery.once'),
),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment