在窗体中重用wicket组件

时间:2012-08-24 12:54:17

标签: wicket

我已经构建了一个wicket组件,其中包含输入/标签和更改演示文稿的方法(必需,启用等)。组件渲染很好,但是当表单提交时我只看到1个表单参数'input',它是最后一个InputRow组件。

InputRow.html

<html xmlns:wicket="http://wicket.apache.org">
<head>
    <link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
    <wicket:panel>
        <label wicket:id="label">abc: <span class="req">*</span></label>
        <span class="input">
            <input wicket:id="input" type="text" id="name"></input>
        </span>
        <span wicket:id="input_feedback"></span>            
    </wicket:panel>

</body>
</html>

InputRow.java

package com.wicket;

import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.feedback.FeedbackMessage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;

public class InputRow extends Panel{

    @SuppressWarnings("unused")
    private String id;

    public InputRow(String id, String label) {
        super(id);

        this.id = id;

         Label memberIdLabel = new Label("label",label);
         memberIdLabel.setEscapeModelStrings(false)
            .add(new AttributeAppender("for", new Model<String>(id),""));
         add(memberIdLabel);

        TextField<String> name = new TextField<String>("input");
        name.setType(String.class)
            .setMarkupId(id)
            .setOutputMarkupId(true);
        add(name);

        add(new Label("input_feedback",""));

    }

    public InputRow disable()
    {
        get("input")
            .setEnabled(false)
            .add(new AttributeAppender("class", new Model<String>("disabled"),""));
        get("label")
            .add(new AttributeAppender("class", new Model<String>("disabled"),""));
        return this;
    }

    public InputRow required()
    {
        Model model = (Model)get("label").getInnermostModel();
        StringBuffer label = new StringBuffer((String)model.getObject());
        label.append(" <span class=\"req\">*</span>");
        model.setObject(label);

        ((TextField)get("input")).setRequired(true);
        return this;
    }

    @Override
    protected void onBeforeRender() {
        super.onBeforeRender();
        Label feedback = (Label)get("input_feedback");

        if (get("input").getFeedbackMessage() != null)
        {
            feedback.setDefaultModel(new Model<String>("Required"));
        }
    }


}

添加到表单组件

add(new InputRow("name","Name:").required());

修改的 我没有设置ListView或转发器,因为我知道在构建时我想要在表单中添加哪些行/字段。

3 个答案:

答案 0 :(得分:1)

不仅提交了一个表单参数。提交的名称类似于name:inputname2:input,...

但正如Nicktar在评论中建议的那样,您应该使用模型将表单组件的值绑定到您的实体对象。您必须在构造函数中接受IModel并在TextField的构造函数中使用它。

更好的方法是编写一个Behavior,为FormComponent添加装饰标记。这样,它不仅适用于简单的文本输入字段,而且您可以完全自定义FormComponents的实例。

看起来像这样:

public class FormComponentBehavior extends Behavior {

    @Override
    public void bind(Component component) {
        if (!(component instanceof FormComponent)) {
            throw new IllegalArgumentException();
        }
    }

    @Override
    public void beforeRender(Component component) {
        FormComponent<?> fc = (FormComponent<?>) component;
        Response r = component.getResponse();
        r.write("<label" + (fc.isRequired() ? " class='required'" : "") + ">");
        r.write(fc.getLabel().getObject());
        r.write("</label>");
        r.write("<span class='input'>");
    }

    @Override
    public void afterRender(Component component) {
        component.getResponse().write("</span>");
        // if feedback errors write them to markup...
    }
}

然后,您必须将此行为添加到FormComponent实例。

答案 1 :(得分:1)

您的InputFields缺少他们的模型。这样,wicket不知道在哪里存储formdata。如果您将模型添加到字段中,它们将自动填充。

答案 2 :(得分:0)

表单的问题可能是您的输入文本字段具有相同的ID。尝试使用属性“name”而不是“id”