Mail
送信フォームを作る必要があり、
Wicket
の Form
の使い方がわからず、
Submit
処理含むを見よう見まねで実装してみました。
Wicket
の Version
は、7.3.0
です。
目次
- 実装イメージ
- HTML
- FORM Button を使う
- FORM AjaxButton を使う
- FORM IndicatingAjaxButton を使う
- FeedBackPanel の CSS を変更する
実装イメージ
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
というか Button
にFocusを移動するための 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
に変更して、
を1行追加することでも可能です。name.setRequired(true);
-
エラー時のメッセージ変更
入力エラー時は、デフォルトでwicket:id
名が項目名としてメッセージが出力されます。
wicket:id
名は出力したくないので、
で項目名称にプロパティファイルから取得した値を設定するようにしました。name.setLabel(Model.of(getString("nameLabelText")));
- 文字列長チェック
文字列長チェックのため、
で、最大文字列長チェックを150文字で行う設定をしています。name.add(StringValidator.maximumLength(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
の場合は、AjaxRequestTarget
にFeedbackPanel
を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
を使用しているので、Bootstrap
のcss
に変更してみました。
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;
}
};
表示
以下のように表示されます。あまりいい感じではない。かもしれません。
以上です。
コメント