2

We are working on the form API which having 4 dependent drop downs, and also the dependent drop down having the option to Add one more (Adding 4 drop downs once again)or remove one set. The values of the drop down are pulled form DB.

The issues we are facing are:

  1. When we select the parent drop down the values are loading correctly in respective child drop down. Once select the 4 drop downs, after if we change the value in the first drop down. The second drop down value only alone changing. we are unable to reset the values in the third and Fourth drop downs.
  2. All the four drop downs are required fields Please find the code for reference, in-case of any questions ask me freely..

                <?php
    
    
            function company_form($form, $form_state) {
    
                // Build the fieldset with the proper number of names. We'll use
                // $form_state['num_names'] to determine the number of textfields to build.
                if (empty($form_state['field_of_study_num'])) {
                    $form_state['field_of_study_num']  = 1;         // For Field of studies
                    }
    
            //Field of studies Field Set
                $form['#tree'] = TRUE;
                $form['field_of_studies_fieldset'] = array(
                    '#type' => 'fieldset',
                    '#title' => t('Field of Studies'),
                    '#prefix' => '<div id="div_names-fieldset-wrapper">',
                    '#suffix' => '</div>',
                );
    
            for ($i = 0; $i < $form_state['field_of_study_num']; $i++) {    
    
            $form['field_of_studies_fieldset'][$i]['labels'] = array(
                        '#prefix' => '<div id="set'.$i.'"><h1 id = "company_form_label">',
                        '#type' => 'item',
                        '#title' => t('Form :'.($i+1)),
                        '#suffix' => '</h1>',
                    );     
    
            // field_of_studies Drop down box
            $options_fieldOf_Studies = _get_field_studies_mstr(0);  //Loading Values in the DB
            // First Dropdown Box
            $form['field_of_studies_fieldset'][$i]['field_of_studies1'] = array(
                    '#prefix' => '<div id = "fieldset'.$i.'"><div class="container-inline bottom_space field_of_studies_drop_down">',
                    '#options' => $options_fieldOf_Studies,
                    '#type' => 'select',
                    '#title' => t('Field of Studies'),
                    '#required' => '1',
                    '#suffix' => '</div></div>',
                    '#ajax' => array(    
                            'callback' => 'ajax_example_dependent_dropdown_callback1',
                            'wrapper' => 'dropdown-second-replace-'.$i,
                    ),      
            );
    
            // Loading values in the 2nd dropdown depends on the value selected in the First Dropdown
            if((isset($form_state['input']['field_of_studies_fieldset'][$i]['field_of_studies1']) && ($form_state['input']['field_of_studies_fieldset'][$i]['field_of_studies1']  != 0)))
            {
                $firstVal = $form_state['input']['field_of_studies_fieldset'][$i]['field_of_studies1']; 
                $options_fieldOf_Studies2 = _ajax_example_get_second_dropdown_options1($firstVal); 
            }
            else
            {// Loading values as "Select" intially
                $options_fieldOf_Studies2 = _ajax_example_get_second_dropdown_options1(0); 
            }
    
            // Second Dropdown Box values are dependent with First dropdown
            $form['field_of_studies_fieldset'][$i]['field_of_studies2'] = array(
                    '#type' => 'select',
                    '#title' => t('Field of Studies2'), 
                    '#prefix' => '<div id="dropdown-second-replace'.$i.'"><div class="container-inline bottom_space field_of_studies_drop_down">',
                     '#required' =>     (isset($form_state["values"]['field_of_studies_fieldset'][$i]['field_of_studies1']) ? ($options_fieldOf_Studies2 != '' ? TRUE : FALSE) : FALSE),
                    '#suffix' => '</div></div>',
                    '#options' => $options_fieldOf_Studies2, 
                    '#ajax' => array(    
                        'callback' => 'ajax_example_dependent_dropdown_callback2',
                        'wrapper' => 'dropdown-third-replace'.$i,
                    ),  
                );
    
    
            // Loading values in the 3rd dropdown depends on the value selected in the second Dropdown
            if((isset($form_state['input']['field_of_studies_fieldset'][$i]['field_of_studies2']) && ($form_state['input']['field_of_studies_fieldset'][$i]['field_of_studies2']  != 0)))
            {
                $secondVal = $form_state['input']['field_of_studies_fieldset'][$i]['field_of_studies2'];    
                $options_fieldOf_Studies3 = _ajax_example_get_second_dropdown_options1($secondVal); 
            }
            else
            {// Loading values as "Select" intially
                $options_fieldOf_Studies3 = _ajax_example_get_second_dropdown_options1(0); 
            }
    
    
            // Third Dropdown Box values are dependent with second dropdown
             $form['field_of_studies_fieldset'][$i]['field_of_studies3'] = array(
                    '#type' => 'select',
                    '#title' => t('Field of Studies3'), 
                    '#prefix' => '<div id="dropdown-third-replace'.$i.'"><div class="container-inline bottom_space field_of_studies_drop_down">',
                    '#suffix' => '</div></div>',
                    '#required' =>      (isset($form_state["values"]['field_of_studies_fieldset'][$i]['field_of_studies2']) ? ($options_fieldOf_Studies3 != '' ? TRUE : FALSE) : FALSE),
                    '#options' => $options_fieldOf_Studies3,
                    '#ajax' => array(
                                'callback' => 'ajax_example_dependent_dropdown_callback3',
                                'wrapper' => 'dropdown-four-replace'.$i,
                            ),           
                );  
    
    
    
            // Loading values in the 4th dropdown depends on the value selected in the third Dropdown
            if((isset($form_state['input']['field_of_studies_fieldset'][$i]['field_of_studies3']) && ($form_state['input']['field_of_studies_fieldset'][$i]['field_of_studies3']  != 0)))
            {
                $thirdVal = $form_state['input']['field_of_studies_fieldset'][$i]['field_of_studies3']; 
                $options_fieldOf_Studies4 = _ajax_example_get_second_dropdown_options1($thirdVal); 
            }
            else
            {// Loading values as "Select" intially
                $options_fieldOf_Studies4 = _ajax_example_get_second_dropdown_options1(0); 
            }
    
    
                $form['field_of_studies_fieldset'][$i]['field_of_studies4'] = array(
                    '#type' => 'select',
                    '#title' => t('Field of Studies4'), 
                    '#required' =>      (isset($form_state["values"]['field_of_studies_fieldset'][$i]['field_of_studies3']) ? ($options_fieldOf_Studies4 != '' ? TRUE : FALSE) : FALSE),
                    '#prefix' => '<div id="dropdown-four-replace'.$i.'"><div class="container-inline bottom_space field_of_studies_drop_down">',
                    '#suffix' => '</div></div></div>',
                    '#options' => $options_fieldOf_Studies4,
                );  
            }
    
            // Creating Remove Button
                if ($form_state['field_of_study_num'] > 1) 
                {
                    $form['field_of_studies_fieldset']['remove_name'] = array(
                            '#type' => 'submit',
                            '#value' => t('Remove one Field of Studies'),
                            '#limit_validation_errors' => array(),
                            '#submit' => array('remove_one_field_of_studies1'),             
                            '#ajax' => array(
                                'callback' => 'add_more_callback_field_of_studies1',
                                'wrapper' => 'div_names-fieldset-wrapper',                  
                            ),
                    );
                }
    
            // Creating Add One more Button
                $form['field_of_studies_fieldset']['add_name'] = array(
                    '#type' => 'submit',
                    '#value' => t('Add one more Field Of Studies'),
                    '#limit_validation_errors' => array(),
                    '#submit' => array('add_one_field_of_studies1'),
                    '#ajax' => array(
                        'callback' => 'add_more_callback_field_of_studies1',
                        'wrapper' => 'div_names-fieldset-wrapper',
                    ),
                );
    
                    $form['submit'] = array(
                    '#type' => 'submit',
                    '#value' => t('Submit'),
                    '#prefix' => '<div style="text-align:center;">',
                    '#suffix' => '</div></div>',
                 );         
                return $form;
            }
            /**
             * Callback for both ajax-enabled buttons.
             *
             * Selects and returns the fieldset with the names in it.
             */
            function add_more_callback_field_of_studies1($form, $form_state) {
                return $form['field_of_studies_fieldset'];
            }
    
            function add_more_callback_language2($form, $form_state) {
                return $form['languages'];
            }
    
    
    
            /**
             * Submit handler for the "add-one-more" button.
             *
             * Increments the max counter and causes a rebuild.
             */
            function add_one_field_of_studies1($form, &$form_state) {
                $form_state['field_of_study_num']++;
                    $form_state['rebuild'] = TRUE;
            }
    
            function add_one_language2($form, &$form_state) {
                $form_state['language_num']++;
                $form_state['rebuild'] = TRUE;
            }
            /**
             * Submit handler for the "remove one" button.
             *
             * Decrements the max counter and causes a form rebuild.
             */
            function remove_one_field_of_studies1($form, &$form_state) {
                if ($form_state['field_of_study_num'] > 1) {
                    $form_state['field_of_study_num']--;
                }
                $form_state['rebuild'] = TRUE;
            }
    
    
    
            /////////////////////////   Field of studies Dependent dropdown functions////////////////////////////////////
    
    
            function ajax_example_dependent_dropdown_callback1($form, $form_state) {
    
                    $commands = array();
                    $indexKey = substr($_POST['_triggering_element_name'], 26, 1); // Getting Iterations value $i value
    
                    $commands[] = ajax_command_replace("#dropdown-second-replace".$indexKey, render($form['field_of_studies_fieldset'][$indexKey]['field_of_studies2']));       
    
                        return array('#type' => 'ajax', '#commands' => $commands);
            }
    
            function ajax_example_dependent_dropdown_callback2($form, $form_state) {
    
                    $commands = array();
                    $indexKey = substr($_POST['_triggering_element_name'], 26, 1);  // Getting Iterations value $i value
    
                        $commands[] = ajax_command_replace("#dropdown-third-replace".$indexKey, render($form['field_of_studies_fieldset'][$indexKey]['field_of_studies3']));
    
                    return array('#type' => 'ajax', '#commands' => $commands);
    
            }
    
            function ajax_example_dependent_dropdown_callback3($form, $form_state) {
    
                    $commands = array();
                    $indexKey = substr($_POST['_triggering_element_name'], 26, 1);  // Getting Iterations value $i value
    
                        $commands[] = ajax_command_replace("#dropdown-four-replace".$indexKey, render($form['field_of_studies_fieldset'][$indexKey]['field_of_studies4']));
    
                    return array('#type' => 'ajax', '#commands' => $commands);
    
            }
    
    
            function _ajax_example_get_second_dropdown_options1($key)
            {       
    
                    if($key != 0)
                        {   
                            $option_Ajax_Values = _get_field_studies_mstr_ONE($key);    
                        }
                    else 
                        { 
                            $option_Ajax_Values =  array('Select' => t('Select'));  
                        }               
                    return $option_Ajax_Values;
            }
    

