在 drupal 7 中使用 hook_field_widget_form 级联 select 列表作为自定义字段

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

问题

我已经为自定义字段编写了一个 Drupal 自定义模块。 该字段包含三个级联的 select 列表。 我正在使用 javascript.

填充列表

现在我需要将其填充到 "hook_field_widget_form" 钩子中。

我的hook_field_widget_form如下:

/**
 * 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;
}

由于我使用 javascript 填充 select 列表,因此每个 $element 中都没有“#options”。

我在谷歌上搜索了很多有关如何在挂钩方法中填充级联 select 列表的信息。

到目前为止,我有 AJAX 回调方法来填充 select 列表。 但是我看不懂这个方法。

假设我有 2 个 select 列表,名为 "post" 和 "bynavn"。对于这 2 个 select 列表,我必须在挂钩方法中编写以下内容:

$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,
    );

回调函数如下:

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'];
}

但它不能填充第二个 select 列表。

如果有人给我一些 link 相关文档或给出解释 AJAX 回调方法如何工作的答案,这对我会有帮助。

提前致谢。

我自己解决了这个问题。在之前的版本中-

  1. 我在 "hook_field_widget_form" 函数中创建了没有“#options”的初始 select 列表。

  2. 我使用 javascript 填充了分区列表。然后在 selecting 划分之后,我填充了地区列表,并通过 selecting 地区填充了类似的列表。

提交表单时出现错误。

现在-

我已经在 "custom_select_list_field_widget_form" 函数中声明了初始 Division 列表、District 列表和 Thana 列表。

$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',
);

然后将这三个数组赋给$element中的三个选项如下:

 $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,
 );

然后保持 javascript 部分与之前相同。这对我有用。