2016-08-22 45 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