1 Answer 1

3

The function specified in the #ajax['callback'] can only return one element of the form (not including subsidiaries):

function test_form($form, $form_state) {
  $form['ajax_element'] = array(
    ...
    '#ajax' = array(
      'callback' => 'test_form_ajax_callback',
      'wrapper' => 'element1-wrapper', // or element2-wrapper, but not both at once
    ),
  );

  $form['element1'] = array(
    ...
    '#prefix' = '<div id="element1-wrapper">',
    '#suffix' = '</div>',
  );

  $form['element2'] = array(
    ...
    '#prefix' = '<div id="element2-wrapper">',
    '#suffix' = '</div>',
  );

  return $form;
}

function test_form_ajax_callback($form, $form_state) {
  return $form['element1']; // or $form['element2'], but not both at once
}

That's why you should use a common div-wrapper or fieldset for all child elements you want to update. For example:

    function mymodule_test_form($form, $form_state) {
          // div wrapper
          $form['terms'] = array(
            '#tree' => TRUE, 
            '#prefix' => '<div id="terms">', 
            '#suffix' => '</div>', 
          );

          $values = isset($form_state['values']['terms']) ? $form_state['values']['terms'] : array();
          $values += array('term' . (count($values)+1) => 'none');
          $parent = 0;
          foreach ($values as $input_name => $tid) {

        if ($parent === 'none' || !($terms = taxonomy_get_tree(1, $parent, 1))) {
          break;
        }

        // Data for Select
        $options = array('none' => '<none>');
        foreach ($terms as $term) {
          $options[$term->tid] = $term->name;
        }

        // Creating Select
        $form['terms'][$input_name] = array(
          '#type' => 'select',
          '#options' => $options,
          '#default_value' => $tid,
          '#ajax' => array(
            'callback' => 'mymodule_test_form_ajax_callback',
            'wrapper' => 'terms',
          ),
        );

        $parent = isset($options[$tid]) ? $tid : 'none';
      }

      $form['submit'] = array(
        '#type' => 'submit',
        '#value' => 'Submit',
      );

      return $form;
    }

    /**
     * AJAX callback
     */
    function mymodule_test_form_ajax_callback($form, $form_state) {
      return $form['terms'];
    }

But it's possible not always. So, in such case you should use #ajax['callback'] with set of commands instead of #ajax['wrapper']:

function test_form($form, $form_state) {
  $form['ajax_element'] = array(
    ...
    '#ajax' = array(
      'callback' => 'test_form_ajax_callback',
    ),
  );

  $form['element1'] = array(
    ...
    '#prefix' = '<div id="element1-wrapper">',
    '#suffix' = '</div>',
  );

  $form['element2'] = array(
    ...
    '#prefix' = '<div id="element2-wrapper">',
    '#suffix' = '</div>',
  );

  return $form;
}

function test_form_ajax_callback($form, $form_state) {
  $commands[] = ajax_command_insert('#element1-wrapper', drupal_render($form['element1']));
  $commands[] = ajax_command_insert('#element2-wrapper', drupal_render($form['element2']));
  return array('#type' => 'ajax', '#commands' => $commands);
}

And when you select your 1st element you should update all your next elements, not only 2nd

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.