我使用 wicket listview 为每一行创建了一个复选框和一个文本字段。
当用户选择复选框时,我可以设置相关的 boolean 值 成功了。
但我需要施加限制。只能有一个复选框 选择提交以下结构的表格。
Textarea checkbox Textarea checkbox Textarea checkbox Textarea checkbox
当我取消选中的复选框时,我在文本区域中输入的文本将被删除。 据我所知,以下行用于防止此问题,但它不起作用。你有什么主意吗?
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);
}
}
最佳答案
如果您在代码中包含如何构建这些文本区域,以及是否将它们添加回 AjaxRequestTarget
,将会很有帮助。
无论如何,我看到您正在尝试实现服务器端行为,以使您可以在客户端执行某些操作(实际上,这是客户端操作)。您最好取消选中客户端的所有其他复选框,例如使用 javascript。
您可以使您的Component
实现IHeaderContributor
,并将复选框的HTML id
属性输出到Javascript。然后,每个复选框都可以有一个 onchange
事件处理程序,您可以在其中取消选中使用 document.getElementById()
选择它们的所有其他复选框。
使用这种方法,您将不需要 setReuseItems(true)
。如果您将 ListView
写回到 AjaxRequestTarget
,setReuseItems()
将帮助您保留在第一次执行 populateItem()
时实例化的相同 Components
(即,它们将保留相同的 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
来达到此目的。
关于java - 取消设置 ajaxcheckbox 时, ListView 中的 wicket 文本区域会被清除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7754236/