Wicket Ajax обновляет один выпадающий список другим - PullRequest
7 голосов
/ 27 февраля 2012

Кажется, что каждый раз, когда я изучаю новую платформу, мне приходится заново решать ту же самую старую проблему: Обновите варианты в одном раскрывающемся списке при изменении другого раскрывающегося списка, используя 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, независимо от выбора категории.

1 Ответ

5 голосов
/ 27 февраля 2012

Вы должны добавить свои DropDowns к AjaxRequestTarget, иначе они не будут обновлены.

как в

target.add(selectedFoo);
...