Prevention of multiple submits blocks use of back navigation

Created on 1 June 2020, almost 5 years ago
Updated 26 September 2024, 8 months ago

The issue is with the double click prevention in form.js `Drupal.behaviors.formSingleSubmit`. It serializes the form data and prevents consecutive submissions of the same data, as in a double click.

But it also prevents submission of non-consecutive form submissions with the same data. Steps to replicate:

  • Visit /admin/structure/types/manage/page
  • Click 'Save content type'
  • Click the browser back button
  • Try to click the 'Save content type' button without changing any of the form data

This seems to be quite heavy handed, the only way out of this form is to use navigation on the page, or the forward button, none of which are obvious or intuitive.

This issue also occurs when there are more steps between first clicking 'Save content type' and going back, for example:

  • Visit /admin/structure/types/manage/page
  • Click 'Save content type'
  • Click 'Edit' for the article content type
  • Click 'Save content type'
  • Click the browser back button
  • Click the browser back button
  • Click the browser back button
  • Try to click the 'Save content type' button without changing any of the form data

This now starts to be quite a negative effect for journeys with multiple steps in them, and starts to break the back navigation within these journeys. IMO this js should only prevent consecutive form submissions. Am I missing something? Or is there a way to do this, it's not obvious to me.

Thanks.

🐛 Bug report
Status

Active

Version

10.2

Component

forms system

Created by

