Commit 502e953f authored by Dries's avatar Dries

Issue #1705618 by nod_, sun, clemens.tolboom, Wim Leers: Double click...

Issue #1705618 by nod_, sun, clemens.tolboom, Wim Leers: Double click prevention on form submission.
parent 634e3a3f
......@@ -59,6 +59,63 @@ Drupal.behaviors.formUpdated = {
}
};
/**
* 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 to 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')
.on('submit.singleSubmit', 'form:not([method~="GET"])', onFormSubmit);
}
};
/**
* Prepopulate form fields with information from the visitor cookie.
*/
......
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