JSP+ServletでシンプルなWebアプリをつくる(5)ー明細部レイアウト
3.開発
3.5 明細部のレイアウトを作成する
検索ボタン押下後に明細部が表示できるようにします。
データベースへの検索処理は実装せず、いったん仮で値を詰めて返すようにします。
①カスタムタグライブラリの導入
明細部のEL式で繰り返し処理を使用したいので、カスタムタグのライブラリをプロジェクトに配置します。
※ライブラリはダウンロード。
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>
⑥確認
検索ボタンを押すと、次のようになります。
ちなみに、このあとにさらに検索ボタンを押下すると、エラーになります。この部分については、更新処理実装のときに改めて実装します。