Mail 送信フォームを作る必要があり、
Wicket Form使い方がわからず、 Submit 処理含むを見よう見まねで実装してみました。
Wicket Version は、7.3.0 です。

目次

実装イメージ

CSS は適用されてますが、以下のようなものになりました。

メール送信画面


HTML

HTML以下の通りです。Bootstrap 使っています。

<!-- Contact -->
<form role="form" wicket:id="mailForm">
    <wicket:enclosure child="feedbackMessage">
    <div class="form-group">
        <div class="col-md-12">
            <div wicket:id="feedbackMessage"></div>
        </div>
    </div>
    </wicket:enclosure>
    <div class="form-group">
        <div class="col-md-12">
            <input wicket:id="name" type="text" class="form-control" id="inputName" placeholder="Name">
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-12">
            <input wicket:id="eMail" type="text" class="form-control" id="inputEmail" placeholder="Email">
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-12">
            <input wicket:id="subject" type="text" class="form-control" id="inputSubject" placeholder="Subject">
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-12">
            <textarea wicket:id="message" name="message" class="form-control" rows="3" placeholder="Message"></textarea>
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-12">
            <button type="submit" wicket:id="sendMessage" class="btn btn-theme btn-lg btn-block">Send message</button>
        </div>
    </div>
</form>


FORM Buttonを使う

以下メソッドで、Form の作成処理を行うようにしました。
retrun しているだけです。呼び出し元で、勿論add しています。

    // newMailForm
    private Form newMailForm() {

        // new MailForm
        Form form = new Form("mailForm");

        // name
        TextField name = new RequiredTextField("name", Model.of(""));
        name.setLabel(Model.of(getString("nameLabelText")));
        name.add(StringValidator.maximumLength(150));
        form.add(name);

        // eMail
        TextField eMail = new RequiredTextField("eMail", Model.of(""));
        eMail.setLabel(Model.of(getString("eMailLabelText")));
        eMail.add(StringValidator.maximumLength(150));
        eMail.add(EmailAddressValidator.getInstance());
        form.add(eMail);

        // subject
        TextField subject = new RequiredTextField("subject", Model.of(""));
        subject.setLabel(Model.of(getString("subjectLabelText")));
        subject.add(StringValidator.maximumLength(150));
        form.add(subject);

        // message
        TextArea<String> message = new TextArea<>("message", Model.of(""));
        message.setLabel(Model.of(getString("messageLabelText")));
        message.setRequired(true);
        message.add(StringValidator.maximumLength(10000));
        form.add(message);

        FeedbackPanel feedBack = new FeedbackPanel("feedbackMessage");
        feedBack.setOutputMarkupId(true);
        add(feedBack);

        // sendMessage
        Button sendMessage = new Button("sendMessage", Model.of(getString("messageButtonLabelText"))) {
            private static final long serialVersionUID = -8204140666393922700L;

            @Override
            public void onSubmit() {
                success(getString("messageMailSendSucceed"));
            }

            @Override
            public void onError() {
                // Set Focus
                add(new DefaultFocusBehavior("buttonSendMessage"));
                error(getString("messageMailSendError"));
            }
        };
        form.add(sendMessage);
        form.setDefaultButton(sendMessage);
        return form;
    }

DefaultFocusBehavior クラスの記述です。
onError 時に、Formいうか ButtonFocusを移動するための Behaviorなります。
以下を参考に作成しました。

public class DefaultFocusBehavior extends Behavior {

        /**
         * DefaultFocusBehavior
         *
         * @param markUpId
         */
        public DefaultFocusBehavior(String markUpId) {
            this.markUpId = markUpId;
        }

        private final String markUpId;
        private static final long serialVersionUID = 1L;

        @Override
        public void bind(Component component) {
            if (!(component instanceof FormComponent)) {
                throw new IllegalArgumentException("DefaultFocusBehavior: component must be instanceof FormComponent");
            }
            component.setMarkupId(markUpId);
        }

        @Override
        public void renderHead(Component component, IHeaderResponse headerResponse) {
            super.renderHead(component, headerResponse);
            headerResponse.render(OnDomReadyHeaderItem.forScript("document.getElementById('"
                    + component.getMarkupId() + "').focus();"));
        }

        @Override
        public boolean isTemporary(Component component) {
            return true;
        }
    }

