ModalWindow
Wicketではモーダルウィンドウもコンポーネントとして提供されているので、使ってみる。例として、以下のような機能のページを作成する。
- メインページのボタンを押すとモーダルウィンドウが立ち上がる
- モーダルウィンドウのテキストボックスに値を入力してOKボタンを押すと、値がメインページのラベルに反映される
- モーダルウィンドウの×ボタンを押すと、処理をせず閉じる
元画面
Javaクラス。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
public class MainPage extends WebPage { private Model<String> model; private ModalWindow modalWindow; public MainPage() { modalWindow = new ModalWindow("modal"); add(modalWindow); modalWindow.setPageCreator(new ModalWindow.PageCreator(){ @Override public Page createPage() { return new SubPage(model, modalWindow); } }); modalWindow.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() { @Override public void onClose(AjaxRequestTarget target) { setResponsePage(getPage()); } }); Form<WebPage> form = new Form<WebPage>("form"); add(form); model = new Model<String>(); Label label = new Label("label", model); form.add(label); AjaxButton ajaxButton = new AjaxButton("ajaxButton") { @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form){ modalWindow.show(target); } }; form.add(ajaxButton); } } |
- モーダルウィンドウはModalWindowというそのまんまのクラスで作成する。
- setPageCreatorの部分で、どのクラスをモーダルとして表示させるかを設定する。モーダルにJavaのインスタンスを渡せるのでいろいろと便利に使える。
- setWindowClosedCallbackはモーダルを閉じた時のイベント。「setResponsePage(getPage())」で、画面(MainPage)を再描画させている。これはどのような操作かにかかわらずとにかくモーダルが閉じたときのイベントだが、「×ボタンを押したとき専用」のイベントも存在するので使い分けができる。
- AjaxButtonでモーダルウィンドウを表示させる。モーダルを閉じる場合はModalWindow#close()を使用する。
HTML。
1 2 3 4 5 |
<div wicket:id="modal"></div> <form wicket:id="form"> <span wicket:id="label"></span> <input type="button" wicket:id="ajaxButton" value="push" /> </form> |
WicketのModalWindowは本当に新規のウィンドウが開くわけではなく、Ajaxを使用して実現している。今回、モーダルウィンドウ表示部分はdivで指定した(別にdivである決まりはない)。
モーダル画面
Javaクラス。モーダル側も通常のページと同様WebPageのサブクラスとして作成する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class SubPage extends WebPage { public SubPage(Model<String> model, final ModalWindow modalWindow) { Form<WebPage> form = new Form<WebPage>("form"); add(form); TextField<String> text = new TextField<String>("text", model); form.add(text); AjaxButton ajaxButton = new AjaxButton("ajaxButton") { @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form){ modalWindow.close(target); } }; form.add(ajaxButton); } } |
今回は以下のような作りにした。
- コンストラクタでModelとModalWindow(表示されているのは自画面)を受け取る
- テキストを入力してボタンを押すと、モデルに値をセットし画面を閉じる
HTML。
1 2 3 4 |
<form wicket:id="form"> <input type="text" wicket:id="text" /> <input type="button" wicket:id="ajaxButton" value="push" /> </form> |
特に注意点はない。
ちなみに、モーダルウィンドウのタイトルの設定にはHTMLのTitleタグが使われるが、java側でModalWindow#setTitle(String)で設定する方法もある。
実際の表示
初期表示時
↓
ボタン押下時
↓
文字記入
↓
モーダル内のボタン押下で親画面に反映
感想、注意点
Wicket全般に言えることではあるがモデルやインスタンスをやり取りできるのはかなり便利。これができるというだけでStrutsではなくWicketを選ぶ価値があるんじゃないかと思えるくらい。もちろん他にもいいところはいっぱいある。
イベント等を細かく拾えたりできるのも大きい。JavaScriptのshowModalDialogと比べて自由度が高いので、上記のようなクラスを直に扱えることとも相まって作りやすくなっている。
注意点としては、モーダルでModelを変更しても、そのままでは親画面の表示は再描画されないため、見た目上値が変更されていないようになってしまうということ。今回は「setResponsePage(getPage())」で再描画させている。