列表视图中的wicket textarea在取消设置ajaxcheckbox时被清除

时间:2011-10-13 12:37:33

标签: java listview wicket

我使用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); 
            }             
    } 

1 个答案:

答案 0 :(得分:1)

如果您在代码中包含了如何构建这些textareas,并且将它们添加回AjaxRequestTarget,那将会很有帮助。

无论如何,我看到你正在尝试实现服务器端行为来制作你可以做客户端的东西(实际上,它是一个客户端操作)。你可以更好地取消选中客户端的所有其他复选框,例如,使用javascript。

您可以制作Component工具IHeaderContributor,并将复选框'HTML id属性输出到Javascript。然后,每个复选框都可以有一个onchange事件处理程序,您可以在其中取消选中所有其他复选框,并使用document.getElementById()选择它们。

使用这种方法,您不需要setReuseItems(true)。如果您将ListView写回AjaxRequestTargetsetReuseItems()将帮助您保留在第一次执行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这样做。