Cascaded select list as a custom field using hook_field_widget_form in drupal 7

做~自己de王妃 提交于 2020-01-05 08:06:02

问题


Problem

I have written a Drupal custom module for a custom field. The field contains three cascaded select list. I am populating the lists using javascript.

Now I need to populate it inside "hook_field_widget_form" hook.

My hook_field_widget_form is as below:

/**
 * Implements hook_field_widget_form().
 */
function custom_select_list_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
    $node = menu_get_object();
  
    $division = isset($node->field_division_custom_select['und'][0]['division']) ? $node->field_division_custom_select['und'][0]['division'] : '';
    $district = isset($node->field_division_custom_select['und'][0]['district']) ? $node->field_division_custom_select['und'][0]['district'] : '';
    $thana = isset($node->field_division_custom_select['und'][0]['thana']) ? $node->field_division_custom_select['und'][0]['thana'] : '';

    drupal_add_js(array('custom_select_list' => array('division' => $division, 'district' => $district, 'thana' => $thana )), array('type' => 'setting'));

    switch ($instance['widget']['type']) {
        case 'custom_field_widget' :
            $element['custom_select_field'] = array(
                '#type' => 'fieldset',
                '#title' => $element['#title'],
                '#tree' => TRUE,
            );
            $element['custom_select_field']['division'] = array(
                '#type' => 'select',
                '#title' => t('Division'),
                '#default_value' => isset($items[$delta]['division']) ? $items[$delta]['division'] : isset($node->field_division_custom_select['und'][0]['division']) ? $node->field_division_custom_select['und'][0]['division'] : '',
                '#required' => $element['#required'],
                '#id' => 'division-select-list',
                '#attributes' => array('class' => array('selectpicker'), 'title' => t('Thana') ),
            );
            $element['custom_select_field']['district'] = array(
                '#type' => 'select',
                '#title' => t('District'),
                '#default_value' => isset($items[$delta]['district']) ? $items[$delta]['district'] : isset($node->field_division_custom_select['und'][0]['district']) ? $node->field_division_custom_select['und'][0]['district'] : '',
                '#required' => $element['#required'],
                '#id' => 'district-select-list',
                '#attributes' => array( 'class' => array('selectpicker'), 'title' => t('Thana') ),
            );
            $element['custom_select_field']['thana'] = array(
                '#type' => 'select',
                '#title' => t('Thana'),
                '#default_value' => isset($items[$delta]['thana']) ? $items[$delta]['thana'] : isset($node->field_division_custom_select['und'][0]['thana']) ? $node->field_division_custom_select['und'][0]['thana'] : '',
                '#required' => $element['#required'],
                '#id' => 'thana-select-list',
                '#attributes' => array('class' => array('selectpicker'), 'title' => t('Thana') ),
            );
            break;
    }
    return $element;
}

Since I am populating the select lists using javascript there is no '#options' in each $element.

I have googled a lot for how to populate cascaded select lists inside hook method.

So far I have got AJAX callback method to populate select lists. But I could not understand the method.

Suppose I have 2 select list named "post" and "bynavn". for these 2 select lists I have to write the following in hook method:

$element['post'] = array(
        '#type' => 'select',
        '#title' => t('post'),
        '#default_value' => isset($items[$delta]['post']) ? $items[$delta]['post'] : NULL,
        '#options' => array(
            '1' => 'One',
            '2' => 'Two',
        ),
        '#ajax' => array(
            'callback' => 'dad_test_callback',
            'wrapper' => 'test-div',
        ),
    );

 $element['bynavn'] = array(
        '#type' => 'select',
        '#title' => t('Bynavn'),
        '#prefix' => '<div id="test-div">',
        '#suffix' => '</div>',
        '#default_value' => isset($items[$delta]['bynavn']) ? $items[$delta]['bynavn'] : NULL,
    );

and the callback function is as follows:

function dad_test_callback($form, $form_state) {
    $field_name = $form_state['custom_select_list']['field_data']['field_name'];
    $delta = $form_state['custom_select_list']['field_data']['delta'];
    $langcode = $form_state['custom_select_list']['field_data']['langcode'];
    $arr = array(
        '3' => 'Two',
        '1' => 'one',
        '2' => 'Three',
    );
    $form[$field_name][$langcode][$delta]['bynavn']['#options'] = $arr;
    return $form[$field_name][$langcode][$delta]['bynavn'];
}

But It can not populate the second select list.

If someone give me some link to related documentation or give an answer explaining how does AJAX callback method work it would be helpful for me.

thanks in advance.


回答1:


I have solved the issue myself. In previous version-

  1. I created initial select list with no "#options" in "hook_field_widget_form" function.

  2. I populated the division list using javascript. Then after selecting division I populated district list and similarly populated thana list by selecting district.

Which generated error when I submit the form.

Now -

I have declared initial Division list, District list and Thana list inside "custom_select_list_field_widget_form" function.

$division_arr = array(
  '1' => 'Division 1',
  '2' => 'Division 2',
  '3' => 'Division 3',
  '4' => 'Division 4',
  '5' => 'Division 5',
);

$district_arr = array(
  '1' => 'District 1',
  '2' => 'District 2',
  '3' => 'District 3',
  '4' => 'District 4',
  '5' => 'District 5',
);

$thana_arr = array(
  '1' => 'Thana 1',
  '2' => 'Thana 2',
  '3' => 'Thana 3',
  '4' => 'Thana 4',
  '5' => 'Thana 5',
);

Then assign these three array to three options in $element as follows:

 $element['custom_select_field']['division'] = array(
   ....
   ....
   '#options' => $division_arr,
 );

$element['custom_select_field']['district'] = array(
   ....
   ....
   '#options' => $district_arr,
 );

$element['custom_select_field']['thana'] = array(
   ....
   ....
   '#options' => $thana_arr,
 );

Then kept the javascript portion same as before. That worked for me.



来源:https://stackoverflow.com/questions/39405925/cascaded-select-list-as-a-custom-field-using-hook-field-widget-form-in-drupal-7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!