🇬🇧United Kingdom kalpaitch

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇧🇪Belgium weseze

    I'm reopening this because it still exists. At least in my test in Drupal 10.2 but I'm assuming it also exists in 10.3 and 11.
    You do have to use certain browsers.

    In Chrome this is not an issue for me: version 127.0.6533.89 (Official Build) (arm64)
    In Firefox this is an issue: version 130.0.1 (64-bit)
    Client working in latest version of Edge also reported this problem.
    A colleague working in Firefox Developer Edition (latest up-to-date version) also reported this problem.

    This was tested using the test scenario as described by kalpaitch in the original post.

    We first encountered this issue in a commerce setup, where this is issue was already reported several times, but no solution yet.
    🐛 Using the browser's back button disables checkout button on cart form Active
    🐛 Next buttons are blocked until page refresh after use browser's back button Active

    There are 2 ways to get it working again (not a fix, but might give some insight into what the problem is):
    1/
    Inspect the page, navigate to the form element and remove the "data-drupal-form-submit-last" attribute.
    2/
    Make any change in any of the fields in the form.
    Both of these make the form work again.

    I have traced back the "data-drupal-form-submit-last" and it has something to do with preventing the form from being submit (double clicking the submit)

  • 🇳🇿New Zealand quietone

    Drupal 10.2 is now only receiving security support.

    @weseze, Can you confirm that this problem exists on Drupal 11. And are the steps to reproduce in the issue summary correct?

  • 🇳🇿New Zealand quietone

    I am going to move this to 11.x for now because changes are made on on 11.x (our main development branch) first, and are then back ported as needed according to our policies and will be visible to more people.

  • 🇺🇸United States rhovland Oregon

    In my testing it affects both Firefox and Chromium.

    This affects all submit buttons in a form not just the one that was previously clicked.

    So for an example I have a cart form. It has multiple submit buttons. The main one is the checkout button. There are also remove buttons on each cart item and an empty cart button. None of these buttons are functional after clicking back in the browser after submitting the form.

    This is the issue where this feature was added
    🐛 Double click prevention on form submission Fixed

    The feature was intended to prevent double clicking a submit button causing two form submits from happening. It was not intended to prevent the same form from being submitted again after loading the submission page and going back in the browser.

    This feature as written causes unexpected behavior in forms across core and contrib. There is no mechanism to opt out a form from this protection. The only way for an end user to fix the page is to refresh the page or change a form value (if they can).

  • 🇺🇸United States rhovland Oregon

    I wrote an event listener for form.js that unsets the double submit data if the page is loaded via the cache (user hits back button), allowing the submit button to work as expected.
    If core wants to prevent ever resubmitting a form then it should be a configurable option not a blanket form API feature.

    As written this prevents the problem from the original issue, clicking submit multiple times, while avoiding breaking forms when the back/forward buttons are used.

  • Pipeline finished with Failed
    2 months ago
    Total: 559s
    #453520
  • Pipeline finished with Failed
    2 months ago
    Total: 703s
    #453600
  • Pipeline finished with Failed
    2 months ago
    #453605
  • Pipeline finished with Failed
    2 months ago
    Total: 420s
    #453615
  • 🇺🇸United States smustgrave

    Thanks for reporting.

    Issue summary needs to be complete, especially steps and proposed solution sections.

    Also will most likely need a test showing the problem.

  • 🇺🇸United States jmev

    I've tested the patch by @rhovland on the checkout screen (Commerce 2.36) and it works well. Thank you!

  • 🇺🇸United States rhovland Oregon
  • 🇺🇸United States rhovland Oregon
  • 🇺🇸United States rhovland Oregon

    I attempted to address the issue summary. Can you please let me know if there needs to be further changes to it.

    In regards to a test, where do you suggest it be placed? It seems FunctionalJavascript tests for forms are located at core/tests/Drupal/FunctionalJavascriptTests/Core/Form. Should a new test file be created there? Should it be added to an existing Form test?

    When writing the test what am I testing for? Am I writing a test to ensure that the submit button is disabled when clicked twice? And then navigate back and ensure that it is not disabled? I was unable to find an existing test for the double click prevention feature.

    Lastly, is there a way to ensure someone with more experience with javascript reviews the merge request for correctness? I'm uncertain if I did it correctly. There's also a failure of a nightwatch test that I don't really understand (I've never used nightwatch before).

    Appreciate your feedback, I'm still learning and have only done work with tests in contrib modules.

  • 🇬🇧United Kingdom catch

    This code was added when core either didn't have JavaScript testing or didn't have very much of it.

    Reading this, I'm wondering whether we should look at removing this altogether - form.js is not included for every form, it's included only when the library is added, and none of the places in core that include it specify that it's for double click prevention. So we have some forms with double click prevention, and some without, pretty much at random. There is no per-form opt-in or opt-out, so if the js is loaded on the page for any reason, it applies to all forms, not just the one that loaded it. Some of this was pointed out in 🐛 Double click prevention on form submission Fixed after commit too (although the history of that issue is hard to track because it was then moved to Drupal 7 for backport).

    I think we should probably discuss whether to remove it altogether before trying to add test coverage, but given this can completely break forms if there's an issue, we'd probably need to add tests both for the original double-click prevention and the back button situation if we go ahead.

  • 🇬🇧United Kingdom catch
  • 🇺🇸United States jmev

    I ended up using this solution on the specific page experiencing this issue to avoid any possible issues on other forms. Thanks for the assist, @rhovland.

  • 🇺🇸United States rhovland Oregon

    Why did you overwrite all of the changes made to this issue?

  • 🇺🇸United States rhovland Oregon

    So while I was looking at the history for this issue to revert the changes made, I ran into this issue's bug. I viewed a comparison, then hit back and then tried to view the comparison again and the button didn't work until I reloaded the page.

  • 🇺🇸United States rhovland Oregon
  • 🇦🇺Australia acbramley

    🐛 Action buttons unresponsive when coming back from node preview Active was marked as a duplicate of this.

    When testing that issue I also found some weird behaviour (I didn't realise this was core's JS at the time) where after you hit Back in the browser you can eventually submit the form if you spam the save button a few times.

  • 🇮🇳India snehal-chibde

    Hello, I have tested the MR on chrome browser on Drupal version 11.2.dev and it is working as expected.
    Have tested both the scenarios mentioned in the IS.

    Scenario 1.
    Visit /admin/structure/types/manage/page
    Click 'Save content type'
    Click the browser back button
    Try to click the 'Save content type' button without changing any of the form data

    Scenario 2.
    Visit /admin/structure/types/manage/page
    Click 'Save content type'
    Click 'Edit' for the article content type
    Click 'Save content type'
    Click the browser back button
    Click the browser back button
    Click the browser back button
    Try to click the 'Save content type' button without changing any of the form data.

    Earlier the issue was the page was getting stuck on click of save and it was not going back to the content type listing page.
    After the MR is applied the issue gets resolved and it goes back to the content type listing page.
    Added before and after screenshots for reference.

  • 🇫🇷France nod_ Lille

    Small nitpick for the selector, fix look appropriate

  • Pipeline finished with Failed
    12 days ago
    Total: 189s
    #501316
  • Status changed to Needs review 12 days ago
  • 🇦🇺Australia acbramley

    Removed the jQuery selector, I'm not sure if this is testable in phpunit.

    The original feature was added in 🐛 Double click prevention on form submission Fixed in 2014 without tests but that could have been before we had extensive test coverage.

  • Pipeline finished with Success
    12 days ago
    Total: 1039s
    #501321
  • 🇮🇳India Tirupati_Singh

    I'm reviewing this.

  • 🇮🇳India Tirupati_Singh

    Hi all, I followed the steps to reproduce the issue and can confirm that it persists. I was able to replicate the problem on both Drupal versions 11.1.7 and 10.4.7. When I click the Save button on a form, such as the one for "/admin/structure/types/manage/page," the page reloads, and the changes are saved. However, if I click Save and then navigate back to the previous page using the browser's Back button, clicking Save again results in no action. The changes are only saved after refreshing the page. This behavior also occurs when creating a new field; after saving it and using the back button to return to the page, clicking Save again doesn’t work.

    I’ve applied the provided MR as a patch on both Drupal 10 and 11 versions, and the patch applied successfully without errors. After applying the patch, I repeated the steps to reproduce the issue. Now, when I click Save, the changes are saved, and the page redirects to its destination route. After navigating back using the browser’s Back button, clicking Save again successfully saves the changes, which wasn’t happening before the patch was applied. The same behavior occurs when creating or editing fields — after saving and navigating back, clicking Save works as expected, as demonstrated in the attached video clips.

    I’ve attached video clips showing the behavior before and after the fix for reference. Since the MR changes are now functioning as expected, I would mark this as RTBC. However, since the MR still requires maintainer review, I won’t change the issue status to RTBC just yet. If the maintainer approves the changes, the status can be updated accordingly.

    Thanks!

Production build 0.71.5 2024