ListViewで生成したコンポーネントに対してバリデータを指定するWicketJava
ListViewでTextFieldとTextAreaの組み合わせを幾つか生成して、一つの組み合わせに対しては「片方が入力されている場合、両方入力されていなかったらエラー」、全てに対して「少なくとも一つの組み合わせが入力されている」というバリデータを追加したかった。
とりあえずSampleとしてListViewで幾つかTextFieldを生成して「少なくとも一つは入力状態にある」というバリデータを追加するプログラム書いた。無理やりな気がする。もう少しスマートな方法があれば教えてください。
ListViewの中と外にバリデータ追加して中では一つ一つに対して入力されているかどうか調べて、入力されていたらフラグ立てる。外のバリデータでフラグが立ってるかどうかチェックしてフラグが立っていた場合OK。フラグが立っていない場合入力されていないということだからエラーを表示する。
外側のエラーでerrorメソッドにFormComponent持たせないといけないが、
error(new TextField<String>("hoge"));
とやって誤魔化せると思ったら誤魔化せられなかったので先にTextFieldのListを生成して無理やり
error(textList.get(0));
と持たせた。
SamplePage.java
import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.FormComponent; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.form.validation.AbstractFormValidator; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.validation.IValidatable; import org.apache.wicket.validation.validator.AbstractValidator; public class SamplePage extends WebPage { boolean test = true; public SamplePage() { final FeedbackPanel feedback = new FeedbackPanel("feedback"); feedback.setOutputMarkupId(true); add(feedback); int loop = 3; final List<SampleStr> sampleList = new ArrayList<SampleStr>(); for(int i = 0; i < 3; i++){ sampleList.add(new SampleStr()); } final List<TextField<String>> textList = new ArrayList<TextField<String>>(); for(int i = 0;i<3;i++){ textList.add(new TextField<String>("text", new PropertyModel<String>(sampleList.get(i), "str"))); } Form<Void> form = new Form<Void>("form"); add(form); ListView<TextField<String>> listView = new ListView<TextField<String>>("list", textList) { @Override protected void populateItem(ListItem<TextField<String>> item) { TextField<String> text = item.getModelObject(); item.add(text); text.add(new AbstractValidator<String>(){ @Override protected void onValidate(IValidatable<String> validatable) { String str = validatable.getValue(); if(!str.isEmpty()){ test = false; } } }); } }; form.add(listView); AjaxButton button = new AjaxButton("button") { @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { //処理 } @Override protected void onError(AjaxRequestTarget target, Form<?> form) { super.onError(target, form); target.addComponent(feedback); } }; form.add(button); form.add(new AbstractFormValidator(){ public FormComponent<?>[] getDependentFormComponents() { return new FormComponent<?>[]{}; } public void validate(Form<?> form) { if(test == true){ error(textList.get(0)); } } @Override protected String resourceKey() { return "SampleValidator"; } }); } } class SampleStr implements Serializable { int id; String str; public SampleStr() { this.str = null; } public int getId() { return id; } public void setId(int id) { this.id = id; } public void setStr(String str) { this.str = str; } public String getStr() { return str; } }
SamplePage.html
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Insert title here</title> </head> <body> <div wicket:id="feedback"></div> <form wicket:id="form"> <div wicket:id="list"> <input type="text" wicket:id="text" /><br /> </div> <input type="submit" wicket:id="button" /><br /> </form> </body> </html>
SamplePage.properties
SampleValidator = "テストです。全て入力されていません"
これで一つも入力されていなかった場合feedbackpanelにはエラーが表示される。だが、一回TextFieldに何か書いて全て消した後ボタン押すとエラーが表示されない。困った。
というかAbstractFormValidatorのerror(textList.get(0));が酷過ぎる。