Problem/Motivation

Issue 1: Same-As component discovery cached globally, not per webform

webform_sameas_get_sameas_components() in webform_sameas.module (line 176) uses drupal_static() with a flat cache that is not keyed per webform. Once populated for the first webform in a request, every subsequent
call returns the first form's sameas components — even if the caller is a completely different webform. This is a real compatibility risk when multiple webforms are rendered in a single page request via Webform
blocks, Views, or panels.

1. Create two webforms, each with a Same-As component mapping different source/target fields.
2. Place both webforms on the same page (e.g. using Webform blocks or a View).
3. Load the page. The second webform will use the first webform's Same-As mappings and CIDs, causing incorrect field copying or PHP errors if the CIDs don't exist on the second form.

Key the drupal_static() cache by node ID. Extract the nid from the first component in the passed array and use it as the cache key, so each webform gets its own isolated set of sameas components.

---

Issue 2: Presave hook stops after copying the first Same-As mapping

webform_sameas_webform_submission_presave() in webform_sameas.module (line 122) contains a break statement immediately after copying source data to the target for the first matched sameas component. If a form has
more than one Same-As component, only the first mapping is applied during submission presave — all subsequent mappings are silently skipped.

1. Create a webform with two or more Same-As components (e.g. "Billing same as Shipping" and "Emergency Contact same as Primary Contact").
2. Check both Same-As checkboxes and submit the form.
3. Inspect the saved submission data. Only the first Same-As mapping will have copied its source values to the target — the second mapping's target fields will contain whatever the user entered (or blank), not
the source values.

Remove the break statement so the foreach loop continues and processes all sameas components in the form.

---

Issue 3: Reference lookup breaks on first non-match instead of continuing

webform_sameas_is_referenced() in webform_sameas.module (line 331) has inverted break logic. The loop breaks when !$is_referenced (i.e. the current sameas component does NOT reference the field being checked),
instead of breaking when a match IS found. This means the function only ever checks the first sameas component in the list — if the field is referenced by the second or third sameas component, it will never be
detected. CSS classes needed by the JavaScript copy logic will not be applied to those fields.

1. Create a webform with two Same-As components where the second one references different source/target fields than the first.
2. Render the form and inspect the HTML of the source and target fields belonging to the second Same-As component.
3. The fields will be missing webform-sameas-* CSS classes because the lookup bailed out after failing to match against the first sameas component. The JavaScript copy behavior will not work for the second
mapping.

Flip the condition from if (!$is_referenced) to if ($is_referenced) so the loop exits when a match is found, and continues searching through remaining sameas components when no match is found yet.

---

Issue 4: Addressfield child class propagation uses array union instead of merge

webform_sameas_process_addressfield() in webform_sameas.module (line 364) propagates tracking CSS classes to addressfield child elements using the PHP += operator on numerically-indexed arrays. PHP's += performs
an array union — it preserves existing keys and silently drops values from the right-hand array that share the same numeric index. If a child element already has one or more classes, any tracking classes at
overlapping indices (e.g. index 0, 1, 2) will never be added. The JavaScript relies on these classes (webform-sameas-cid--*, webform-sameas-type--addressfield, etc.) to locate source and target subfields during
copy and AJAX operations.

1. Create a webform with a Same-As component that maps between two addressfield components.
2. Render the form and inspect the HTML of the nested address subfields (street, city, country, etc.) inside the source and target addressfields.
3. The subfields will be missing most or all of the webform-sameas-* tracking classes because the union operator dropped them. The JavaScript copy behavior for address fields will be broken — field values will
not be copied between source and target address subfields.

Replace $field[$child]['#attributes']['class'] += $classes with $field[$child]['#attributes']['class'] = array_merge($field[$child]['#attributes']['class'], $classes) so all tracking classes are appended
regardless of existing numeric indices.

---

Issue 5: JavaScript event handlers accumulate on AJAX rebuilds

Drupal.behaviors.webform_sameas in webform_sameas.js (line 133) binds event handlers globally without using Drupal's context parameter or .once() guards. Every time Drupal.attachBehaviors is called — on AJAX form
rebuilds, conditional logic updates, multi-page navigation, or addressfield country changes — the handlers are re-attached to elements that already have them. The ajaxSuccess handler on document is particularly
problematic as it stacks up with no element-level scoping. This causes copy operations to fire multiple times per interaction, leading to unpredictable behavior and potential performance degradation.

1. Create a webform with a Same-As component and an addressfield (or any component that triggers AJAX rebuilds).
2. Load the form, change the country dropdown to trigger an AJAX rebuild, then change a source field value.
3. Observe in the browser console (or by adding a console.log to copy_single) that the copy handler fires multiple times for a single field change. Each subsequent AJAX rebuild adds another duplicate handler.

Scope all selectors to the context parameter, wrap each binding with .once() using a unique key, and replace deprecated .bind() calls with .on(). This ensures each element is only bound once, even across multiple
attachBehaviors cycles.

Comments

kaustubhb created an issue. See original summary.

kaustubhb’s picture

Issue summary: View changes
kaustubhb’s picture

StatusFileSize
new3.46 KB