Wydaje się, że za każdym razem, gdy uczę się nowej platformy, muszę ponownie rozwiązać ten sam stary problem: Zaktualizuj opcje w jednym menu po zmianie innego menu, używając Ajax. Tym razem ramą jest Wicket.Ajax Wicket uaktualnienie jednego dropdown do innego
Mam dwa podmioty, które będę nazywać Foo i Bar, a każdy Foo ma kategorię, która jest wewnętrzną enum dla Foo. Istnieje również metoda FooDAO z przeciążonymi metodami: Argument no-arg zwraca wszystkie Foo w DB lub wersję z parametrem "filter" typu Foo, która zwraca wszystkie pasujące filtry Foo w wartościach innych niż NULL.
Klient chce skojarzyć Foos z Bars podczas tworzenia nowego paska, ale aby filtrować Foos według kategorii przed dodaniem. Załóżmy, że garstka Foo już istnieje, każda ma kategorię. Użytkownik przechodzi do strony tworzenia paska, a sekcja do dodania nowego Foo: Dropdown A zawiera listę kategorii, a po wybraniu kategorii, Dropdown B ma pokazać listę dostępnych Foo w tej kategorii, poprzez aktualizację Ajax. Pamiętaj, że nie wybrano żadnej kategorii, menu rozwijane B powinno pokazywać wszystkie dostępne Foo.
Moje HTML wygląda trochę tak:
<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>
(. Przycisk ostatecznie dostać swój własny identyfikator i zachowanie, ale teraz skupiamy się na listach)
Oto Java bok (w metodzie konstruktora strony użytkownika):
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.....
nie wykazały moje logger.debug
połączeń, ale z nich jestem w stanie pokazać, że jest w trakcie newSelection
poprawnie zrobione, a DAO zwraca oczekiwaną listę Foo. Ponadto lista avaliableFoo
zawiera również wymagane wartości. Jednak lista rozwijana B zawsze pokazuje pełną listę Foo, niezależnie od tego, czy jest to wyboru kategorii.
Widząc jak masz właściwą odpowiedź, to na marginesie: ja prawdopodobnie przenieść wybór/wybór kodu aktualizującego w odpowiednich modeli komponentów wyboru rozwijana i po prostu wykonaj wywołanie 'target.addComponent()' w metodzie 'onUpdate()', kod będzie znacznie łatwiejszy do odczytania i konserwacji. – biziclop