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