Текстовое поле wicket в listview очищается при снятии ajaxcheckbox - PullRequest
1 голос
/ 13 октября 2011

Я создал один флажок и одно текстовое поле для каждой строки, используя вид списка калитки.

Когда пользователь устанавливает флажок, я могу установить соответствующее логическое значение успешно.

Но мне нужно было установить ограничение. Только один флажок может быть выбран для отправки формы в следующей структуре.

Текстовый флажок Флажок Textarea Флажок Textarea Флажок Textarea

Текст, который я набрал в текстовых областях, удаляется, когда я снимаю флажок, который я выбрал. Насколько я знаю, следующая строка используется для предотвращения этой проблемы, но она не работает. Есть ли у вас какие-либо идеи?

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 Ответ

1 голос
/ 13 октября 2011

Было бы полезно, если бы вы включили в код, как вы строите эти текстовые области, и если вы добавляете их обратно в 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 или добавить его с помощью SimpleAttributeModifier в классе Java.

Как всегда, вы должны также реализовать это ограничение / поведение на стороне сервера, чтобы пользователи без JavaScript не могли его обойти. Я бы предложил FormValidator на этот счет.

...