先日、Wicket で、処理中をModalWindow で表現するを書いたのですが、、
oboe2uran.hatenablog.com
処理が終わった後に、正常終了か異常終了かのメッセージを表示したい
というのを対応しようと書き直しました。
というのを処理完了時に出すようにします。
Wicket-Panel のHTML を以下のように修正します。
処理開始トリガになる見えないボタン wicket:id="lazy_mocal_start" id="lazy_mocal_start" と
処理終了時に見せるボタン wicket:id="lazy_mocal_close" として、ボタンラベルも span で書きます。
必要な JavaScript もここに書きます(前回は、JSファイルに分けていた)
<!DOCTYPE html> <html xmlns:wicket="http://wicket.apache.org"> <body> <wicket:panel> <form wicket:id="lazy_mocal_form" id="lazy_mocal_form" > <section class="lazy-modal-panel"> <div> <ul> <li id="lazy_modal_progress_container"><div id="lazy_modal_progress"></div></li> <li><span wicket:id="message"></span></li> <li id="lazy_modal_close_container" style="display:none"> <button wicket:id="lazy_mocal_close" type="button"><span wicket:id="closeLabel"></span></button> </li> <li style="display:none"> <button wicket:id="lazy_mocal_start" id="lazy_mocal_start" type="button"></button> </li> </ul> </div> </section> </form> <script type="text/javascript"> var sizefitMessageModal = function(){ $('.w_content_container').css("height", $('.lazy-modal-panel ul').outerHeight(true) + "px" ); $('.wicket-modal').css("width", $('.lazy-modal-panel ul').outerWidth(true) + 22 + "px" ); }; var convergementLazy = function(){ $('#lazy_modal_progress_container').remove(); $('#lazy_modal_close_container').removeAttr('style'); $('.lazy-modal-panel li span').addClass('reduce'); $('.w_content_container').css("height", $('.lazy-modal-panel ul').outerHeight(true) + "px" ); $('.wicket-modal').css("width", $('.lazy-modal-panel ul li span').outerWidth(true) + 40 + "px" ); }; $(function(){ new Spinner().spin(document.getElementById('lazy_modal_progress')); setTimeout("$('#lazy_mocal_form').parent().parent().parent().parent().parent().prev().children('a').css('display','none');",100); }); </script> </wicket:panel> </body> </html>
スタイルシート CSS は、処理終了時、spin.js によるSPINアニメーションを表示しない分、調整します
.lazy-modal-panel li span.reduce
@CHARSET "UTF-8"; /* lazymodal.css */ .lazy-modal-panel ul{ margin: 10px 0; padding: 10px; } .lazy-modal-panel li{ list-style-type: none; white-space: nowrap; display: flex; align-items: center; justify-content: space-around; } .lazy-modal-panel li span{ margin: 40px 0 5px 0; } .lazy-modal-panel li span.reduce{ margin: 5px 20px !important; } #lazy_modal_progress{ position: absolute; margin-top: 10px; }
Panel の Javaソース
終了時メッセージ表示しない自動で閉じる場合も、コンストラクタとして残します。
メッセージ表示するコンストラクタは、ボタンラベル文字列やボタンのスタイル class属性を
付与できるものを用意します。省略もできます。
import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import org.apache.wicket.ajax.AjaxEventBehavior; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.core.util.string.JavaScriptUtils; import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.markup.head.CssHeaderItem; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Button; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.IModel; import org.apache.wicket.request.resource.CssResourceReference; import org.apache.wicket.request.resource.JavaScriptResourceReference; import org.danekja.java.util.function.serializable.SerializableConsumer; import org.danekja.java.util.function.serializable.SerializableFunction; import org.yipuran.wicketcustom.function.SerialThrowableConsumer; /** * LazyModalPanel */ public class LazyModalPanel extends Panel{ /** * コンストラクタ(自動で閉じる) * @param id Wicket-ID * @param model 処理中メッセージ * @param consumer 目的の処理実行する Throwableな Consumer * 例外発生すると oncatch指定のConsumerが実行される * @param oncatch 目的の処理をするconsumerで例外を捕捉した時に実行するConsumer */ public LazyModalPanel(String id, IModel<String> model , SerializableConsumer<AjaxRequestTarget> consumer , SerializableConsumer<Exception> oncatch){ super(id, model); queue(new Form<Void>("lazy_mocal_form")); queue(new Label("message", Optional.ofNullable(model.getObject()).orElse(""))); queue(new Label("closeLabel", "")); queue(new Button("lazy_mocal_start").add(AjaxEventBehavior.onEvent("click", SerialThrowableConsumer.of(t->{ consumer.accept(t); ModalWindow.closeCurrent(t); },(t, x)->{ oncatch.accept(x); ModalWindow.closeCurrent(t); })))); queue(new Button("lazy_mocal_close")); } public LazyModalPanel(String id, IModel<String> model, String closeLabel , SerializableFunction<AjaxRequestTarget, String> function , SerializableFunction<Exception, String> oncatch){ this(id, model, closeLabel, null, function, oncatch); } public LazyModalPanel(String id, IModel<String> model , SerializableFunction<AjaxRequestTarget, String> function , SerializableFunction<Exception, String> oncatch){ this(id, model, "OK", null, function, oncatch); } /** * コンストラクタ(終了後結果表示する場合) * @param id Wicket-ID * @param model 処理中メッセージ * @param closeLabel CLOSEボタンのラベル * @param stylelist CLOSEボタンに付けるclass属性、 * @param function 目的の処理を実行して正常終了のメッセージを返す Throwable な Function * 例外発生すると oncatch指定の Function が実行される * @param oncatch 目的の処理で例外を捕捉した時に実行する Function * 表示する異常終了のメッセージを返す Function */ public LazyModalPanel(String id, IModel<String> model , String closeLabel , List<String> stylelist , SerializableFunction<AjaxRequestTarget, String> function , SerializableFunction<Exception, String> oncatch){ super(id, model); queue(new Form<Void>("lazy_mocal_form")); final Label mesageLabel = new Label("message", Optional.ofNullable(model.getObject()).orElse("")); mesageLabel.setEscapeModelStrings(false); mesageLabel.setOutputMarkupId(true); queue(mesageLabel); queue(new Label("closeLabel", closeLabel)); queue(new Button("lazy_mocal_start") .add(AjaxEventBehavior.onEvent("click", SerialThrowableConsumer.of(t->{ String s = function.apply(t); mesageLabel.setDefaultModelObject(Optional.ofNullable(s).orElse(null)); t.appendJavaScript("convergementLazy();"); t.add(mesageLabel); },(t, x)->{ String s = oncatch.apply(x); mesageLabel.setDefaultModelObject(Optional.ofNullable(s).orElse(null)); t.appendJavaScript("convergementLazy();"); t.add(mesageLabel); })))); queue(new Button("lazy_mocal_close"){ @Override protected void onComponentTag(ComponentTag tag){ super.onComponentTag(tag); Optional.ofNullable(stylelist).filter(li->li.size() > 0).ifPresent(li->{ tag.put("class", li.stream().collect(Collectors.joining(" "))); }); } }.add(AjaxEventBehavior.onEvent("click", t->ModalWindow.closeCurrent(t)))); } @Override protected void onAfterRender(){ super.onAfterRender(); JavaScriptUtils.writeJavaScript(getResponse() , "setTimeout('sizefitMessageModal();$(\"#lazy_mocal_start\").trigger(\"click\");', 100);"); } @Override public void renderHead(IHeaderResponse response){ super.renderHead(response); response.render(CssHeaderItem.forReference( new CssResourceReference(LazyModalPanel.class, "lazymodal.css"))); response.render(JavaScriptHeaderItem.forReference( new JavaScriptResourceReference(LazyModalPanel.class, "spin.min.js"))); } }
処理終了でメッセージ表示する例の呼び出しコード
Arrays.asList を使えば、ボタンデザインのスタイルも簡単に記述できます
以下は、Bootstrap使用 のボタンの場合です。
final ModalWindow window = new ModalWindow("lazy_window").setResizable(true).setAutoSize(true); queue(window); queue(new Button("link").add(AjaxEventBehavior.onEvent("click", t->{ window.setContent(new LazyModalPanel(window.getContentId(), Model.of("処理中...") , "OK", Arrays.asList("btn", "btn-primary") , u->{ // 時間がかかる処理 return "正常終了<br/>メッセージ"; }, x->{ // 例外捕捉 return "異常終了"; })); window.show(t); })));
上は、Page クラスのHTMLで、wicket:head タグを以下のように書いてます。
<wicket:head> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script> </wicket:head>