Document that buttons with the same #value need a unique #name for the form API to distinguish them, or change the form API to assign unique #names automatically

Created on 15 November 2011, about 13 years ago
Updated 12 March 2024, 9 months ago

FAPI button handling uses #value as #op when the form is submitted. This prevents developers from using the same label on two buttons. Consider a form similar to a node form, where more than one field contains an "Add Another" option:

  // Some input fields ...

  $form['button1'] = array(						
    '#type' => 'button',
    '#value' => t('Add Another'),
  );

  // Some more input fields ...

  $form['button2'] = array(						
    '#type' => 'button',
    '#value' => t('Add Another'),
  );

In the submit handler, $form_state['triggering_element'] will always point to the first button, even if the second one was clicked. Node forms do not use FAPI; they have a different mechanism for generating forms that includes the machine name of the element and thus are not affected by this bug.

Another situation is where 2 form buttons ('Cancel' and 'Continue') have different values but one button 'Continue' was initially disabled on render and enabled via javascript after an ajax login was completed. Clicking on that 2nd button 'Continue' now was always triggering the 'Cancel'. So there are two and only two submit buttons - both have name="op", but their values are different. If the first button is initially disabled in a HOOK_form_alter, it appears the triggering element will get set to the value of the 2nd button.

πŸ“Œ Task
Status

Active

Version

11.0 πŸ”₯

Component
DocumentationΒ  β†’

Last updated 1 day ago

No maintainer
Created by

πŸ‡©πŸ‡°Denmark Dack

Live updates comments and jobs are added and updated live.
  • DrupalWTF

    Worse Than Failure. Approximates the unpleasant remark made by Drupal developers when they first encounter a particular (mis)feature.

  • Needs backport to D7

    After being applied to the 8.x branch, it should be considered for backport to the 7.x branch. Note: This tag should generally remain even after the backport has been written, approved, and committed.

Sign in to follow issues

Comments & Activities

Not all content is available!

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

  • Knowing this helped me fix a bug. It'd be incredibly helpful to document this.

  • πŸ‡ΊπŸ‡ΈUnited States paulmckibben Atlanta, GA

    This was a root cause for an ajax issue I was experiencing, due to two different forms appearing on the same page. On one of the forms, ajax submit failed to get a callback method because the formState->getTriggeringElement() returned NULL.

    Once I assigned a unique #name to the submit button for the form that was failing to submit using ajax, the problem was fixed.

    Before:

          $form['filter-container']['top-row']['submit'] = [
            '#type' => 'submit',
            '#value' => $this->t('Submit'),
            '#id' => 'license-filter-submit',
            '#ajax' => [
              'callback' => '::ajaxUpdateLicenseResults',
              'wrapper' => 'license-results-container',
              'progress' => [
                'type' => 'fullscreen',
              ],
            ],
          ];
    

    After:

          $form['filter-container']['top-row']['submit'] = [
            '#type' => 'submit',
            '#value' => $this->t('Submit'),
            '#id' => 'license-filter-submit',
            '#name' => 'license-filter-submit',
            '#ajax' => [
              'callback' => '::ajaxUpdateLicenseResults',
              'wrapper' => 'license-results-container',
              'progress' => [
                'type' => 'fullscreen',
              ],
            ],
          ];
    

    Adding a unique '#name' fixed the triggeringElement issue.

    Adding this here in hopes that anyone else experiencing this particular use case will find it.

  • The issue summary was updated/improved in #13 but the tag wasn't removed after.

Production build 0.71.5 2024