2012-04-26 25 views
2

これは非常に一般的な質問ではありませんが、私は次の再利用可能なWicketコンポーネントを構築することができるように、再利用可能なWicketコンポーネントを構築する

https://skitch.com/cmagnollay/8sn2s/multitextform

私が知っている、偉大な描画右:

ここスキッチのラフスケッチはありますか?したがって、本質的に、このフォームコンポーネント(私はこれが正しいクラスであると思います)を使用して、ユーザー定義の入力数をフォームに追加します。ユーザーがTextInputFieldの横にある - ボタンを押すと、そのinputFieldが削除されます。彼らが+ボタンを押すと、新しい空欄が追加されます。ユーザーがボタンをクリックしたときに、コンポーネントがAJAXを使用してコンポーネントを更新する必要があることは明らかですが、これを構造化する方法が問題です。これは一つのクラスですか? 2つ(1つはコンポーネント全体、もう1つは - ボタン付きの入力フィールド)、これを行うためにどのクラスを使用する必要がありますか?私は、オブジェクトをできるだけ一般的にして再利用を促進したいと思います。

public class MultiTextInput<T> extends FormComponent<List<T>> 
{ 
    private static final long serialVersionUID = 1L; 

    private final String removeInputButtonName = "removeInputButton"; 
    private final String addInputButtonIdName = "addInputButton"; 

    private int numInputs = 1; 
    private List<TextField<T>> inputFieldList = new ArrayList<TextField<T>>(); 

    public MultiTextInput(String id, IModel<T> model) 
    { 
     super(id); 

     inputFieldList.add(new TextField<T>("input1", model)); 

     add(inputFieldList.get(0)); 
     addAddInputFieldMarkup(); 
    } 

    /** 
    * Adds an "add" button. 
    */ 
    private void addAddInputFieldMarkup() 
    { 
     Button addInputButton = new Button(this.addInputButtonIdName + numInputs); 
     addInputButton.add(new AjaxFormComponentUpdatingBehavior("onclick"){ 

      private static final long serialVersionUID = 1L; 

      @Override 
      protected void onUpdate(AjaxRequestTarget target) 
      { 
       numInputs++; 

       inputFieldList.add(new TextField<T>("input" + numInputs)); 

       target.add(MultiTextInput.this); 
      } 

     }); 
    } 

    /** 
    * Adds a "remove" button. 
    */ 
    private void addRemoveInputFieldMarkup() 
    { 
     Button removeInputButton = new Button(this.removeInputButtonName + numInputs); 
     removeInputButton.add(new AjaxFormComponentUpdatingBehavior("onclick"){ 

      private static final long serialVersionUID = 1L; 

      @Override 
      protected void onUpdate(AjaxRequestTarget arg0) 
      { 
       // TODO Auto-generated method stub 

      } 

     }); 
    } 


} 

私が言ったように、私はちょうどWicketのコンポーネントを作ることを考えに慣れるしようとしています:ここで私はこれまで持っているものです。私はオブジェクト指向と多くの経験がありますが、特にウィッケットではありません。どんな助けと方向性もありがとう!

答えて

1

希望の動作を実装する最も簡単な方法は、リストに裏付けされたListViewを使用することです。追加/削除ボタンを押した後にリロードするだけです。私はこれをやっただけで、特別な事は周りのフォームを置くことです

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.sourceforge.net/" xml:lang="en" lang="en"> 
<wicket:panel> 
    <form wicket:id="multiTextForm"> 
     <wicket:container wicket:id="listView"> 
      <input type="text" wicket:id="textField" /> 
      <a wicket:id="removeButton">-</a> 
     </wicket:container> 
    </form> 
    <a wicket:id="addButton">+</a> 
</wicket:panel> 

:ここ

は、コードの落書き(テストしていません)

public abstract class MultiTextPanel<T> extends Panel { 

public MultiTextPanel(String id, IModel<ArrayList<T>> model) { 
    super(id, model); 

    final Form<ArrayList<T>> multiTextForm = new Form<ArrayList<T>>("multiTextForm", model); 
    add(multiTextForm); 

    final ListView<T> listView = new ListView<T>("listView", model) { 

     @Override 
     protected void populateItem(final ListItem<T> item) { 
      // TODO Auto-generated method stub 
      TextField<T> textField = new TextField<T>("textField", item.getModel()); 
      add(textField); 

      AjaxSubmitLink removeButton = new AjaxSubmitLink("removeButton", multiTextForm) { 

       @Override 
       protected void onSubmit(AjaxRequestTarget target, Form<?> form) { 
        multiTextForm.getModelObject().remove(item.getModelObject()); 
        target.addComponent(multiTextForm); 
       } 

       @Override 
       protected void onError(AjaxRequestTarget target, Form<?> form) { 
        //errors should be ignored, we shoudlnt validate in our form, so this shouldnt happen anyway 
        multiTextForm.getModelObject().remove(item.getModelObject()); 
        target.addComponent(multiTextForm); 
       } 

      };    
      add(removeButton); 

     } 

    }; 
    add(listView); 

    AjaxSubmitLink addButton = new AjaxSubmitLink("addButton", multiTextForm) { 

     @Override 
     protected void onError(AjaxRequestTarget target, Form<?> form) { 
      //errors should be ignored, we shoudlnt validate in our form, so this shouldnt happen anyway 
      multiTextForm.getModelObject().add(createNewT()); 
      target.addComponent(multiTextForm); 
     } 

     @Override 
     protected void onSubmit(AjaxRequestTarget target, Form form) { 
      multiTextForm.getModelObject().add(createNewT()); 
      target.addComponent(multiTextForm); 
     } 
    }; 
    add(addButton); 



} 

public abstract T createNewT();} 

基本的なHTMLですListViewを使用して、作成したパネルの中にサブミットすることができます(この段階では検証は必要ない可能性が高く、画面を保存する形式で行う必要があります)。

この実装の欠点は、完全なフォームを常にリロードしてオーバーヘッドが大きくなることです。 1行のみが追加/削除されますが、n( -/+)1は再描画されます。

+0

これは実際には、より大きな形式の1つの入力コンポーネントであると考えられています。そのため、私はスーパークラスとしてformcomponentを使うべきだと思ったのです。私の質問ではっきりしていない場合は申し訳ありませんが、私にlistviewのドキュメントをチェックさせてください。レスポンスありがとう! – thatidiotguy

+0

まあ、ListViewで簡単に同じ動作を実現できるのであれば、なぜ新しいFormComponentを作成するのが面倒なのかわかりません。しかし、FormComponentPanel(http://wicket.apache.org/apidocs/1.5/org/apache/wicket/markup/html/form/FormComponentPanel.html) –

+0

をチェックすることができます。あなたは、私が探している振る舞いが、それが自分自身のオブジェクトであっても価値がないというリストビューに似ていることを意味します。私はコードを最初のものから午前中に試してみます。努力とアドバイスありがとう! – thatidiotguy

関連する問題