0

I've tried to build a form with #ajax submit function and rebuild the form. The following is my code.

function campaign_new_form($form, &$form_state){

 if(!isset($form_state['num_names'])){
   $form_state['num_names']=2;
 }

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

 for ($i = 1; $i <= $form_state['num_names']; $i++) {
   $form['name_' . $i] = array(
     '#type' => 'textfield',
     '#title' => 'Value ' . $i,
     '#required' => true
   );
 }

 $form['add_button']= array(
  '#type' => 'submit',
  '#value'=> 'Add more',
  '#ajax' => array(
    'callback' => 'campaign_new_form_callback',
    'method' => 'replace',
    'effect' => 'fade',
    'wrapper' => 'form-wrapper',
 ),
);

 return $form;
}

function campaign_new_form_callback($form, &$form_state){
  $form_state['num_names']++;
  $form_state['rebuild'] = true;
  return $form;
}

It always renders two fields. What is the problem in my code?

3
  • I have done something similar without the forced rebuild (Drupal is smart enough to understand you want to rebuild the Ajax part). Does it work if you remove the rebuild from the callback? Commented Dec 24, 2016 at 20:22
  • Are you sure that $form_state['num_names']++ increases $form_state['num_names'] even when $form_state['num_names'] has not been defined?
    – avpaderno
    Commented Dec 25, 2016 at 7:04
  • It is not working for me.
    – Guru
    Commented Dec 26, 2016 at 12:43

1 Answer 1

4

Setting the rebuild in the ajax callback will not work, as the form has already been built at that point. It needs to be set in a submit function, which is fired before the form is built. You also need to increment your counter in the submit function for the same reason - if you do it in the ajax callback, the form is already built so the increment is not saved. It needs to be done in the submit function.

function campaign_new_form_submit($form, &$form_state)
{
  $form_state['num_names']++;
  $form_state['rebuild'] = TRUE;
}
6
  • I have always seen $form_state['rebuild'] set in a submission handler, so I take this is the right answer.
    – avpaderno
    Commented Dec 25, 2016 at 7:10
  • Ah yes, I did not find in my ajax callback but it is in the submit handler. Commented Dec 25, 2016 at 11:14
  • Is any other way to rebuild the form with #AJAX callback?
    – Guru
    Commented Dec 26, 2016 at 12:36
  • Not as far as I know. Is there some reason you don't want to create a submit function?
    – Jaypan
    Commented Dec 26, 2016 at 12:55
  • I need to display more than 1 form on a page. so I don't need to refresh the page
    – Guru
    Commented Dec 26, 2016 at 14:58

Your Answer

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

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