Stop nesting form elements in the checkout address step - #233
Draft
boo-code wants to merge 1 commit into
Draft
Conversation
The address step wrapped the whole block in a <form> and rendered full address <form> elements inside it, and the address form's own buttons block opened yet another <form> around the Continue button. The HTML parser resolves nesting by dropping the inner start tag and letting the inner </form> close the outer form, so every control after the address form loses its form owner. Measured on 9.2.0 with classic 3.1.2: with two saved addresses, a separate invoice address and the delivery address open for editing, the Continue button, both invoice radios and the not-valid-addresses input all report form === null. Attach those controls to the step form through the form attribute instead, leave the step form element empty so the address forms stay siblings, and replace the buttons-block form with a div, matching what hummingbird already does.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
<form>around the whole block and then renders full address<form>elements inside it, andcheckout/_partials/address-form.tplopens a third<form>around the Continue button. HTML forbids nesting, and the parser resolves it by ignoring the inner start tag and letting the inner</form>close the OUTER form - so every control rendered after an address form loses its form owner. This attaches the step's own controls (address selector radios, Continue button,not-valid-addresses) to the step form through theformattribute, leaves that form element empty so the address forms are siblings rather than children, and replaces the buttons-block<form>with a<div>, which is what hummingbird already does.#not-valid-addresseshave no form owner (document.querySelector('button[name=confirm-addresses]').formisnull), so Continue does nothing. After, all three belong to the step form.Measured on 9.2.0 with classic 3.1.2, counting
<form>tags in the address step of the served HTML and reading form ownership from the parsed DOM:Depth 3 is the case in the issue's screenshot: step form, then the address form, then the buttons-block form.
Form ownership in the two-address state, before -> after:
Why the
formattribute rather than moving the markupThe step form is needed for the address selectors and the Continue button; the address form is needed for
the address fields. They are never the same submission, but they interleave: a delivery selector can be
followed by an invoice form, so no arrangement of open/close tags puts every selector in the same form as
the Continue button. Explicit form ownership is the platform feature for exactly that, and it keeps source
order, markup and CSS unchanged.
Companion
PrestaShop/hummingbirdneeds the same change (branchfix/checkout-address-form-nesting-36563); itsaddress-form.tplalready uses a<div>for the buttons block, so only the step-form half applies there,plus a one-line fix to
initFormValidationwhich looked the submit button up withquerySelectorand soonly saw DOM descendants.