How to specify in a form field's #ajax setting that the entire form should be rebuilt I have a form with 3 sequential selects at the top, each populated as a result of the selection in the one prior.

After the third select is choice is made, a large number of fields segregated into two vertical tabs should be populated.


In the form, I set the default value of each of the fields to an associative array element, which is empty when the form is first built.
When the third select choice is made, its callback 
a. obtains an associative array of the values needed for the form
b. stores them in $form_state['storage']['mykey']
c. sets $form['rebuild'] to true (for good measure)
d. returns $form
In the form function, prior to the field definitions, I set the associative array used for the default values to $form_state['storage']['mykey']


I can see in xdebug that $form_state has the data in the correct place prior to returning, but when execution returns to the form function, $form_state no longer has a ['storage'] key. 

AJAX CALLBACK

function my_ajax_callback($form, &amp;$form_state) {
  $form_state['storage']['draft'] = my_mysql_get($form_state['values']['id']);
  return $form;
}


FIRST LINE OF FORM FUNCTION (most fields use $r for default_value)

  $r =  !isset($form_state['storage']['draft']) ?  array() : $form_state['storage']['draft'];


A breakpoint at the callback reveals that it is reached, and that $form_state['storage']['draft'] is populated at the point of returning.

A breakpoint at the equate reveals that ['storage'] is no longer in $form_state, but this is only reached (in the form function) if I return only a field from the callback, not the entire form. I really need the entire form, because 17 of 20 fields on the form need to be rebuilt at that point, to get the default value into them.

FORM FIELD WITH AJAX CALLBACK

  $form['info'] = array(
    '#type' =&gt; 'select',
    '#title' =&gt; 'Player',
    '#prefix' =&gt; '&lt;div id="info_select"&gt;',
    '#suffix' =&gt; '&lt;/div&gt;',
    '#options' =&gt; info_options($form_state['values']['key1'], $form_state['values']['key2']),

    // ajax to bind this select to the players select
    '#ajax' =&gt; array(
      'event' =&gt; 'change',
      'callback' =&gt; 'my_ajax_callback',
      'wrapper' =&gt; 'my_form_id',
    ),
The workflow in an AJAX callback with a non button element is:


Submit data is received, form is constructed and validated. 
If no validation errors are detected form is rebuilt. This means that the form function is called again (the form that returns the form structure).
AJAX callback function is called. The task of this function is only to return the data to the browser. No persistent calculations should be done here.


You have to detect if tou are in an AJAX form request in your form function. If yes, calculate your date. Then, construct your form accordingly. Last, return the right form fragment (or the whole form) in your AJAX callback function.

Form function:

 $form['info'] = array(
    '#type' =&gt; 'select',
    '#title' =&gt; 'Player',
    '#prefix' =&gt; '&lt;div id="info_select"&gt;',
    '#suffix' =&gt; '&lt;/div&gt;',
    '#options' =&gt; info_options($form_state['values']['key1'], $form_state['values']['key2']),

    // ajax to bind this select to the players select
    '#ajax' =&gt; array(
      'event' =&gt; 'change',
      'callback' =&gt; 'my_ajax_callback',
      'wrapper' =&gt; 'my_form_id',
    ),

// If all selects have values get data to populate elements in vertical tabs.
if (all_select_have_values()) {
  $form_state['storage']['draft'] = my_mysql_get($form_state['values']['id']);
}

// Then add the rest of form elements. 
$r =  !isset($form_state['storage']['draft']) ?  array() : $form_state['storage']['draft'];
...


In callback just return your form:

function my_ajax_callback($form, &amp;$form_state) {
  return $form;
}


You are losing the values in $form_state because you are adding data to the $form_state in the callback function. AJAX calls are procesed by ajax_form_callback(). This function first calls drupal_process_form(), and then the AJAX callback function. $form_state is saved (when condition apply) at the end of drupal_process_form function.