开发者

wicket textarea in listview is cleared when unset the ajaxcheckbox

I created one checkbox and one textfield for each line using wicket listview.

When the user selects the checkbox I am able to set the related boolean value succesfully.

But I needed to put a restriction. Only one checkbox can be selected to submit the form in the following structure.

Textarea checkbox Textarea checkbox Textarea checkbox Textarea checkbox

The text that I typed into the textareas are removed when I unset the checkbox that I selected. As far as I know the following line is used to prevent this problem but it doesnt work. Do you have any idea?

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); 
                                              开发者_StackOverflow中文版                      } 
                                                            } 
                                                    } 
                                                    target.addComponent(inputForm); 
                                            }                                              
                                    }); 
                            } 
                    }; 
                listView.setReuseItems(true); 
                add(listView); 
            }             
    } 


It would be helpful if you included in the code how are you building those textareas, and if you're adding them back to the AjaxRequestTarget.

Anyway, I see you're trying to implement a server-side behavior to make something you could do client-side (actually, it's a client-side operation). You'd be far better unchecking all other checkboxes client-side, for instance, with javascript.

You can make your Component implement IHeaderContributor, and output the checkboxes' HTML id attributes to Javascript. Then, every checkbox can have an onchange event handler in which you can uncheck all other checkboxes selecting them with document.getElementById().

With this approach, you wouldn't need setReuseItems(true). In case you write the ListView back to the AjaxRequestTarget, setReuseItems() would help you keep the same Components that were instantiated in the first execution of populateItem() (i.e, they would keep the same markupId's). In general, if you need to manage state of components inside the ListView, it's recommendable to use setReuseItems(true). In this case this is done client-side, so it's not necessary at first glance.

For instance:

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;
          }
     }
}

You can append onchange="deselectChecks(this.id);" to the checkboxes in the HTML file, or add it with a SimpleAttributeModifier in the Java class.

As always, you should also implement this restriction/behavior server-side to prevent users without javascript to bypass it. I'd suggest a FormValidator to that effect.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