drupal 7 ajax form rebuild form to change form_state value

15.3k Views Asked by At

I have one drupal form, i want it works as "add one more": there is one button at the end of the form, when click it, another form will append to it. Here is part of my code:

function add_passenger_form($form, &$form_state){
   if(!isset($form_state['num_names'])){
      $form_state['num_names']=2;
   }
   $form['add_button']= array(
    '#type' => 'button',
    '#value'=> 'Add more',
    '#ajax' => array(
        'callback' => 'ajax_add_passenger_callback',
        'method' => 'replace',
        'effect' => 'fade',
        'wrapper' => 'last_field',
    ),
  );
  $form['form_number']=array(
        '#prefix'=>'<div class="form_number">',
        '#suffix'=>'</div>',
        '#type'=>'hidden',
        '#value'=>2,
    );
}

function ajax_add_passenger_callback($form, &$form_state){
    $form_state['num_names']++;
$form_state['rebuild']=TRUE;
    $form['form_number']['#value']=$form_state['num_names'];
    return array(
                    '#type' => 'ajax',
                    '#commands' => array(
                                    ajax_command_replace(".form_number", render($form['form_number'])),

                    )
                );
}

I want the $form['num_names']['#value'] increase one when i click the add one button. Now it only works once (to 3).

2

There are 2 best solutions below

1
On
    function add_passenger_form($form, &$form_state){
    $form['#tree'] = TRUE;

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

   $form['passenger_fieldset'] = array(
      '#type' => 'fieldset',
      '#title' => t('List of Passengers'),
      '#prefix' => '<div id="passenger-form-wrapper">',
      '#suffix' => '</div>',
    );

   for ($i = 0; $i < $form_state['num_names']; $i++) {
     $form['passenger_fieldset']['passenger_name'][$i] = array(
       '#type' => 'textfield',
       '#title' => t('Passenger Name'),
       '#required' => false,
     );
   }

   $form['passenger_fieldset']['add_button']= array(
    '#type' => 'submit',
    '#value'=> t('Add passenger'),
    '#submit' => array('add_passenger_form_add_one'),
    '#ajax' => array(
        'callback' => 'add_passenger_form_callback',
        'method' => 'replace',
        'effect' => 'fade',
        'wrapper' => 'passenger-form-wrapper',
    ),
  );
// Remove passenger 
if ($form_state['num_names'] > 2) {
     $form['passenger_fieldset']['remove_button'] = array(
      '#type' => 'submit',
      '#value' => t('Remove Passenger'),
      '#submit' => array('remove_passenger_form_remove_one'),
      '#ajax' => array(
        'callback' => 'add_passenger_form_callback',
        'method' => 'replace',
        'effect' => 'fade',
        'wrapper' => 'passenger-form-wrapper',
        ),
      );
   }
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
    );

  return $form;
}
/* 
* add a textfield one more
*/
function add_passenger_form_add_one($form, &$form_state) {
  $form_state['num_names']++;
  // rebuild whole form with new values
  $form_state['rebuild'] = true;
}
function remove_passenger_form_remove_one($form, &$form_state) {
  if ($form_state['num_names'] > 2) {
    $form_state['num_names']--;
  }
  $form_state['rebuild'] = TRUE;
}
function add_passenger_form_callback($form, $form_state){
    return $form['passenger_fieldset'];    
}
0
On

Change your code like this.. this will create button "Add more" to add new passenger and one field (name) for each passenger. You can replace that "Name" field for example with fieldset and add more fields for one passenger.

function add_passenger_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 = 0; $i < $form_state['num_names']; $i++) {  

     $form['name_' . $i] = array(
       '#type' => 'textfield',
       '#title' => t('Name'),
       '#required' => true
     ); 
   }

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

function ajax_add_passenger_callback($form, &$form_state){

    $form_state['num_names']++;

    // rebuild whole form with new values
    $form_state['rebuild'] = true;
}

Also check this link for more info about ajax:

https://api.drupal.org/api/examples/ajax_example!ajax_example_graceful_degradation.inc/7