そのへんのちらしのうら

調べたこと、学んだこと、おもしろかったこと。

JSP+ServletでシンプルなWebアプリをつくる(5)ー明細部レイアウト

3.開発

3.5 明細部のレイアウトを作成する


検索ボタン押下後に明細部が表示できるようにします。
データベースへの検索処理は実装せず、いったん仮で値を詰めて返すようにします。


①カスタムタグライブラリの導入
明細部のEL式で繰り返し処理を使用したいので、カスタムタグのライブラリをプロジェクトに配置します。
※ライブラリはダウンロード。
f:id:bubox2:20190310000118p:plain
zaikochosei.jspに下記を追加します。

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

②明細部のフォームを作成する
明細部1行の項目と対応するJavaBeansをパッケージ「src/form」配下に作成します。 ■ZaikoChoseiDetail.java

package form;

public class ZaikoChoseiDetail {

    private String index;
    private String no;
    private String location;
    private String itemcd;
    private String lot;
    private String quantity;

    public String getIndex() {
        return index;
    }
    public void setIndex(String index) {
        this.index = index;
    }
    public String getNo() {
        return no;
    }
    public void setNo(String no) {
        this.no = no;
    }
    public String getLocation() {
        return location;
    }
    public void setLocation(String location) {
        this.location = location;
    }
    public String getItemcd() {
        return itemcd;
    }
    public void setItemcd(String itemcd) {
        this.itemcd = itemcd;
    }
    public String getLot() {
        return lot;
    }
    public void setLot(String lot) {
        this.lot = lot;
    }
    public String getQuantity() {
        return quantity;
    }
    public void setQuantity(String quantity) {
        this.quantity = quantity;
    }

}


③画面ヘッダフォームに明細部のプロパティを持たせる
ヘッダのJavaBeansに明細部を追加します。
■ZaikoChoseiForm.java

package form;

import java.util.List;

public class EmployeeForm {

    private String empId;
    private List<EmployeeDetail> detail;

    public String getEmpId() {
        return empId;
    }
    public void setEmpId(String empId) {
        this.empId = empId;
    }
    public List<EmployeeDetail> getDetail() {
        return detail;
    }
    public void setDetail(List<EmployeeDetail> detail) {
        this.detail = detail;
    }

}


④検索処理(仮)の実装
formをmodelに引き渡し、検索結果をformに詰めて戻す部分を実装します。
検索処理自体はいったん仮です。
■ZaikoChoseiModel.java

package model;

import java.util.ArrayList;
import java.util.List;

import form.ZaikoChoseiDetail;
import form.ZaikoChoseiForm;

public class ZaikoChoseiModel {

    public ZaikoChoseiForm search(ZaikoChoseiForm form){

        List<ZaikoChoseiDetail> detail = new ArrayList<ZaikoChoseiDetail>();

        //TODO
        for (int i = 0; i < 3; i++) {
            ZaikoChoseiDetail row = new ZaikoChoseiDetail();
            row.setIndex(Integer.toString(i));
            row.setNo(Integer.toString(i + 1));
            row.setLocation("XXXXXX");
            row.setItemcd("ITEM");
            row.setLot("LOT");
            row.setQuantity(Integer.toString(999));
            detail.add(row);
        }

        form.setDetail(detail);
        return form;
    }

}

■ZaikoChoseiController.java
該当部分を抜粋

   protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {

        try {

            ZaikoChoseiModel model = new ZaikoChoseiModel();

            if (null != request.getParameter("SRH")) {
                //検索
                ZaikoChoseiForm form = model.search(setForm(request));
                //SetAttributeする
                getForm(form, request, response);
                RequestDispatcher dispatcher 
                    = request.getRequestDispatcher("/WEB-INF/jsp/zaikochosei.jsp");
                dispatcher.forward(request, response);
            }

        } catch (Exception ex) {
            //TODO エラーページ
            response.getWriter().append("ERROR:"
                    + ex.getMessage()).append(request.getContextPath());
        }
    }


⑤明細部のレイアウト
■zaikochosei.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>在庫調整画面</title>
</head>
<body>
    在庫調整画面
    <form action="/zaiko/ZaikoChoseiController" method="post">
        <input type="submit" name="SRH" value="検索">
        <input type="submit" name="UPD" value="更新">
        <br>ロケーション
        <input type="text" name="location" value="${form.location}">
        <br>商品コード
        <input type="text" name="itemcd" value="${form.itemcd}">
        <table>
            <tr>
                <td></td>
                <td>No.</td>
                <td>ロケーション</td>
                <td>商品コード</td>
                <td>ロット</td>
                <td>数量</td>
            </tr>
        <c:forEach var="detail" items="${form.detail}">
            <tr>
                <td><input type="hidden" name="index[${detail.index}]"
                    value="${detail.index}"></td>
                <td><input type="text" name="no[${detail.index}]"
                    value="${detail.no}" readonly></td>
                <td><input type="text" name="location[${detail.index}]"
                    value="${detail.location}" readonly></td>
                <td><input type="text" name="itemcd[${detail.index}]"
                    value="${detail.itemcd}" readonly></td>
                <td><input type="text" name="lot[${detail.index}]"
                    value="${detail.lot}" readonly></td>
                <td><input type="text" name="quantity[${detail.index}]"
                    value="${detail.quantity}"></td>
            </tr>
        </c:forEach>
        </table>
    </form>
</body>
</html>

コツその1:<c:forEach>タグのitems属性
items属性にListなどインスタンスのコレクションを指定することで、要素の集合を取得できる。取得した要素は変数varに代入される。

<c:forEach var="detail" items="${form.detail}">

コツその2:name属性にインデックスをつける
明細部項目のname属性に、「no」など各項目名のほか、[インデックス]を付加する。こうすることで、1行ずつ各項目を別々にリクエストパラメータとしてスコープに詰めることができるようになる。
検索だけの画面であれば不要だが、明細部の内容をまとめてリクエストし、各行に処理を加えたい場合に有用。

<td><input type="text" name="no[${detail.index}]" value="${detail.no}" readonly></td>


⑥確認
検索ボタンを押すと、次のようになります。
f:id:bubox2:20190310004432p:plain
ちなみに、このあとにさらに検索ボタンを押下すると、エラーになります。この部分については、更新処理実装のときに改めて実装します。