在没有AJAX的情况下动态添加和删除组件?

时间:2012-09-11 17:18:44

标签: java wicket

我有一个动态表单,我正在Wicket中编写一些表单,这些表单可以通过“单击此处添加更多问题”类型的按钮进行复制。我写了一个非常基本的(我还是Wicket的新手)AJAXy监听器,它主要起作用,但我无法弄清楚如何删除甚至隐藏ListView中的项目。

这让我很奇怪,有没有办法让一些JS复制表单字段?在我使用Wicket组件重新构建表单之前,我使用了Jquery Dynamic Form Plugin复制值。这很好用,很容易理解(一个重要的加分)。但是,如果我只是使用插件而不是像

这样的话,我无法弄清楚这会如何影响Wicket
    //Issue box magic
    final MarkupContainer rowPanel = new WebMarkupContainer("issuesPanel");
    rowPanel.setOutputMarkupId(true);
    form.add(rowPanel);
    ArrayList numIssues = new ArrayList();
    numIssues.add(new Object());
    numIssues.add(new Object());
    numIssues.add(new Object());
    final ListView lv = new ListView("issuesBox", numIssues) {
        @Override
        protected void populateItem(ListItem item) {
            int index = item.getIndex() + 1;

            item.add(new DropDownChoice("issues", combinedIssues));
            item.add(new TextField<String>("note"));
        }
    };
    lv.setReuseItems(true);
    rowPanel.add(lv);
    form.add(new AjaxSubmitLink("addIssue", form) {
        @Override
        public void onSubmit(AjaxRequestTarget target, Form form) {
            lv.getModelObject().add(new Object());
            if (target != null)
                target.add(rowPanel);
        }
    }.setDefaultFormProcessing(false));
    form.add(new AjaxSubmitLink("removeIssue", form) {
        @Override
        public void onSubmit(AjaxRequestTarget target, Form form) {
            //Wicket gets very angry when you remove components, so just hide it (recommended way)
            if (target != null) {
                Component lastObject = (Component)lv.get(lv.getList().size() - 1);
                lastObject.setVisible(false);
                log.debug("Components " + lv.get );
            }

        }
    }.setDefaultFormProcessing(false));

JQuery插件更容易使用,但我怎么能告诉Wicket有更多的字段呢?

注意我也试图避免AJAX调用只是为了添加一个新问题,我在使用该应用程序时可能会成为一个问题。

有什么建议吗?

2 个答案:

答案 0 :(得分:3)

您无法通过ajax在html中添加表单元素。使用Wicket,你有一个html和Java的compnent树,两者都必须匹配。最后,Wicket在您提交表单时必须知道这些值的结果。

我不确定我是否理解您的特殊要求,但我想类似的问题可能是向某人添加地址。在这里,我将构建一个AdressEditPanel,其中包含一个表单,其中包含一个地址所需的所有字段。该Panel将具有PersonAdress(作为示例)Object作为Model。

在Person上,您将拥有一个Adresses集合,并使用ListView来呈现和编辑每个地址。在ListView的populateItem()函数中,您将向项目添加一个AdressEditPanel实例。

如果你需要向一个人添加一个地址,只需在一个地址集中添加一个条目并重新显示该表单(我将首先使用Ajax,一旦它工作,则执行切换到ajax所需的最小更改)

希望有所帮助

答案 1 :(得分:0)

如果在修改了模型对象后在ListView上调用removeAll(),则应解决问题。例如

new AjaxSubmitLink("addIssue", form) {
        @Override
        public void onSubmit(AjaxRequestTarget target, Form form) {
            lv.getModelObject().add(new Object());
            lv.removeAll();
            if (target != null)
                target.add(rowPanel);
        }

但是我不知道这是否会导致形成验证问题,但我认为它应该是安全的。

<强>更新

如果你想使用相同的方法删除链接,你应该写这样的东西:

new AjaxSubmitLink("removeIssue", form) {
        @Override
        public void onSubmit(AjaxRequestTarget target, Form form) {

            if (target != null) {
                lv.getModelObject().remove(lv.getList().size() - 1);
                lv.removeAll();
                target.add(rowPanel);

            }

        }
    }

然而,如果没有AJAX,这是不可能的。唯一的方法是使用JS并在服务器端读取来自表单的请求参数。