1

I am editing a node/add/ form using hook_form_alter(). The form that I have added has Ajax functionality.

The first part of the form allows the user to build a search which then retrieves a list of legislators, and populates the #options array of the tableselect with those legislator

The second part of the form, needs to move legislators from the first tableselect to the second tableselect, as they are selected, using Ajax.

The issue: when I set the #options array for the legislator_tableselect in the contact_rep_node_add_ajax_get_legislators_callback, it does not update the $form_state['values'] array, which prevents be from retrieving the values in my next callback.

How do I go about forcing the $form_state['values'] to update? Or is there a better way to do this?

P.S. there is more to this form, I edited it for the sake of brevity though

function contact_rep_form_alter(&$form, &$form_state, $form_id) {

  if ($form_id == 'contact_rep_node_form') {

    $form['search_container'] = array(
      '#type' => 'fieldset',
      '#title' => t('Get a list of legislators to contact by building a search below'),
      '#collapsible' => FALSE,
    );

    $form['search_container']['select_state'] = array(
      '#title' => t("Select a state for your legislators"),
      '#type' => 'select',
      '#required' => FALSE,
      '#options' => array(
        //Contains a list of US states. Removed for brevity
      ),
      '#ajax' => array(
        'wrapper' => 'filteredLegislatorsSearch-div'
      ),
    );

    $form['search_container']['first_name'] = array(
      '#title' => t('Legislator\'s first name'),
      '#type' => 'textfield',
      '#size' => 60,
      '#maxlength' => 128,
      '#required' => FALSE,
    );

    $form['search_container']['last_name'] = array(
      '#title' => t('Legislator\'s last name'),
      '#type' => 'textfield',
      '#size' => 60,
      '#maxlength' => 128,
      '#required' => FALSE,
    );

    $form['search_container']['chamber'] = array(
      '#type' => 'select',
      '#title' => t('Chamber'),
      '#options' => array(
        0 => t(''),
        'upper' => t('Upper'),
        'lower' => t('Lower'),
      ),
    );

    $form['search_container']['district'] = array(
      '#type' => 'textfield',
      '#attributes' => array(
        'data-type' => 'number'
      ),
      '#title' => 'District',
      '#size' => 10,
      '#maxlength' => 3,
      '#required' => FALSE,
    );

    $form['search_container']['party'] = array(
      '#type' => 'textfield',
      '#title' => 'Party',
      '#size' => 60,
      '#maxlength' => 128,
      '#required' => FALSE,
    );

    $form['search_container']['filtered_submit'] = array(
      '#type' => 'submit',
      '#name' => 'filtered_search',
      '#value' => t('Find Legislators'),
      '#ajax' => array(
        'submitter' => FALSE,
        'callback' => 'contact_rep_node_add_ajax_get_legislators_callback',
        'wrapper' => 'legislator_container',
      ),
    );

    $form['search_container']['legislator_container'] = array(
      '#prefix' => '<div id="legislator_container">',
      '#suffix' => '</div>',
    );

    // The problem?
    $form['search_container']['legislator_container']['legislator_tableselect'] = array(
      '#options' => array(),
      '#type' => 'tableselect',
      '#empty' => t('Build your search above to get a list of legislators'),
      '#attributes' => array(
        'id' => 'legislatorTableSelect',
      ),
      '#header' => array(
        'first_name' => t('First Name'),
        'last_name' => t('Last Name'),
        'chamber' => t('Chamber'),
        'district' => t('District'),
        'party' => t('Party'),
      ),
      '#ajax' => array(
        'event' => 'change',
        'callback' => 'contact_rep_node_add_ajax_legislators_list_callback',
        'wrapper' => 'legislatorsToContact',
      ),
    );

    $form['search_container']['legislators_to_contact_container'] = array(
      '#prefix' => '<div id="legislatorsToContact">',
      '#suffix' => '</div>',
    );

    $form['search_container']['legislators_to_contact_container']['legislators_to_contact_tableselect'] = array(
      '#type' => 'tableselect',
      '#empty' => t('Legislators in this table will be emailed'),
      '#header' => array(
        'first_name' => t('First Name'),
        'last_name' => t('Last Name'),
        'chamber' => t('Chamber'),
        'district' => t('District'),
        'party' => t('Party'),
      ),
    );
  }
}

/**
 * Implements ajax callback for contact_rep_form_alter
 */
function contact_rep_node_add_ajax_callback($form, $form_state) {
  return $form['search_container'];
}

// Callback connected to filtered_submit button.
function contact_rep_node_add_ajax_get_legislators_callback($form, $form_state) {
  // Get form values and pass the to fetch function, save result to $legislators.
  /* Gets the form values from form elemets, passes them to a function and saves the out put to a variable. */
  $legislators = fetchFilteredLegislators($state, $chamber, $first_name, $last_name, $district, $party);
  // Creates the $options array for the tableselect.
  $element = $form['search_container']['legislator_container']['legislator_tableselect'];
  $element['#options'] = $legislators; // Set the options array to preformated $legislators array.
  $element = form_process_tableselect($element);// This has to be called in order to reset the $options in the tableselect items.
  return $element;
}

// Callback that is supposed to handle the the tableselect data.
function contact_rep_node_add_ajax_legislators_list_callback($form, $form_state) {
  $options = $form_state['values']['legislator_tableselect'];
  $element = $form['search_container']['legislator_to_contact_container']['legislators_to_contact_tableselect'];
  $element['#options'] = $options;
  $element = form_process_tableselect($element);// This has to be called in order to reset the $options in the tableselect item.
  return $element;
}

Edit: So after doing some more googling it seems that I need to set $form_state['rebuild'] = TRUE. And I added that to contact_rep_node_add_ajax_get_legislators_callback, but it still is not working.

Is that the correct place to put the the $form_state['rebuild'], or is there a better place to put it?

1

In your callback function save values to a secondary key such as $form_state['storage']. This will be retained each callback but $form_state['values'] will be overwritten with the current form elements values.

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.