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

如何在Docassemble中通过Ajax/JS动态联动countries_list与states_list?

在Docassemble中实现国家-地区实时联动(同一页面)

核心实现思路

  • 用input type: ajax定义国家选择框,绑定前端JS触发事件
  • 通过自定义JS监听国家选择变化,向Docassemble后端请求对应地区列表和subdivision_type值
  • 实时更新地区下拉框的选项、标签文本,同时处理单一地区国家的自动填充/隐藏逻辑

完整代码实现

1. Docassemble YAML 配置

question: |
  请选择您所在的国家和地区
fields:
  - 国家: user_country
    input type: ajax
    choices: countries_list()
    js: |
      $(this).on('change', function() {
        updateSubdivisions($(this).val());
      });
  - id: subdivision_field
    地区: user_subdivision
    input type: select
    choices: []
    skip: True # 初始隐藏,后续根据AJAX结果控制显示

comment: |
  <script>
  function updateSubdivisions(countryCode) {
    // 发送AJAX请求获取地区数据
    $.ajax({
      url: '/api/questions',
      method: 'POST',
      data: JSON.stringify({
        "action": "get_subdivisions",
        "country": countryCode
      }),
      contentType: 'application/json',
      success: function(response) {
        const subdivisionField = $('#subdivision_field');
        const subdivisionLabel = subdivisionField.prev('label');
        const subdivisionSelect = subdivisionField.find('select');
        
        // 更新地区标签文本(如省/州/地区)
        subdivisionLabel.text(response.subdivision_type + ':');
        
        // 清空并填充地区选项
        subdivisionSelect.empty();
        response.subdivisions.forEach(function(option) {
          subdivisionSelect.append($('<option>', {
            value: option.code,
            text: option.name
          }));
        });
        
        // 处理单一地区的情况:自动选中并隐藏字段
        if (response.subdivisions.length === 1) {
          subdivisionSelect.val(response.subdivisions[0].code);
          // 自动提交选中值到后端
          $.ajax({
            url: '/api/set',
            method: 'POST',
            data: JSON.stringify({
              "user_subdivision": response.subdivisions[0].code
            }),
            contentType: 'application/json'
          });
          subdivisionField.parent().hide();
        } else {
          subdivisionField.parent().show();
          subdivision_field.set('skip', false); // 取消跳过,让系统验证该字段
        }
      },
      error: function() {
        alert('获取地区信息失败,请重试');
      }
    });
  }
  </script>

# 后端AJAX处理逻辑
code: |
  from docassemble.base.util import states_list, subdivision_type
  import json

  def get_subdivisions(country):
    subdivisions = states_list(country)
    # 转换为前端可用的格式
    formatted_subdivisions = [{'code': code, 'name': name} for code, name in subdivisions.items()]
    return {
      'subdivision_type': subdivision_type(country),
      'subdivisions': formatted_subdivisions
    }

  # 处理AJAX请求
  if request.method == 'POST' and 'action' in request.json and request.json['action'] == 'get_subdivisions':
    country_code = request.json.get('country')
    result = get_subdivisions(country_code)
    return json.dumps(result)

2. 关键细节说明

  • AJAX接口利用:通过Docassemble内置的/api/questions获取地区数据,/api/set提交选中的地区值到后端
  • 动态标签更新:直接修改页面上的标签元素文本,实时替换为subdivision_type()返回的对应地区类型名称
  • 单一地区自动处理:检测到地区列表长度为1时,自动选中该选项并隐藏下拉框,无需用户手动操作
  • 初始状态控制:地区字段初始设置skip: True,避免页面加载时显示空的下拉框

注意事项

  • 确保Docassemble项目默认的AJAX功能处于开启状态
  • 测试时需验证不同国家的地区数据返回准确性,尤其是单一地区的国家
  • 若需调整样式,可通过CSS自定义字段的显示/隐藏效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 21:52:50