読者です 読者をやめる 読者になる 読者になる

A Day In The Life

とあるプログラマの備忘録

シンプルなポップアップ画面を作ってみた。

シンプルな検索ポップアップ画面を作ってみました。
今まではwindow.open使ってポップアップさせてwindow.opener使って親画面の値をセットしてましたが違う方法で実装してみました。
現場で使えるかどうかはかなり微妙ですw
画面イメージはこんな感じです。
画面イメージ
まずActionFormから実装していきましょう。

public class OrderItemForm extends ValidatorForm {
    private Product product = new Product();
    private String qty;
    //明細番号
    private int position;
    //検索ポップアップ表示用
    private List<Product> products = new ArrayList<ProductForm>();
    public Product getProduct() {
        return product;
    }
    public void setProduct(Product product) {
        this.product = product;
    }
    :
    以下getter,setter省略
    :
}

public class ProductForm {
    private String id;
    private String name;
    private String unitPrice;
    :
    getter,setter省略
    :
}

となります。

ポップアップ画面と入力画面で1つのActionFormを共有している以外は普通のつくりです。



入力画面のJSPはこんな感じです。

:
省略
:
<script type="text/javascript">
function setTarget(form) {
    form.target = "popup";
}
</script>
:
省略
:
<html:form action="productPopup">
    <html:submit property="search" value="検索" onclick="setTarget(this.form)" />
</html:form>

JavaScriptでform.target = "popup"としていますがこの指定をすることにより別ウインドウ(Firefoxの場合、タブ)が立ち上がります。

form.target = "_blank"としてもいいのですが新しいウインドウがぼこぼこ立ち上がって具合がよくないので名前指定をしています。

このようにすることで別ウインドウは1枚しか立ち上がりません。
struts-config.xmlとActionはこのようになります。

<form-beans>
    <form-bean name="orderItemForm" type="hoge.OrderItemForm" />
</form-beans>
<action path="/productPopup"
    name="orderItemForm"
    validate="false"
    class="hoge.ProductPopupAction" 
    parameter="search=search">
    <forward name="success" path="/hoge/productsPopup.jsp" />
</action>
public class ProductPopupAction extends EventDispatchAction {
    public ActionForward search(ActionMapping mapping,
            ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        OrderItemForm orderItemForm = (OrderItemForm) form;
        //productServiceでDBからデータを取得する
        orderItemForm.setProducts(productService.search());
        return mapping.findForward("success");
    }
}

EventDispatchActionを使っているだけであとは普通です。

これで入力画面の実装は終わりです。

あとはポップアップ画面の実装になります。

まずJSPから

:
省略
:
<script type="text/javascript">
function selected(form) {
    form.action = form.action + "?select=select";
    form.submit();
    window.opener.location.reload();
    window.close();
}
</script>
:
省略
:
<c:forEach items="${orderItemForm.products}"
    var="products" varStatus="status">
    <html:radio idName="products" property="product.id"
      name="orderItemForm" value="id" />
    <c:out value="${products.id}" />
    <c:out value="${products.name}" />
    <c:out value="${products.unitPrice}" />
</c:forEach>
<html:button property="select" value="選択" onclick="selected(this.form);" />

のようになります。

JavaScriptで親画面をリロードするところとhtml:radioタグの使い方がミソです。

あとはポップアップ画面の選択ボタンを押したときのstruts-config.xmlとActionを実装すればOKです(お決まりの実装なので省略します)。
JavaScriptバリバリでやるほうがいいのかわかりませんが、こんな実装方法もありかと思います。