Problem/Motivation
When there's multiple webforms into a page, both containing phone fields, with the same name, all the hidden inputs are put only in the last form (in order of appearance in the DOM)
so say one have in the page two forms (inserted via twig form example): eg. business contact and press contact
both containing a field of type "phone" with name "contact"
the first form, business, will end up with:
input name='contact[localnumber]' ...
<code>
while the last one, press contact, will end up with:
<code>
input name='contact[local_number]' ...
input name='contact[phone_number]' ...
input name='contact[phone_number]' ...
input name='contact[country_code]' ...
input name='contact[country_code]' ...
so on
This make the all but the last form fail to submit, as required field is missing:
Phone number in contact is required.
Steps to reproduce
Create two webforms containing phone field with the same name.
Insert both in the same page.
Open that page and check the Elements in DevTools.
[Optional] try submit the first form to see it fails.
Proposed resolution
The script phone.js has two flaws that are causing this problems:
on definition of Drupla.initPhoneNumber function, it used "global" selector for the existing hidden inputs via name attribute, to later move'em next to the tel input.
const $phoneNumber = $('[name="' + phoneFieldName + '"]');
const $countryCode = $('[name="' + codeFieldName + '"]');
const $countryIso2 = $('[name="' + iso2FieldName + '"]');
But that will math all inputs in the page with the same name.
It would be better to scope that selection to within the same webform field's wrapper.
Next to this, it already tries to to find elements scoped to that input, beeing label and error message
but it uses a selector that gets no element for what i could see:
const $phoneParent = $phoneMasked.closest('div.field--type-phone');
So it would be better to change it to a class of the field's wrapper.
const $phoneParent = $phoneMasked.closest('div.phone-number-field');
Which is actually inserted by the module itself at /src/Element/Phone.php#94
$element['#prefix'] = "<div class=\"phone-number-field form-item $field_name\" id=\"$id\">";
With seletor fixed, to complete the chain, mode the $phoneParent variable to just bellow the input itself ( $phoneMasked ), so it can them be used to select the hidden inputs too, ending up with:
const $phoneMasked = $(field);
const $phoneParent = $phoneMasked.closest('div.phone-number-field');
const $phoneNumber = $phoneParent.find('[name="' + phoneFieldName + '"]');
const $countryCode = $phoneParent.find('[name="' + codeFieldName + '"]');
const $countryIso2 = $phoneParent.find('[name="' + iso2FieldName + '"]');
const $phoneLabels = $phoneParent.find("label");
const $errorStatus = $phoneParent.find(".phone-error-msg");
Issue fork phonenumber-3572945
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments