我使用wicket listview为每一行创建了一个复选框和一个文本字段。
当用户选中复选框时,我可以设置相关的布尔值 成功地。
但我需要加以限制。只有一个复选框 选择以下列结构提交表格。
Textarea复选框 Textarea复选框 Textarea复选框 Textarea复选框
当我取消设置我选中的复选框时,我删除了输入textareas的文本。 据我所知,以下行用于防止此问题,但它不起作用。你有什么主意吗?
listView.setReuseItems(true);
public class CheckBoxListPage extends WebPage {
private Form inputForm;
public CheckBoxListPage()
{
add(inputForm = new InputForm("inputForm"));
}
private class InputForm extends Form
{
private List<NameWrapper> data;
public InputForm(String name)
{
super(name);
data = new ArrayList<NameWrapper>();
data.add(new NameWrapper("one"));
data.add(new NameWrapper("two"));
data.add(new NameWrapper("three"));
data.add(new NameWrapper("four"));
final ListView<NameWrapper> listView = new ListView<NameWrapper>("list", data)
{
protected void populateItem(ListItem<NameWrapper> item) {
final NameWrapper wrapper = (NameWrapper)item.getModelObject();
item.add(new Label("name", wrapper.getName()));
final CheckBox checkBox = new CheckBox("check", new PropertyModel<Boolean>(wrapper, "selected"));
item.add(checkBox);
checkBox.add(new OnChangeAjaxBehavior() {
@Override
protected void onUpdate(AjaxRequestTarget target) {
if (wrapper.getSelected()) {
for (NameWrapper entity : data) {
if (!entity.equals(wrapper)) {
entity.setSelected(Boolean.FALSE);
}
}
}
target.addComponent(inputForm);
}
});
}
};
listView.setReuseItems(true);
add(listView);
}
}
答案 0 :(得分:1)
如果您在代码中包含了如何构建这些textareas,并且将它们添加回AjaxRequestTarget
,那将会很有帮助。
无论如何,我看到你正在尝试实现服务器端行为来制作你可以做客户端的东西(实际上,它是一个客户端操作)。你可以更好地取消选中客户端的所有其他复选框,例如,使用javascript。
您可以制作Component
工具IHeaderContributor
,并将复选框'HTML id
属性输出到Javascript。然后,每个复选框都可以有一个onchange
事件处理程序,您可以在其中取消选中所有其他复选框,并使用document.getElementById()
选择它们。
使用这种方法,您不需要setReuseItems(true)
。如果您将ListView
写回AjaxRequestTarget
,setReuseItems()
将帮助您保留在第一次执行Components
时实例化的populateItem()
(即,他们将保持相同的markupId)。通常,如果您需要管理ListView
内的组件状态,建议您使用setReuseItems(true)
。在这种情况下,这是在客户端完成的,因此乍一看没有必要。
例如:
private class InputForm extends Form implements IHeaderContributor {
private List<String> checkboxIds = new ArrayList();
//...
protected void populateItem(ListItem<NameWrapper> item) {
// PropertyModel can be used on Models, too,
// not necessarily modelObejcts.
IModel checkboxModel = new PropertyModel<Boolean>(item.getModel(), "selected"));
final CheckBox checkBox = new CheckBox("check", checkboxModel);
checkBox.setOutputMarkupId(true);
// If checkboxMarkupId is null at this point,
// you can always set it this way
// checkBox.setMarkupId("check" + item.getIndex());
String checkboxMarkupId = checkBox.getMarkupId();
checkboxIds.add(checkboxMarkupId);
item.add(checkBox);
String js = "deselectChecks('" + checkboxMarkupId + "');";
checkbox.add(new SimpleAttributeModifier("onchange", js));
}
//...
public void renderHead(IHeaderResponse response) {
String jsArrDecl = "var checkIds = [";
for (String checkId : checkboxIds){
jsArrDecl += "'" + checkId + "', ";
}
jsArrDecl = jsArrDecl.substring(0, jsArrDecl.length()-1);
jsArrDecl += "];";
response.renderOnDomReadyJavascript(jsArrDecl);
}
}
Javascript:
function deselectChecks(selected){
for each (var checkId in checkIds) {
if (checkId != selected){
document.getElementById(checkId).checked = false;
}
}
}
您可以将onchange="deselectChecks(this.id);"
附加到HTML文件中的复选框,或者在Java类中添加SimpleAttributeModifier
。
与往常一样,您还应该实施此限制/行为服务器端,以防止没有javascript的用户绕过它。我建议FormValidator
这样做。