0

I have a custom ajax form in a custom module, the form function code is over 400 lines so it's too big to post here, but hopefully I can explain the situation clearly here.

The form has a form function mymodule_form($form, &$form_state) and also an ajax callback attached to a button mymodule_ajax_callback($form, $form_state). I put a dpm($form_state['values'], 'form state values from form function); in mymodule_form function, and also dpm($form_state['values'], 'form state values from callback'); inside the mymodule_ajax_callback function.

Now when I change the values in the form, and press the ajax'd button, the form state values from the form function only has 1 element in the array, and that's the button that was pressed. All other values are missing. At the same time, the form state values from ajax callback function has all the form fields with the correct values. If I understood ajax forms in D7 correctly, you're meant to change the form inside the form function and only do return render($form['element']) from the ajax callback. This situation makes it impossible to do so as I can't access all the values from the form function.

There's nothing in the Recent Log Messages about ajax errors. The form has only 1 Ajax button, but it has also 1 ajax'd select dropdown which when changed, changes options for another select dropdown.

I'm currently sitting here scratching my head, ready to pull some hair out wondering what could cause such weird behavior.

I'm posting a screenshot of the dpm's for clarification: enter image description here

As you can see values from form function has 1 element in array, values from ajax callback has 56 elements in array.

When I change the Ajax'd select dropdown however, the form state values from form function shows 55 elements, which is probably correct:

enter image description here

So it's only when I use the Ajax button this weird behavior occurs. Any help greatly appreciated. Can post the form code if needed.

2

It seems you are a bit confused about how the form API works. What you are seeing is exactly as expected. I'll try to explain about how the form API works.

The ajax callback is called in a context of the form being submitted, which is why, all of the form values are passed along, the actual form function is called in the context of being initialized where no form values exist.

There are different ways of structuring ajax. One way could be to add another input like what's possible with fields that can hold many values. In that case, the ajax callback function should only worry about a subset of the form, and return this (You shouldn't call render inside ajax callbacks).

Another way to use ajax is to restructure the entire form. In that case, what you can do, is to set

$form_state['rebuild'] = TRUE;

Which will force Drupal to rebuild the entire form, with the current values and make it possible to fx create a multistep form. This can be done both with and without AJAX.

It sounds like you will need to rebuild the form, to get $form_state values into the form function. Then you can add ajax behavior to the form, where you get this working.

2

I managed to fix this, it seems another developer has put #limit_validation_errors => array() on the Add filter button which caused the values to be discarded.

  $form['step3']['addfilter'] = array(
    '#name' => 'addfilter',
    '#value' => t('Add filter'),
    '#type' => 'button',
    '#ajax' => array(
      'event' => 'click',
      'callback' => 'filters_car_callback',
      'wrapper' => 'results-div',
      'method' => 'replace',
      'effect' => 'fade',
    ),
    '#limit_validation_errors' => array(),
  );

As soon as I removed that, the form started working again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.