Кажется, каждый раз, когда я изучаю новую платформу, мне приходится заново решать ту же старую проблему: Обновите варианты в одном раскрывающемся списке при изменении другого раскрывающегося списка, используя Ajax. В этот раз каркас - Wicket.
У меня есть две сущности, которые я назову Foo и Bar, и у каждого Foo есть категория, которая является внутренним для Foo перечислением. Кроме того, существует FooDAO с перегруженными методами find ()
: версия без аргументов возвращает все Foo в БД или версия с параметром «filter» типа Foo, которая возвращает все соответствующие фильтры Foo в ненулевые значения.
Клиент хочет связать Foos с Bars при создании нового Bar, но фильтровать Foos по категориям перед добавлением одного. Итак, предположим, что несколько Foo уже существуют, каждая с категорией.Пользователь переходит на страницу создания панели и в раздел, чтобы добавить новый Foo: раскрывающийся список A перечисляет категории, и при выборе категории раскрывающийся список B должен отображать список доступных Foo в этой категории через обновление Ajax. Обратите внимание, что ни одна категория не выбрана, раскрывающийся список 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>
(Кнопка со временем получит свой собственный идентификатор и поведение, но сейчас в центре внимания находятся списки.)
Вот сторона 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, независимо от того,
выбора категории.