1

I have a multistep form. In the first step i have an AJAX submit callback that updates my &$step in $form_state and should return the next step of the form in the same page (replace contents of the form with the form elements in the second step) e.g.

  <?php

  funtion my_form_builder($form, &$form_state) {
     if (empty($form_state['step'])) {
      $form_state['step'] = 'step_1';
     }
     $step = & $form_state['step'];
     // build step 1
     if ($step == 'step_1') {
       $form['first_submit'] = array(
         '#type' => 'submit',
         '#ajax' => array(
           'callback' => 'form_first_submit',
          ),
         '#executes_submit_callback' => TRUE,
       );
     }
     // build step 2
     if ($step == 'step_2') {
       $form['elem_2'] = array(...)
       $form['elem_2_1'] = array(...)
     }
     return $form;
  }


  function form_first_submit($form, &$form_state) {
     $current_step = & $form_state['step'];
     // store values...
     // move on to the next step
     $current_step = 'step_2';

  $form = drupal_rebuild_form('my_form_builder', $form_state, $form);
  $commands[] = ajax_command_replace('#main-content', render($content));
  // return  ajax
  return array(
   '#type' => 'ajax',
   '#commands' => $commands,
  );
  }

So, naturally after the first submit, i should be able to rebuild my form and return to the #main-content the form elements defined for step 2. Why this doesn't work?I see the code passes on the right places and rebuilds and prepares the form for rendering.

I tried with drupal_build, drupal_retrieve_form and im getting nowhere.

If i drupal_get_form('another_form_id') it will work as expected.

Where is my error?

1 Answer 1

2

You dont' have to call drupal_get_form explicitly, instead mark form to rebuild.

In your ajax powerd element define two attributes: #submit, and #ajax.

#submit references the function that makes the action related to the submission (in your case changing the step value to 2 in form state). Also, set $form_state['rebuild'] to TRUE.

#ajax, where you set the ajax parameters and the PHP function that will return the result form the built form (in this case, the rebuilt one). When this fucntion is called form is build (or rebuilt) and you only have to return the form part you need.

Take into account that in the #ajax attribute you can set the HTMl element that will be replaced by the answer, so you don't need to use ajax commands.

<?php

  funtion my_form_builder($form, &$form_state) {
     if (empty($form_state['step'])) {
      $form_state['step'] = 'step_1';
     }
     $step = & $form_state['step'];
     // build step 1
     if ($step == 'step_1') {
       $form['first_submit'] = array(
         '#type' => 'submit',
         '#ajax' => array(
           'callback' => 'form_first_ajax_callback',
          ),
         '#executes_submit_callback' => TRUE,
         '#submit' => array('my_form_builder_callback'),
       );
     }
     // build step 2
     if ($step == 'step_2') {
       $form['elem_2'] = array(...)
       $form['elem_2_1'] = array(...)
     }
     return $form;
  }

  function my_form_builder_callback($form, &$form_state) {
     $current_step = & $form_state['step'];
     // store values...
     // move on to the next step
     $current_step = 'step_2';
     $form_state['rebuild'] = TRUE;
  }


  function form_first_ajax_callback($form, &$form_state) {

  $commands[] = ajax_command_replace('#main-content', render(form['element_to_return']));
  return array(
   '#type' => 'ajax',
   '#commands' => $commands,
  );
  }

Example uses the ajax commands aproach.

Check the Form API internal workflow illustration.

10
  • Thanks, but i don't ever see the code to pass through form_first_ajax_callback() ... it goes straight to the form_builder and exits..
    – Pan Chrono
    Dec 9, 2013 at 15:47
  • Have you set to true $form_state['rebuild']? Also, validation errors prevents form from being rebuilt, make sure there are no errors.
    – sanzante
    Dec 9, 2013 at 15:58
  • yep my code is similar to your answer, i just return render($form) in the command, but the code in the form_first_ajax_callback is never executed for some reason - no errors doublechecked, thats weird -- $form_state['rebuild'] = TRUE yes
    – Pan Chrono
    Dec 9, 2013 at 16:10
  • Are you using Drupal 7?
    – sanzante
    Dec 9, 2013 at 16:12
  • added 7 tag, yes
    – Pan Chrono
    Dec 9, 2013 at 16:17

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.