【问题标题】:Reusing wicket component in a form在表单中重用检票口组件
【发布时间】:2015-08-13 18:09:20
【问题描述】:

我已经构建了一个检票口组件,其中包含输入/标签和更改表示的方法(必需、启用等)。组件渲染得很好,但是当表单提交时,我只看到 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 或中继器,因为我知道在构建时要添加到表单中的行/字段。

【问题讨论】:

  • 您是否有理由不在输入字段中使用模型?如果您使用模型,它们会在提交时更新吗?
  • 在应用示例时没有其他原因。我会应用这个建议,看看会发生什么。
  • 尼克塔,成功了。如果你回答我可以投票。 tks

标签: wicket


【解决方案1】:

您的 InputField 缺少它们的模型。这样,wicket 不知道在哪里存储表单数据。如果您将模型添加到字段中,它们将被自动填充。

【讨论】:

    【解决方案2】:

    提交的表单参数不止一个。提交的名称类似于 name:input, name2: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 实例中。

    【讨论】:

      【解决方案3】:

      也许您的表单的问题是您的输入文本字段具有相同的 id。尝试使用属性 'name' 而不是 'id'

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-30
        • 2019-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多