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.

  • hook_form should have only 2 arguments. Where $foo is coming from? – corbacho May 19 '11 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 '11 at 7:28
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'];
}
  • In my case it was the other way round: "$form_state['values']['bla'] = $form_state['input']['bla'];". Thanks for the answer. – Bart Jun 6 '11 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);
}
  • 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! – AyeshK May 13 '13 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, privacy policy and cookie policy

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