[FIX] website: fix form submit button permanent loading

Before this commit, in some cases the submit button of the form snippet
never stopped loading after being clicked (e.g. redirect to an anchor in
the same page).

Now, the form and the button loading effect are reset at the same time
at the appropriate time depending on the post-send action:

- Redirect to another page: never (we leave the form values and the
  button loading effect for the whole redirection duration)

- Redirect to an anchor on the same page: after the scroll animation

- Show a custom HTML message: never (this type of post-send action is
  meant to hide the form after that message is shown, there is no need
  to restore it to its initial state)

- "Nothing" (= small message next to send button): once the data is sent

In the last two cases, a 400ms delay was also added before showing the
message so that the send flickers less and seems more smooth. In the
last case, it also prevents to double click and double send the form.

Related to task-2172312

closes odoo/odoo#81703

X-original-commit: 42f6887bb4406d4aa636040c8325e8ecab202778
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
qsm-odoo
2021-12-21 10:44:01 +00:00
parent e6d6961c75
commit 08a2dd9133
@@ -8,6 +8,7 @@ odoo.define('website.s_website_form', function (require) {
var ajax = require('web.ajax');
var publicWidget = require('web.public.widget');
const dom = require('web.dom');
const concurrency = require('web.concurrency');
var _t = core._t;
var qweb = core.qweb;
@@ -269,7 +270,7 @@ odoo.define('website.s_website_form', function (require) {
// Post form and handle result
ajax.post(this.$target.attr('action') + (this.$target.data('force_action') || this.$target.data('model_name')), form_values)
.then(function (result_data) {
.then(async function (result_data) {
// Restore send button behavior
self.$target.find('.s_website_form_send, .o_website_form_send')
.removeAttr('disabled')
@@ -291,28 +292,41 @@ odoo.define('website.s_website_form', function (require) {
successMode = successPage ? 'redirect' : 'nothing';
}
switch (successMode) {
case 'redirect':
case 'redirect': {
successPage = successPage.startsWith("/#") ? successPage.slice(1) : successPage;
if (successPage.charAt(0) === "#") {
dom.scrollTo($(successPage)[0], {
await dom.scrollTo($(successPage)[0], {
duration: 500,
extraOffset: 0,
});
} else {
$(window.location).attr('href', successPage);
break;
}
break;
case 'message':
$(window.location).attr('href', successPage);
return;
}
case 'message': {
// Prevent double-clicking on the send button and
// add a upload loading effect (delay before success
// message)
await concurrency.delay(dom.DEBOUNCE);
self.$target[0].classList.add('d-none');
self.$target[0].parentElement.querySelector('.s_website_form_end_message').classList.remove('d-none');
break;
default:
return;
}
default: {
// Prevent double-clicking on the send button and
// add a upload loading effect (delay before success
// message)
await concurrency.delay(dom.DEBOUNCE);
self.update_status('success');
break;
}
}
// Reset the form
self.$target[0].reset();
self.restoreBtnLoading();
}
})
.guardedCatch(error => {