You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Drupal 8中创建基于其他下拉框值的多级依赖下拉字段?

嗨,我来帮你搞定Drupal 8里的多级依赖下拉字段!这种逐级触发显示的需求其实很常见,我给你两种靠谱的实现方式,你可以根据自己的场景选:

方法一:用Conditional Fields模块(无代码快速实现)

如果你的需求只是简单的「前一个字段选了才显示下一个」,不需要动态修改选项内容,这个模块绝对是首选,零代码就能搞定:

  • 先安装并启用Conditional Fields模块(注意选对应Drupal 8的稳定版本)
  • 先在你的内容类型里创建好所有需要的下拉字段:比如第一个叫field_category(一级分类)、第二个field_subcategory(二级分类)、第三个field_item(具体项),都设为单选下拉类型
  • 配置依赖规则:
    • 进入内容类型的「表单显示」设置页面,找到第二个字段field_subcategory,点击它右侧的「条件」按钮
    • 设置依赖逻辑:当field_category被选中任意值(或者你可以指定特定值)时,才显示field_subcategory
    • 用同样的方式给第三个字段field_item设置依赖:当field_subcategory被选中值时,才显示它
  • 测试验证:保存配置后,去创建内容,就能看到第一个下拉选完,第二个才会出现;第二个选完,第三个才显示,完全符合你的要求
方法二:自定义代码实现(更灵活可控)

如果你的下拉选项需要动态从数据库读取,或者有更复杂的依赖逻辑(比如只有选特定值才触发),就需要用自定义模块来实现了,这里给你核心的实现步骤:

  1. 先创建一个自定义模块(比如叫custom_dependent_fields),先搞定基础的.info.yml和.module文件
  2. 在.module文件里添加以下代码,实现AJAX依赖和动态选项:
function custom_dependent_fields_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  // 替换成你自己的内容类型表单ID,比如"article_node_form"
  if ($form_id == 'article_node_form') {
    // 给第一个下拉字段添加AJAX事件
    $form['field_main_category']['#ajax'] = [
      'callback' => 'custom_dependent_fields_subcategory_ajax_callback',
      'wrapper' => 'subcategory-field-wrapper',
      'event' => 'change',
    ];

    // 用div包装第二个字段,方便AJAX刷新
    $form['field_sub_category']['#prefix'] = '<div id="subcategory-field-wrapper">';
    $form['field_sub_category']['#suffix'] = '</div>';

    // 根据第一个字段的值,控制第二个字段的可见性和选项
    $main_category = $form_state->getValue('field_main_category');
    if (empty($main_category)) {
      $form['field_sub_category']['#access'] = FALSE;
    } else {
      // 这里示例用分类术语加载子选项,替换成你的词汇表机器名
      $subcategories = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree('subcategory_vocab', $main_category[0]['target_id']);
      $options = [];
      foreach ($subcategories as $term) {
        $options[$term->tid] = $term->name;
      }
      $form['field_sub_category']['widget'][0]['#options'] = $options;
      $form['field_sub_category']['#access'] = TRUE;

      // 同理给第二个字段添加AJAX,控制第三个字段
      $form['field_sub_category']['#ajax'] = [
        'callback' => 'custom_dependent_fields_item_ajax_callback',
        'wrapper' => 'item-field-wrapper',
        'event' => 'change',
      ];

      $form['field_item']['#prefix'] = '<div id="item-field-wrapper">';
      $form['field_item']['#suffix'] = '</div>';

      $sub_category = $form_state->getValue('field_sub_category');
      if (empty($sub_category)) {
        $form['field_item']['#access'] = FALSE;
      } else {
        // 动态加载第三个字段的选项
        $items = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree('item_vocab', $sub_category[0]['target_id']);
        $item_options = [];
        foreach ($items as $term) {
          $item_options[$term->tid] = $term->name;
        }
        $form['field_item']['widget'][0]['#options'] = $item_options;
        $form['field_item']['#access'] = TRUE;
      }
    }
  }
}

// 二级分类的AJAX回调函数
function custom_dependent_fields_subcategory_ajax_callback(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
  return $form['field_sub_category'];
}

// 具体项的AJAX回调函数
function custom_dependent_fields_item_ajax_callback(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
  return $form['field_item'];
}

代码说明:

  • 用hook_form_alter()修改目标内容类型的表单,给每个下拉字段绑定change事件的AJAX回调
  • 根据前一个字段的选中值,通过#access属性控制当前字段的可见性,同时动态加载对应的选项列表
  • AJAX回调负责刷新对应的字段区域,实现无刷新更新

注意事项:

  • 替换代码里的表单ID、字段名、词汇表机器名为你自己的实际内容
  • 启用自定义模块后,记得清一下Drupal缓存,避免看不到效果
  • 如果你的下拉选项不是分类术语,也可以换成从自定义表或者其他实体加载数据的逻辑

内容的提问来源于stack exchange,提问作者Vatsal Khanna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:11:20