1

I am working on a dynamic set of three multiple select list which will function as one field which can be placed inside a form. The options in the second and third select lists will be set based upon the selection in the first and second selects.

Here is how I create the widget:

function multiselect_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
    $options_first = multiselect_first_dropdown_options();
    $value_dropdown_first = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first);

    $form['dropdown_first'] = array(
        '#type' => 'select',
        '#multiple' => TRUE,
        '#title' => 'First Dropdown',
        '#options' => $options_first,
        '#default_value' => $value_dropdown_first,
        '#ajax' => array(
            'event' => 'change',
            'callback' => 'multiselect_school_ajax_callback',
            'wrapper' => 'dropdown_second_replace',
        ),
    );
    $form['dropdown_second'] = array(
        '#type' => 'select',
        '#multiple' => TRUE,
        '#title' => 'Second Dropdown',
        '#prefix' => '<div id="dropdown_second_replace">',
        '#suffix' => '</div>',
        '#options' => multiselect_second_dropdown_options($value_dropdown_first),
        '#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',

        '#ajax' => array(
            'event' => 'change',
            'callback' => 'multiselect_class_ajax_callback',
            'wrapper' => 'dropdown_assignment_replace',
        ),
      );
      $form['dropdown_assignment'] = array(
        '#type' => 'select',
        '#multiple' => TRUE,
        '#title' => 'Second Dropdown',
        '#prefix' => '<div id="dropdown_assignment_replace">',
        '#suffix' => '</div>',
        '#options' => multiselect_second_dropdown_options($value_dropdown_first),
        '#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',
      );

  return $form;
}

And here is an example of one of my ajax callbacks:

function multiselect_school_ajax_callback($form, $form_state) {
      global $classes;
      $index = array_shift(array_values($form_state['values']['dropdown_first']));
      $selected_school = $form['dropdown_first']['#options'][$index];
      $class_array = multiselct_get_subgroups($selected_school, 'organization_group');
      $form['dropdown_second']['#options'] = $class_array;
      $classes = $class_array;
      return $form['dropdown_second'];
    }

When I set the options of the dropdown_second in my ajax callback, it causes the widget to be re-rendered with the correct contents but when I examine the value stored in $form['dropdown_second']['#options'] from any other hook the values I set are not preserved. If I set $form['dropdown_second']['#options'] from hook_form_alter() the values are preserved but hook_form_alter is not called after my ajax call. Is there some way to make these changes stick around from my ajax callback or force a hook_form_alter?

1
+50

You can refer the following example for creating Dependent select list

function multiselect_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
    $options_first = multiselect_first_dropdown_options();
    $value_dropdown_first = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first);

    $form['dropdown_first'] = array(
        '#type' => 'select',
        '#multiple' => TRUE,
        '#title' => 'First Dropdown',
        '#options' => $options_first,
        '#default_value' => $value_dropdown_first,
        '#ajax' => array(
            'event' => 'change',
            'callback' => 'multiselect_school_ajax_callback',
            'wrapper' => 'dropdown_second_replace',
        ),
    );
    $form['wrapper'] = array(
        '#prefix'  => '<div id="dropdown_second_replace">',
        '#suffix'  => '</div>',
    );
    if(!empty($form_state['values']['dropdown_first'])){
        // Code here or call function for  fetching value second and third dropdown
    }
    $form ['wrapper']['dropdown_second'] = array(
        '#type' => 'select',
        '#multiple' => TRUE,
        '#title' => 'Second Dropdown',
        '#prefix' => '<div id="dropdown_second_replace">',
        '#suffix' => '</div>',
        '#options' => multiselect_second_dropdown_options($value_dropdown_first),
        '#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',

        '#ajax' => array(
            'event' => 'change',
            'callback' => 'multiselect_class_ajax_callback',
            'wrapper' => 'dropdown_assignment_replace',
        ),
    );
    $form['wrapper']['dropdown_assignment'] = array(
        '#type' => 'select',
        '#multiple' => TRUE,
        '#title' => 'Second Dropdown',
        '#prefix' => '<div id="dropdown_assignment_replace">',
        '#suffix' => '</div>',
        '#options' => multiselect_second_dropdown_options($value_dropdown_first),
        '#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',
    );
    return $form;
}

The basic idea about above example is that use wrapper as a div which will have your second and third dropdown so on change of first drop down form state will be set so it will go into if condition than that will give you the value for the secoond and third drop down

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.