Submit buttons confused during function ajax_form_callback: form state triggering_element

Created on 10 May 2011, about 13 years ago
Updated 20 September 2023, 9 months ago

When I declare a button that is used only to initiate an ajax call (I would rather this button not be rendered as a submit button, just a button with the capability to kick off an ajax request).

Regardless of what the button wants to do, here is what the button looks like:

  $form['search_feature_in_form'] = array(
    '#type' => 'button',
    '#input' => FALSE,
    '#name' => 'search_feature_in_form',
    '#title' => t('Search Function'),
    '#value' => t('Search Function'),
    '#description' => t(''),
    '#required' => FALSE,	
    '#prefix' => '<div class="form-item"><label></label>',
    '#suffix' => '</div>',
    '#ajax' => array(
      'callback' => 'ajax_search_function_dependent_dropdown_callback',
      'wrapper' => 'something-id-replace',
    ),
    '#attributes' => array('onclick' => 'return false;'),
  );

So, I'm trying to get a simple button to kick off an AJAX request to update options in a selection form field.

This ajax callback will hopefully search for data, compile form select options and build an option list in the form.

I keep getting an error:
"Notice: Undefined index: #ajax in ajax_form_callback() (line 376 of C:\Program Files (x86)\Zend\Apache2\htdocs\proj\includes\ajax.inc)."

When I go into the ajax.inc code, it seems a bit hard coded to derive the #ajax from the 'triggering_element' without any conditionals whether it is the actual form submit button or only a button for kicking off an ajax request.

So, I stumbled on a bug.

Found that if you have TWO buttons in your form. No matter which button you click, the last submit button on the form gets processed by the ajax code :)

So what does that mean.

This means that the hard coded lookup of 'triggering_element' needs to consider the instance when two different submit buttons may have separate triggering_element's.

How I found this is a bug:

  if (!empty($form_state['triggering_element'])) {
    watchdog('ajax_form_callback', 'Error %error_message.', array('%error_message' => print_r($form_state['triggering_element'])), WATCHDOG_NOTICE);
    $callback = $form_state['triggering_element']['#ajax']['callback'];
  }

I put the debug line of code into the ajax.inc function ajax_form_callback(). I tested it for other ajax fields that do work. I notice that I can inspect the triggering_element information.

I found that when I click the "Search Function" button as I showed you above, the debug shows me the triggering_element information for the other form submit button?!?!?

This is a bug. Please help me recreate the problem. I keep digging, and what I am expecting to finally find is that there is something hardwired somewhere that if the submit button is tied to callback, it looks for 'op' regardless if I change the name or not. Otherwise, I do not see why triggering_element is pulling up the wrong form field artifact.

πŸ› Bug report
Status

Active

Version

9.5

Component
AjaxΒ  β†’

Last updated about 2 hours ago

Created by

πŸ‡¨πŸ‡¦Canada mdshields

Live updates comments and jobs are added and updated live.
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.

  • πŸ‡«πŸ‡·France bedlam Lyon

    We're seeing what I think is this issue on Drupal 9 too. If any other input[type="submit"] appears on the page before the ajax-enabled one, the ajax behavior gets attached to it instead.

    We're able to reproduce it at will, but only on one specific client environment, and it's not clear (yet) what role that environment might be playing. Making sure the ajax form is the first one on the page makes it work reliably.

    We initially thought the ajax behavior was missing, but found it was only misplaced by stepping through the js code on the page. Now that we know what to look for, we can try to discover where the selector goes wrong (i.e. because the observed behavior is like something like this made-up javascript is going on: const idSelector = functionReturingFalsyValue(); const ajaxSubmit = `input[type="submit"]${idSelector}`;).

Production build 0.69.0 2024