mirror of
https://github.com/tag1consulting/d7_to_d10_migration.git
synced 2024-11-10 02:33:25 +00:00
61 lines
2.6 KiB
JavaScript
61 lines
2.6 KiB
JavaScript
|
(function ($) {
|
||
|
|
||
|
/**
|
||
|
* Prevents consecutive form submissions of identical form values.
|
||
|
*
|
||
|
* Repetitive form submissions that would submit the identical form values are
|
||
|
* prevented, unless the form values are different from the previously
|
||
|
* submitted values.
|
||
|
*
|
||
|
* This is a simplified re-implementation of a user-agent behavior that should
|
||
|
* be natively supported by major web browsers, but at this time, only Firefox
|
||
|
* has a built-in protection.
|
||
|
*
|
||
|
* A form value-based approach ensures that the constraint is triggered for
|
||
|
* consecutive, identical form submissions only. Compared to that, a form
|
||
|
* button-based approach would (1) rely on [visible] buttons to exist where
|
||
|
* technically not required and (2) require more complex state management if
|
||
|
* there are multiple buttons in a form.
|
||
|
*
|
||
|
* This implementation is based on form-level submit events only and relies on
|
||
|
* jQuery's serialize() method to determine submitted form values. As such, the
|
||
|
* following limitations exist:
|
||
|
*
|
||
|
* - Event handlers on form buttons that preventDefault() do not receive a
|
||
|
* double-submit protection. That is deemed to be fine, since such button
|
||
|
* events typically trigger reversible client-side or server-side operations
|
||
|
* that are local to the context of a form only.
|
||
|
* - Changed values in advanced form controls, such as file inputs, are not part
|
||
|
* of the form values being compared between consecutive form submits (due to
|
||
|
* limitations of jQuery.serialize()). That is deemed to be acceptable,
|
||
|
* because if the user forgot to attach a file, then the size of HTTP payload
|
||
|
* will most likely be small enough to be fully passed to the server endpoint
|
||
|
* within (milli)seconds. If a user mistakenly attached a wrong file and is
|
||
|
* technically versed enough to cancel the form submission (and HTTP payload)
|
||
|
* in order to attach a different file, then that edge-case is not supported
|
||
|
* here.
|
||
|
*
|
||
|
* Lastly, all forms submitted via HTTP GET are idempotent by definition of HTTP
|
||
|
* standards, so excluded in this implementation.
|
||
|
*/
|
||
|
Drupal.behaviors.formSingleSubmit = {
|
||
|
attach: function () {
|
||
|
function onFormSubmit (e) {
|
||
|
var $form = $(e.currentTarget);
|
||
|
var formValues = $form.serialize();
|
||
|
var previousValues = $form.attr('data-drupal-form-submit-last');
|
||
|
if (previousValues === formValues) {
|
||
|
e.preventDefault();
|
||
|
}
|
||
|
else {
|
||
|
$form.attr('data-drupal-form-submit-last', formValues);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$('body').once('form-single-submit')
|
||
|
.delegate('form:not([method~="GET"])', 'submit.singleSubmit', onFormSubmit);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
})(jQuery);
|