我的域名看起来像这样:
ProductLine有很多主题有很多子主题。
在Subtopic create.gsp视图中我想要有两个下拉列表 - 首先选择ProductLine,然后在第二个我要显示属于以前选择的ProductLine的主题。如何实现这个?
答案 0 :(得分:2)
答案 1 :(得分:2)
将两个下拉框连在一起并不是太难,但第一次连接三个或更多可能很困难。下面我将三个下拉框链接在一起,但您应该能够从这个示例中得出如何将任意数量的下拉框链接在一起。
在我的Load
课程中,当我创建一个新实例时,我需要知道货物提供商是谁,使用了什么货源,以及货物是什么。例如,假设我有一家名为ACME Rock的货运提供商。然后想象一下,ACME Rock有两个位置,他们提供货物,123 Somewhere Road和456 Nowhere Road。这些地点将代表货物来源。最后想象一下,每个货源都提供不同的货物。我们会想象123 Somewhere Road只生产Rock而456 Nowhere Road只生产Dirt。所有这些都说明了我的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>
我们开始将这些下拉框与位于同一页面上的一些JavaScript(create.gsp)链接在一起。请记住将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
语句中。这就是为什么您在我的Load控制器的onchange: 'updateCargoes();
操作的render
语句中包含getCargoSources
以及正确执行我的应用程序所需的其他属性的原因。您包含的属性将根据您在视图中的确切操作而有所不同,我选择的属性非常标准。编写属性两次是一种烦恼,但它比在页面加载时将整个数据集加载到下拉框中更好,这取决于您拥有的数据量可能非常低效。
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')
}
此时,您的链式下拉框应该正常工作。