5

I can't get a form to display a (default?) value after an AJAX call. I am using the following code:

function foo_form ($form, &$form_state, $foo) {

  $form['#prefix'] = '<div id="foo-form-wrapper">';
  $form['#suffix'] = '</div>';

  $form['copy'] = array(
    '#type' => 'submit',
    '#value' => t('Copy foo'),
    '#limit_validation_errors' => array(),
    // #submit is required to use #limit_validation_errors
    '#submit' => array('foo_form_submit'),
    '#ajax' => array(
      'wrapper' => 'foo-form-wrapper',
      'callback' => 'foo_form_callback',
    ),
  );

  $form['description'] = array(
    '#type' => 'textarea',
    '#title' => t('Short description'),
    '#required' => TRUE,
    '#maxlength' => 255,
    '#default_value' => $foo->description,
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );

  return $form;
}

function foo_form_callback($form, $form_state) {
  return $form;
}

function foo_form_submit ($form, &$form_state) {
  if (!isset($form_state['triggering_element']['#ajax'])) {
    $foo = (object)$form_state['values'];

    entity_get_controller('foo')->save($foo);

    $form_state['redirect'] = 'admin/foo';
    return;
  } else {
    form_set_value($form['description'], 'description text', $form_state);
    $form_state['rebuild'] = true;
  }
}

As I understand it, the form should automatically try to display the value if it is set in $form_state. When the callback is executed and the form is built, $form_state['values']['description'] is the value set in foo_form_submit. However, nothing is being displayed.

2
  • hook_form should have only 2 arguments. Where $foo is coming from?
    – corbacho
    May 19, 2011 at 17:01
  • It's an entity passed in as parameter. When the form is called there's either an empty entity passed (create) or one that's loaded from the database (update). You can pass additional arguments with drupal_get_form.
    – Bart
    May 20, 2011 at 7:28

4 Answers 4

1

I've experienced similar problems especially with textfields, checkboxes and radios. The solution I found (and I can't guarantee is the "correct" solution) is to change the $form_state['input'][VARIABLE] field. Do this in the validation function:

function foo_form_validate ($form, &$form_state) {
  // this will take a entered value from one element and make it display in another
  $form_state['input']['some_value_to_change'] = $form_state['values']['another_element'];
}
1
  • In my case it was the other way round: "$form_state['values']['bla'] = $form_state['input']['bla'];". Thanks for the answer.
    – Bart
    Jun 6, 2011 at 13:22
4

I know this is late, but for people like me who are still experiencing similar problems with ajax and forms in Drupal, here's how I fixed this. In your ajax callback function, instead of returning just the render array, you need to call the form_builder() function and return its result. Eg., my code goes like this:

function inventory_purchase_item_add_ajax(&$form, &$form_state) {
    //...

    unset($form_state['input']['line']);
    unset($form_state['values']['line']);

    //Update the form's lines array
    $lines = update_inventory_purchase_form_lines($form_state['node']->line, $purchase_item_count);
    $form['vtab1']['purchase']['items_wrapper']['line'] = $lines;
    return form_builder($form['#id'], $lines, $form_state);
}
1
  • This worked for me. For my case, I stored the original form element in $form_state['storage'] and then replaced in the Ajax callback. Thanks a lot!
    – AKS
    May 13, 2013 at 2:36
3

this bug even exists in drupal 8 and is presented HERE.

simplest simple solution is to remove input value of form element in form builder function before creating that element:

unset($form_state['input']['description']);
$form['description'] = array(
    '#type' => 'textarea',
    '#title' => t('Short description'),
    '#required' => TRUE,
    '#maxlength' => 255,
    '#default_value' => $foo->description,
 );

Another solution:

in some cases where there is no java script event handler attached to that element you can have different name for element so input doesn't come in the way, example:

$name='description_'.rand();
$form[$name] = array(
    '#type' => 'textarea',
    '#title' => t('Short description'),
    '#required' => TRUE,
    '#maxlength' => 255,
    '#default_value' => $foo->description,
 );

and save the name in $form for later use (in validation,submittion,...):

$form['a_unique_name']=$name;
0

thanks, this code works for me, the input method works for me ...

if (isset($form_state['values']['task-name'])) {
  $form_state['input']['task-description'] = show_task_description($form_state['values']['task-name']);
}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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