実装の説明

  • テキストフィールドの必須化

        TextField name = new RequiredTextField("name", Model.of(""));
    
    上記で、テキストフィールドを必須化しています。
    必須化は、生成するインスタンスを RequiredTextField から TextField変更して、
        name.setRequired(true);
    
    1行追加することでも可能です。

  • エラー時のメッセージ変更
    入力エラー時は、デフォルトでwicket:id 名が項目名としてメッセージが出力されます。
    wicket:id 名は出力したくないので、

        name.setLabel(Model.of(getString("nameLabelText")));
    
    項目名称にプロパティファイルから取得した値を設定するようにしました。


  • 文字列長チェック
    文字列長チェックのため、
        name.add(StringValidator.maximumLength(150));
    
    で、最大文字列長チェックを150文字で行う設定をしています。

  • テキストエリア
        TextArea<String> message = new TextArea<>("message", Model.of(""));
    
    には、RequiredTextFieldあたるクラスが存在しないので、
        message.setRequired(true);
    
    必須化しました。

  • FeedbackPanelついて
    FeedbackPanel は、Validatorエラーメッセージ出力のために使用します。 以下の記述
        <div wicket:id="feedbackMessage"></div>
    
    メッセージが出力されます。

  • エラー時のフォーカス
        add(new DefaultFocusBehavior("buttonSendMessage"));
    
    で、エラー時に 対象項目に Focus するようにしています。

参考


FORM AjaxButtonを使う

FORM を以下のように書き換えると、AjaxButtonで結果を返すことができます。

        AjaxButton sendMessage = new AjaxButton("sendMessage", Model.of(getString("messageButtonLabelText"))) {
            private static final long serialVersionUID = -8204140666393922700L;

            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                target.addChildren(getPage(), FeedbackPanel.class);
                success(getString("messageMailSendSucceed"));
            }

            @Override
            protected void onError(AjaxRequestTarget target, Form<?> form) {
                target.addChildren(getPage(), FeedbackPanel.class);
                error(getString("messageMailSendError"));
            }
        };


実装の説明

  • target.addChildren(getPage(), FeedbackPanel.class);FeedbackPanelメッセージ通知を行います。
    AjaxButton場合は、AjaxRequestTargetFeedbackPanel add しないとメッセージが反映されません。

  • target.addChildren(getPage(), FeedbackPanel.class);使用すると、
    FeedbackPanelインスタンスを知らなくてもよくなるので、もち回らずともadd できるようになります。


参考


FORM IndicatingAjaxButtonを使う

IndicatingAjaxButton使用することで、ちょっと待てのクルクルを表示することができます。
クルクル自体はもの小さくてわかりにくいので、
こいつを参考に独自クラスを用いて実装したほうが良いように思います。

        AjaxButton sendMessage = new IndicatingAjaxButton("sendMessage", Model.of(getString("messageButtonLabelText"))) {

            private static final long serialVersionUID = -8204140666393922700L;

            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                target.addChildren(getPage(), FeedbackPanel.class);
                success(getString("messageMailSendSucceed"));
            }

            @Override
            protected void onError(AjaxRequestTarget target, Form<?> form) {
                target.addChildren(getPage(), FeedbackPanel.class);
                error(getString("messageMailSendError"));
            }
        };

また、このクラス自体は、wicket-core には含まれていないため、pom.xml以下を追記する必要があります。

    <dependency>
        <groupId>org.apache.wicket</groupId>
        <artifactId>wicket-extensions</artifactId>
        <version>7.3.0</version>
    </dependency>

参考

FeedBackPanel のCSSを変更する

FeedbackPanel#getCSSClass()オーバーライドすることで、
FeedbackPanel出力される、<li >タグのcss class 属性を変更することができます。
Bootstrap使用しているので、Bootstrapcss変更してみました。

        FeedbackPanel feedBack = new FeedbackPanel(id) {

            private static final long serialVersionUID = -3677487785071675904L;

            protected String getCSSClass(final FeedbackMessage message) {
                String cssClass;
                switch (message.getLevel()) {
                    case FeedbackMessage.UNDEFINED:
                        cssClass = getString(FeedbackMessage.UNDEFINED_CSS_CLASS_KEY);
                        break;
                    case FeedbackMessage.DEBUG:
                        // FeedbackMessage.INFO 以下は、"alert alert-info"
                        cssClass = "alert alert-info";
                        break;
                    case FeedbackMessage.INFO:
                        cssClass = "alert alert-info";
                        break;
                    case FeedbackMessage.SUCCESS:
                        cssClass = "alert alert-success";
                        break;
                    case FeedbackMessage.WARNING:
                        cssClass = "alert alert-warning";
                        break;
                    case FeedbackMessage.ERROR:
                        cssClass = "alert alert-danger";
                        break;
                    case FeedbackMessage.FATAL:
                        // FeedbackMessage.ERROR 以上は、"alert alert-danger"
                        cssClass = "alert alert-danger";
                        break;
                    default:
                        cssClass = "feedbackPanel" + message.getLevelAsString();
                }
                return cssClass;
            }
        };

表示

以下のように表示されます。あまりいい感じではない。かもしれません。エラー時の<wbr>スクリーンショット

以上です。

コメント