Thymeleaf中从地图创建依赖下拉列表

5
我希望创建一个下拉列表,其中包含国家名称,并且第二个下拉列表将根据第一个列表中选择的值进行更改。城市列表应该是动态变化的。 在视图(Thymeleaf)中,我从控制器获得了一个Map<CountryModel, Set<RegionModel>>。 国家模型的名称应该显示在第二个下拉列表中,而Set应该显示在第二个(依赖于第一个)下拉列表中。
这里我创建第一个下拉列表:
 <tr>
   <td th:text="#{country}"/>
   <td>
      <div class="form-group">
          <select th:field="*{transferRequestModel.country}" class="form-control" id="country">
                <option th:each="country : ${transferModel.countries}"
                    th:value="${country}"
                    th:text="${country.key.countryName}">Wireframe
                </option>
          </select>
      </div>
    </td>
 </tr>

那么如何创建一个依赖于第一个列表中选择的国家的第二个下拉列表呢?

页面渲染完成后,如果您想动态更改一个下拉菜单,则需要使用JavaScript进行处理。请查看http://stackoverflow.com/questions/22219749/html-dropdown-menu-change-dynamically - Balaji Krishnan
2个回答

11

所以我通过AJAX请求和jQuery append解决了我的问题。

  1. Change Map<CountryModel, Set<RegionModel>> to Map<String, Set<String>>

  2. AJAX request

    function sendAjaxRequest() {
        var country = $("#country").val();
        $.get( "/regions?country=" + country, function( data ) {
            $("#region").empty();
            data.forEach(function(item, i) {
                var option = "<option value = " + item + ">" + item +  "</option>";
                $("#region").append(option);
            });
        });
    };
    
  3. Use sendAjaxRequest() when i change first drop-down list.

    $(document).ready(function() {
        $("#country").change(function() {
            sendAjaxRequest();
        });
    });
    
  4. Drop-down list at the Thymeleaf template

第一个下拉列表

<td th:text="#{country}"/>
<td>
    <div class="form-group">
        <select th:field="*{model.country}" class="form-control" id="country">
            <option th:each="country : ${model.countries}"
                    th:value="${country}"
                    th:text="${country}">Wireframe
            </option>
        </select>
    </div>
</td>

第二个下拉菜单

<td>
    <div class="form-group">
        <select th:field="*{requestModel.region}" class="form-control" id="region">
        </select>
    </div>
</td>
  1. Controller

    @RequestMapping(value = "/regions")
    @ResponseBody
    public Set getRegions(@RequestParam String country) {
        Map<String, Set<String>> regions = regionsService.getRegions();
        return regions.get(country);
    }
    

如何使用AngularJS Watch来实现,而不是使用jQuery。我的选择框没有ng-model,因为我使用Thymeleaf,而ng-change需要一个ng-model。因此,我正在尝试在Angular中监视元素并触发ajax调用以获取新值。 - Mukun

0
在我们的项目中,我们是这样做的:
<div class="form-group">
    <label class="col-sm-4 control-label" 
           th:text="#{person.edit.policy.tfoms}"></label>

    <div class="col-sm-8">
        <select class="form-control" th:field="*{tfoms}" 
                onchange="loadInsuranceCompanies()">
            <option th:each="t : ${tfomses}" 
                    th:value="${t.uidtfoms}"  
                    th:text="${t.shortName}"
                    th:selected="${personBean.tfoms != null 
                    and personBean.tfoms.equals(t)}">
            </option>
        </select>
    </div>
</div>
<div th:class="${#fields.hasErrors('insuranceCompany')} 
     ? 'form-group has-error' : 'form-group'">
    <label class="col-sm-4 control-label" 
          th:text="#{person.edit.policy.ic}">
    </label>

    <div class="col-sm-8" id="insuranceCompaniesContent">
        <select class="form-control" id="insuranceCompany" 
                name="insuranceCompany"  
                th:fragment="insuranceCompany">
            <option th:each="i : ${insuranceCompanies}" 
                    th:value="${i.uidinsurancecompany}"  
                    th:text="${i.shortName}"
                    th:selected="${personBean.insuranceCompany != null 
                    and personBean.insuranceCompany.equals(i)}">
            </option>
        </select>
        <div th:if="${#fields.hasErrors('insuranceCompany')}" 
         th:each="err : ${#fields.errors('insuranceCompany')}">
        <span class="text-danger" th:text="${err}"></span><br/>
        </div>
    </div>
</div>

保险公司加载函数loadInsuranceCompanies()

function loadInsuranceCompanies() {
    var url = /*[[@{/PersonEdit/insuranceCompanies}]]*/ "/PersonEdit/insuranceCompanies";
    if ($('#tfoms').val() !== '') {
        url = url + '/' + $('#tfoms').val();
    }
    $("#insuranceCompaniesContent").load(url);
}

最后,在控制器中编写代码:

@RequestMapping(value = "/PersonEdit/insuranceCompanies/{tfoms}", method = RequestMethod.GET)
public String getInsuranceCompaniesByTfoms(@PathVariable("tfoms") Integer tfomsId,
        Model model) {
    model.addAttribute("insuranceCompanies", insuranceCompanyService
            .getInsuranceCompaniesByTfoms(new TerritorialFondOms(tfomsId)));
    return "person/PersonEdit :: insuranceCompany";
}

如果您重新加载保存的数据,如何管理加载预填充(即在页面加载时)的依赖列表? - niksvp
如果我理解你的问题正确——依赖输入是通过JavaScript函数在页面加载时加载的。 - sanluck
依赖输入通过loadInsuranceCompanies函数加载,但是该函数仅在父级下拉框的onChange事件中调用。 - niksvp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接