2011-11-11 43 views
1

我的域看起來是這樣的:Grails中的已連接下拉列表

ProductLine hasMany Topic(s)hasMany Subtopic(s)。

關於Subtopic create.gsp視圖我想要有兩個下拉列表 - 第一個用於選擇ProductLine,然後在第二個下拉列表中顯示屬於先前選擇的ProductLine的主題。如何實現這一點?

回答

2

鏈接兩個下拉框起來不是太難,但鏈接三個或更多的可能是困難的第一次。下面我將三個下拉框鏈接在一起,但您應該能夠從此示例中獲得如何將任意數量的下拉框鏈接在一起。

在我的Load課程中,當我創建一個新實例時,我需要知道貨運商是誰,貨源是什麼以及貨物是什麼。例如,假設我有一個名叫ACME Rock的貨運商。那麼想象一下,ACME Rock有兩個地方可以提供貨物,123 Somewhere Road和456 Nowhere Road。這些地點將代表貨物來源。最後想象一下,每個貨源都提供不同的貨物。我們會想象,123 Somewhere Road只會產生Rock和456 Nowhere Road只會產生污垢。這裏所說的全部就是我的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)上一起鏈接這些下拉框。請記住在關閉body元素的</body>標記之前放置JavaScript。請注意,我正在使用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') 
} 

在這一點上你的鏈式下拉框應該正常工作。

+0

你應該得到更多的信貸:)不錯的工作! YYYYYYYYYYYYYYY – danielad

+0

我沒有TD轉儲的HTML我簡單地想覆蓋或更新我的當前下拉框從結果? – danielad

+0

@danielad對不起,但我不明白你在說什麼。 – ubiquibacon