2011-10-13 57 views
1

我使用wicket listview爲每一行創建了一個複選框和一個文本框。在取消設置ajaxcheckbox時,listview中的wicket textarea被清除

當用戶選中複選框時,我可以成功設置相關的布爾值 。

但我需要加一個限制。只有一個複選框可以選擇 以提交以下結構中的表單。

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

,如果你在你是如何建立這些文字區域的代碼中包含了這將是有益的,如果你加入他們回到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