Seems to be an extremely simple question. But I can't figure it out. In my module's form I need to load form values depend on the value of certain one and rebuild the form using those.

here is the part of the code (form builder):

$namevalue = isset($form_state['values']['name']) ? $form_state['values']['name'] : "";
$form['name'] = array(
    '#type' => 'textfield',
    '#default_value' => $namevalue
);
$form['load_settings'] = array(
    '#type' => 'button',
    '#value' => t('Load my settings'),
    '#ajax' => array(
        'callback' => 'simplenews_mod_load_subscriptions',
    )
);

Here is the callback:

function simplenews_mod_load_subscriptions( $form, &$form_state){
  $form_state['values']['name'] = "loaded value"; // here will be a function which will get the value form DB
  return $form_state;
}

Nothing changes in the $form_state array. I think I just don't get the basis of ajax in D7 itself... I'd be very appreciated if someone show my the simplest example of how to change a form field value using ajax.

Or alternatively: how do I rebuild form with new values using custom submit callback. Not on validation.

Thank you.

up vote 0 down vote accepted

the problem was in the way I pass submit callback. It should be like

'#submit' => array('foo_submit_callback')

ARRAY!

the less visible thing is the most visible one...

You're pretty close...

$form_state['values']['name'] = "loaded value";
return $form_state();

Is wrong for a few reasons:

  • Messing with the submitted values ($form_state['values']) directly possibly isn't the best idea; if you need to do it that way, use form_set_value, but even better, stash it somewhere else in $form_state
  • $form_state is an array, and can't be invoked as a function. If you look in the logs, your AJAX requests will probably be returning a 500.
  • You need to return the element of the form that you want to replace rather than the state; $form_state is by reference so changes you make are persisted to it that way.

You're also missing the wrapper property for the ajax array in the form function, so the system won't be able to manipulate the DOM with the new data.

With those in mind, try something like this for the form function:

$namevalue = isset($form_state['namevalue']) ? $form_state['namevalue'] : "";
$form['name'] = array(
    '#type' => 'textfield',
    '#default_value' => $namevalue,
    '#prefix' => '<div id="name-value-field">',
    '#suffix' => '</div>',
);
$form['load_settings'] = array(
    '#type' => 'button',
    '#value' => t('Load my settings'),
    '#ajax' => array(
        'callback' => 'simplenews_mod_load_subscriptions',
        'wrapper' => 'name-value-field',
    ),
    '#submit' => 'foo_submit_callback',
);

and this for the callback:

$form_state['namevalue'] = "loaded value"; // here will be a function which will get the value form DB
return $form['name'];

and a submit handler for your button to rebuild the form:

function foo_submit_callback($form, &$form_state) {
  $form_state['rebuild'] = TRUE;
}
  • thanks, Clive. 'form_state()' was a mistyping. it's 'form_state' of course. But. your solution didn't help. Name field keeps being empty and dpm shows no "namevalue" variable within form_state after form update. – Andriy Jun 30 '16 at 20:54
  • Try adding $form_state['rebuild'] = TRUE; in the callback – Clive Jun 30 '16 at 21:00
  • still no luck. neither in the field nor in the form_state array – Andriy Jun 30 '16 at 21:12
  • Try adding '#submit' => 'some_function' to your button definition, and in some_function set $form_state['rebuild'] = TRUE; – Clive Jun 30 '16 at 22:50
  • I did. I was in the middle of replihng when the post is deleted. anyway. I've added a submit callback and moved form_state modifications there. Still no luck. Cahes are cleared etc. – Andriy Jul 1 '16 at 8:39

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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