Grails中的连接下拉列表



我的域名看起来像这样:

ProductLine hasMany Topic(s) hasMany Subtopic(s).

On Subtopic create。在gsp视图中,我希望有两个下拉框——第一个下拉框用于选择ProductLine,然后在第二个下拉框中,我希望显示属于先前选择的ProductLine的主题。如何实现这一点?

将两个下拉框链接在一起并不太难,但是将三个或更多的下拉框链接在一起第一次可能会很困难。下面我将三个下拉框链接在一起,但是您应该能够从这个示例中推导出如何将任意数量的下拉框链接在一起。

在我的Load类中,当我创建一个新实例时,我需要知道谁是货物提供者,使用了什么货物来源,以及货物是什么。例如,假设我有一个名为ACME Rock的货物提供程序。然后想象ACME Rock有两个提供货物的地点,123 Somewhere Road和456 Nowhere Road。这些地点将代表货物来源。最后,假设每个货源提供不同的货物。我们可以想象123某处路只产生岩石,而456某处路只产生泥土。下面是Load类的创建视图(create.gsp)中的下拉框。

        <tr class="prop">
            <td valign="top" class="name">
                <label for=cargoProvider"><g:message code="load.cargoProvider.label" default="Cargo Provider"/></label>
            </td>
            <td valign="top" class="value ${hasErrors(bean: loadInstance, field: 'cargoProvider', 'errors')}">
                <g:select from="${cargoProviders}" id="cargoProvider.id" name="cargoProvider.id" noSelection="['':'-Select-']" optionKey="id" optionValue="${{it.businessName?.toString() + ': ' + it?.toString()}}" value="${loadInstance?.cargoProvider?.id}"/>
            </td>
        </tr>
        <tr class="prop">
            <td valign="top" class="name">
                <label for="cargoSource"><g:message code="load.cargoSource.label" default="Cargo Source"/></label>
            </td>
            <td id="cargoSourceCell" valign="top" class=" value ${hasErrors(bean: loadInstance, field: 'cargoSource', 'errors')}">
                <g:select from="${loadInstance?.cargoSource}" id="cargoSource.id" name="cargoSource.id" optionKey="id" value="${loadInstance?.cargoSource?.id}"/>
            </td>
        </tr>
        <tr class="prop">
            <td valign="top" class="name">
                <label for="cargo"><g:message code="load.cargo.label" default="Cargo"/></label>
            </td>
            <td id="cargoCell" valign="top" class="value ${hasErrors(bean: loadInstance, field: 'cargo', 'errors')}">
                <g:select from="${loadInstance?.cargo}" id="cargo.id" name="cargo.id" optionKey="id" value="${loadInstance?.cargo?.id}"/>
            </td>
        </tr>

我们开始将这些下拉框与位于同一页面(create.gsp)上的一些JavaScript链接在一起。记得把你的JavaScript放在关闭body元素的</body>标签之前。请注意,我使用的是jQuery,而不是Prototype。

<g:javascript>
    $(document).ready(function() {
        $("#cargoProvider\.id").change(function() {
            var cargoSourceValue = $("#cargoSource\.id").val();
            $.ajax({
                url: "/truckingmanagement/load/getCargoSources",
                data: "id=" + this.value,
                dataType: 'html',
                cache: false,
                success: function(result) {
                    $("#cargoSourceCell").html(result);
                    $("#cargoSource\.id").val(cargoSourceValue);
                    $("#cargoSource\.id").trigger('change');
                }
            });
        });
    });
</g:javascript>
<g:javascript>
    function updateCargoes() {
        var data = ($("#cargoSource\.id").val() == null) ? "" : $("#cargoSource\.id").val();
        var cargoValue = $("#cargo\.id").val();
        $.ajax({
            url: "/truckingmanagement/load/getCargoes",
            data: "id=" + data,
            dataType: 'html',
            cache: false,
            success: function(result) {
                $("#cargoCell").html(result);
                $("#cargo\.id").val(cargoValue);
            }
        });
    }
</g:javascript>

乍一看,updateCargoes函数似乎没有做任何事情,但它实际上是。当在第一个下拉框中进行选择时,第二个下拉框将使用Load控制器中的Grails render语句生成的HTML填充。这实际上用一个新下拉框替换了原来的下拉框,因此,我最初写在下拉框中的任何属性都将丢失,除非它们也包含在render语句中。这就是为什么您会看到onchange: 'updateCargoes();包含在下面Load控制器的getCargoSources动作的render语句中,以及正确执行应用程序所需的其他属性。您包含的属性将根据您想在视图中做什么而变化,我选择的属性是非常标准的。写两次属性很烦人,但这比在加载页面时将整个数据集加载到下拉框中要好,后者可能非常低效,这取决于您有多少数据。

def getCargoSources = {
    if(params.id == ""){
        render g.select(name: 'cargoSource.id', onchange: 'updateCargoes(); updateTotal()')
        return
    }
def getCargoes = {
    if(params.id == ""){
        render g.select(name: 'cargo.id', onchange: 'updateTotal()')
        return
    }
    def cargoSource = Address.get(params.id)
    def cargoes = Cargo.findAll("from Cargo as cargoes where cargoes.cargoSource=:cargoSource", [cargoSource: cargoSource])
    render g.select(from: cargoes,  name: 'cargo.id', noSelection: noSelection, onchange: 'updateTotal()', optionKey: 'id')
} 

此时链接的下拉框应该可以正常工作了。

http://blog.osx.eu/2010/04/13/creating-dependent-selects-in-grails/

http://www.grails.org/AJAX-Driven +选择+在+ GSP

最新更新