2012-02-27 21 views
7

新しいプラットフォームを学ぶたびに、同じ古い問題を再解決する必要があります。 Ajaxを使用して別のドロップダウンを変更すると、1つのドロップダウンで選択肢が更新されます。この時間は フレームワークはWicketです。Wicket Ajaxを別のドロップダウンリストに更新する

私はFooとBarを呼び出す2つのエンティティを持っています。それぞれのFooにはカテゴリがあり、これはFoo内部の列挙型です。また、オーバーロードされたfind()メソッドを持つFooDAOが存在します。引数なしのバージョンは、DB内のすべてのFooを返します。または、Foo型のすべてのFoo適合フィルタをnull以外の値で返す型の "filter"を持つバージョンを返します。

クライアントは、新しいバーを作成するときにFoosをバーに関連付けるが、追加する前にカテゴリ別にFoosをフィルタしたい。だからFooの一握りがすでに存在し、それぞれにカテゴリがあるとします。ユーザーはバーの作成ページに移動し、新しいFooを追加するセクションに移動します。ドロップダウンAはカテゴリをリストし、カテゴリを選択すると、ドロップダウンBはAjaxの更新を介して、そのカテゴリの利用可能なFooのリストを表示します。カテゴリが選択されていないことに注意してください。ドロップダウンBは利用可能なすべてのFooを表示する必要があります。私のHTMLは少しこのようになります

<form wicket:id="createBarForm"> 
<div> 
    <label>Category</label> 
    <select wicket:id="category"> 
    </select> 
</div> 
<div> 
    <label>Available Foo(s)</label> 
    <select class="xlarge" wicket:id="selectedFoo"> 
    </select> 
</div> 
<button style="float:right;">Add</button> 

<!-- and more Bar related fields --> 
</form> 

(ボタンは最終的に自分のIDと動作を取得しますが、今の焦点は、リストの上にある。)

ここでのJavaです(ページのコンストラクタメソッド内)側:

createBarForm = new Form<Bar>("createBarForm", 
      new CompoundPropertyModel<Bar>()); 

    final List<Foo> availableFoo = fooDao.find(); 

    final FormComponent<Foo> selectedFoo = 
      new DropDownChoice<Foo>("selectedFoo", 
        Model.of(new TechnologyFoo()), availableFoo); 

    Foo.Category categoryStandin = null; 

    final FormComponent<Foo.Category> fooCategory = 
      new DropDownChoice<Foo.Category> 
       ("fooCategory", Model.of(categoryStandin), 
         Arrays.asList(Foo.Category.values())); 

    fooCategory.add(new AjaxFormComponentUpdatingBehavior("onchange") { 
     private static final long serialVersionUID = 1L; 
     @Override 
     protected void onUpdate(AjaxRequestTarget target) { 
      // re-set the form component 
      availableFoo.clear(); 
      ((DropDownChoice<Foo>)selectedFoo).setChoices(availableFoo); 
      createBarForm.remove(selectedFoo); 

      Foo.Category newSelection = 
        fooCategory.getModelObject(); 
      if (newSelection != null) { 
       Foo filter = new Foo(); 
       filter.setCategory(newSelection); 
       availableFoo.addAll(fooDao.find(filter)); 
      } 
      else { 
       availableFoo.addAll(fooDao.find()); 
      } 
      // re-fresh the form component 
      ((DropDownChoice<Foo>)selectedFoo).setChoices(availableFoo); 
      createBarForm.add(selectedFoo); 
     } 
    }); 

    createBarForm.add(fooCategory); 
    createBarForm.add(selectedFoo); 

    // etc..... 

は私logger.debug呼び出しを示していないが、彼らと私はnewSelectionがされていることを示すことができていますDAOは期待されるFooのリストを返しています。また、avaliableFooリストにも必要な値が含まれています。ただし、ドロップダウンBは、カテゴリ選択の にかかわらず、Fooの完全なリストを常に表示します。

+1

のように

あなたは正しい答えを持っているとして見て、これは追記である:私はおそらくちょうどドロップダウン選択コンポーネントのそれぞれのモデルで選択/選択更新コードを移動し、したいです'onUpdate()'メソッドで 'target.addComponent()'呼び出しを行うと、あなたのコードは読みやすく保守しやすくなります。 – biziclop

答えて

5

DropDownsをAjaxRequestTargetに追加する必要があります。そうしないと、更新されません。

target.add(selectedFoo); 
+0

'selectedFoo.setOutputMarkupId(true);'も追加する必要がありますが、動作しているようです。 – cobaltduck

関連する問題