Odd behaviour with vertical tabs on validation failure

Created on 22 February 2025, 4 months ago

Problem/Motivation

Im noticing what feels like an odd behaviour when using vertical tabs (via field group). It only happens in a particular setup, but given this behaviour is coming from the vertical-tabs.js I'm raising it here.... it's worth noting that I'm using other modules as well to achieve this setup. As below.

When adding a node with paragraphs, if a previous validation failure has occurred, the tab that contains the complaint is reopened, even if the validation issue has been resolved.

Example below.

Steps to reproduce

1. Drupal 10.4
2. Latest Field Group
3. Latest Paragraphs
4. Disable html5 validation on the basic page form
5. Enable the 2 above modules
6. Add a new paragraph type, with a single plain text field - make it required
7. Add a paragraphs field to the basic page content type
8. Configure the basic page into tabs using field group. One tab for the title (which should be required) and one tab for the paragraphs
9. Add a new basic page
10. Leave the node title empty
11. Open the paragraphs tab
12. Add a new paragraph - new paragraph is added as expected
13. Try and save the node
14. The validation will fail because the node title was empty, and the title tab is opened as you'd expect
15. Now add a node title (to resolve the validation complaint)
16. Reopen the components tab again
17. Add a new paragraph
18. On AJAX complete, the title tab is reopened with the title field showing a validation complaint even though its been resolved

As far as I can tell this is what's reopening the tab

      // If a validation error is within a vertical tab, open that tab.
      context.querySelectorAll('details .form-item .error').forEach((item) => {
        const details = item.closest('details');

        if (details.style.display === 'none') {
          const tabSelect = document.querySelector(
            "[href='#".concat(details.id, "']"),
          );

          if (tabSelect) {
            tabSelect.click();
          }
        }
      });
    },
  };

Proposed resolution

Unsure at this point whether this issue can be resolved in the field group module given the JS that fires this behaviour is in the vertical tabs js from Core.

Im not a UX expert but to me the title tab shouldn't have been reopened because the validation complaint has been resolved. It also feels odd that it would open this tab at all on AJAX complete, given I haven't tried to resave the node yet.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

πŸ› Bug report
Status

Active

Version

10.4 ✨

Component

other

Created by

πŸ‡¬πŸ‡§United Kingdom aaron.ferris

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

Merge Requests

Comments & Activities

  • Issue created by @aaron.ferris
  • πŸ‡¬πŸ‡§United Kingdom aaron.ferris
  • πŸ‡¬πŸ‡§United Kingdom aaron.ferris
  • πŸ‡³πŸ‡ΏNew Zealand quietone

    Changes are made on on 11.x (our main development branch) first, and are then back ported as needed according to the Core change policies β†’ . Also, Drupal 10.4 is in maintenance mode.

  • πŸ‡΅πŸ‡ΉPortugal dxvargas

    I have a simpler use case where paragraphs is not needed, just Field group. It can be replicated in latest D11.
    I'm attaching an image with the configuration bellow.

    1. Go to the "Basic Page" content type
    2. Make body required
    3. Add an image field
    4. Go to the form display page
    5. Add vertical tabs "Tabs" with tab "Tab 1" and tab "Tab 2"
    6. Put "Tab 1" and "Tab 2" inside "Tabs"
    7. Put "Title" and "image" inside "Tab 1"
    8. Put "Body" inside "Tab 2"
    9. Go to the Basic page creation form
    10. Fill the title and submit
    11. The form is submitted and there will be an error because Body is empty. The visible tab will be "Tab 2" by now, this is correct.
    12. Go to back to "Tab 1"
    13. Upload an image
    14. The tab "Tab 1" is hidden and we jump to "Tab 2" with the body. This should not happen.

    The problem exists whenever:

    1. A validation error exists in field A
    2. A field B that updates the DOM of the page is changed
    3. The field A and B are in different tabs.

    The problem comes from the core file web/core/misc/vertical-tabs.js.
    When an image is uploaded (or removed), there is a change in the DOM. Then, every time there is a "DOMContentLoaded" event, the context.querySelectorAll() in Drupal.behaviors.verticalTabs is triggered and it looks for tabs with errors and programmatically clicks them. This is what makes our tab that has the body to be visible.

  • πŸ‡΅πŸ‡ΉPortugal dxvargas
  • Pipeline finished with Failed
    3 days ago
    Total: 128s
    #527709
  • Pipeline finished with Canceled
    3 days ago
    Total: 282s
    #527718
  • Pipeline finished with Success
    3 days ago
    #527720
  • πŸ‡΅πŸ‡ΉPortugal dxvargas

    The code to focus the tab with errors should happen inside a "once", to not run after AJAX events.
    This is basically the main change I am proposing.

    The focus of the tab with errors is covered already in \Drupal\FunctionalJavascriptTests\Core\Form\FormGroupingElementsTest::testVerticalTabValidationVisibility() and it is passing in my MR.

  • Pipeline finished with Success
    3 days ago
    Total: 536s
    #527898
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Seems like something probably should have test coverage for.

    Also tagging for IS update as the proposed solution isn't super clear

Production build 0.71.5 2024