2016-08-22 28 views
0

在我的Web應用程序中,我有許多帶有組件列表的表單,用戶可以動態地添加/刪除這些組件。例如,在輸入有關自己的信息時,用戶可能會添加包含其子女姓名的多個文本字段。每個組件都有一個刪除鏈接,並且還有添加鏈接以添加新組件。 的標記看起來是這樣的:Wicket - 帶添加/刪除功能的表單組件列表

<div> 
    <div wicket:id="rows"> 
     <input type="text" wicket:id="name"/> 
     <a wicket:id="remove">Remove</a> 
    </div> 
    <a wicket:id="add">Add</a> 
</div> 

中行是一個檢票口轉發。

輸入組件因列表而異(可能是下拉列表或其他內容,可能會添加不同的驗證程序,等等),但鏈接保持不變。他們的標記和邏輯不會改變。 因爲我的表單中有很多這樣的列表,所以我有makup和代碼重複。 我想有是讓我輸入組件的標記的形式,而擺脫這些鏈接的,是這樣的:

<div wicket:id="dynamicList"> 
    <input type="text" wicket:id="name"/> 
</div> 

這將被渲染爲具有附加文本字段列表/刪除鏈接。

我知道我必須有鏈接的標記,比如自動生成或將它們放在面板或其他東西中,我只是不想每次都複製它們。

UPD: 下面是建議的解決方案的標記使用Border組件(沒有工作): ListBorder.html:

<wicket:border> 
    <div wicket:id="rows"> 
     <wicket:body/> 
     <a wicket:id="remove">Remove</a> 
    </div> 
    <a wicket:id="add">Add</a> 
</wicket:border> 

MyForm.html:

<form wicket:id="form"> 
    ... 
    <div wicket:id="dynamicList"> 
     <input type="text" wicket:id="name"/> 
    </div> 
    ... 
</form> 
+0

你能提供你的添加/刪除鏈接如何工作的片段嗎?另外,你使用的是中繼器? – WiseTree

+0

我正在使用基於Wicket in Action [blog](http://wicketinaction.com/2008/10/building-a-listeditor-form-component/)中的示例的RepeatingView,其中還介紹了這些鏈接的工作原理。但我認爲這更多關於如何安排標記... – koszek

回答

1

我想在你描述的問題中有幾個不同的方面。首先,你想包裝一個輸入,使得刪除鏈接將被添加到 。你想要重複這個包裝輸入。最後,你想在重複輸入結尾附加一個添加鏈接。最後你希望把這件事全部包裝在一個組件中。

首先,添加刪除鏈接到輸入。這是您可以使用Border的地方。正如你可能推斷出,它看起來像

<wicket:border> 
    <wicket:body/> 
    <a wicket:id="remove">Remove</a> 
</wicket:border> 

然後重複此整個邊界,實現與自動刪除鏈接多個輸入。

爲了在問題的其餘部分達到您想要的確切行爲,您可以通過覆蓋Component#onComponentTag()來完成。您可以手動添加鏈接的HTML,如

@Override 
protected void onRender() { 
    super.onRender(); 
    Response response = getResponse(); 
    String url = generateAddUrl(); 
    response.write("<a href=\"" + url + "\">Add</a>");   
} 

您生成URL的方式非常棘手。我不打算介紹它(因爲我認爲你所要求的確切行爲不可行 - 我會在一秒內解釋其原因),但可以使用Link#getUrl()的源代碼作爲起點。

或者,您可以編寫自己的Component實現,它將掃描其標記的主體,然後基於此實現您想要的內容。顯然,這不是一個快速的解決方案,但如果您所描述的用例足夠大,從長遠來看可能會更好。

但最後我相信更好的解決方案將是爲每種類型的輸入(即輸入,選擇等)提供一個Panel,其標記結構以您想要的方式構建,並通過wicket行爲提供必要的標記更改AttributeAppender等等。這當然意味着一些html最終會出現在Java的東西上,這並不理想,但這種解決方案可以很好地工作,並且可以快速設置。

+0

我嘗試使用邊框,但它似乎不能與中繼器一起工作,甚至有[錯誤報告](https://issues.apache.org/jira/瀏覽/ WICKET-2493)。他們說邊界不應該用在中繼器中。 – koszek

+0

我開始認爲重複這些鏈接的標記並不是那麼糟糕,但事實證明,當您添加一個項目時,您需要刷新列表以顯示該項目,並且無法刷新中繼器本身,您需要刷新父容器。因此,必須有一個用於此目的的周圍容器,這是我絕對想要避免的那種重複。 – koszek

+0

我認爲你仍然可以實現你想要的邊界,儘管稍有不同。我會編輯我的答案以表明我的意思。 – WiseTree