トップページへ戻る

1、JSPおさらい

trimDirectiveWhitespaces="true"を付けよう!

JSPのおさらい。ここをクリックしてください。

 

2、JSPとjQueryの連携(テーブルとデータ、JSPの準備)

今回は量が多いので、public_html/tomcatに、jqshopというディレクトリを作って、まとめて保存しましょう。

ショップ用のテーブル作成(もうある場合は、それを再利用しても良い)

例 jq_items、jq_customers、jq_ordersテーブルの作成、grant

jqshop.sql (これをviで作っておく。psql db名 < jqshop.sql で一気にテーブルを作成)

   drop table jq_orders;
   drop table jq_items;
   drop table jq_customers;

   create table jq_items(
   id varchar(10) not null primary key,
   name varchar(100) not null,
   price int not null,
   stock int not null
   );
   create table jq_customers(
   id varchar(10) not null primary key,
   name varchar(20) not null
   );

   create table jq_orders(
   id serial primary key,
   order_date timestamp not null default now(),
   cid varchar(10) references jq_customers(id) not null,
   iid varchar(10) references jq_items(id) not null,
   quantity int not null
   );

grant all on jq_items to tomcat;
grant all on jq_customers to tomcat;
grant all on jq_orders to tomcat;

データを入力

例 jqshopdata.sql (psql db名< jqshopdata.sql)

   insert into jq_items values('i1001','SoftBank d0201',23000,100);
   insert into jq_items values('i1002','docomo k3030',45000,100);
   insert into jq_items values('i1003','kddi g5100',32000,100);
   insert into jq_items values('i1004','apple iPhone',65000,100);
   insert into jq_items values('i1005','kddi is08',55000,100);
   insert into jq_customers values('c01','Hanrin');
   insert into jq_customers values('c02','Yamada');
   insert into jq_customers values('c03','Nakabayashi');
   insert into jq_orders(cid,iid,quantity) values('c01','i1003',3);
   insert into jq_orders(cid,iid,quantity) values('c01','i1005',10);
   insert into jq_orders(cid,iid,quantity) values('c02','i1004',4);
   insert into jq_orders(cid,iid,quantity) values('c02','i1001',5);
   insert into jq_orders(cid,iid,quantity) values('c01','i1001',6);
   insert into jq_orders(cid,iid,quantity) values('c01','i1005',2);

jq_itemsのデータを表示するJSPを作成。今のところ、index.jspという名前で。xhtmlを出力させる。jqueryをインポートしておく

例 index.jsp (フォームの文字化け防止、日本国内単位の使用、ページ専用のデータソースのセットをしてあります)

<%@ page contentType="application/xhtml+xml; charset=UTF-8"  trimDirectiveWhitespaces="true" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<fmt:requestEncoding value="UTF-8"/>
<fmt:setLocale value="ja_JP" />
<sql:setDataSource dataSource="jdbc/hanrin"/>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>ktaishop</title>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
</head>
<body>
	<sql:query var="rs" sql="select * from jq_items" />
		<c:forEach items="${rs.rows}" var="i">
		 ${i.name}:${i.price}<br />
		</c:forEach>
</body>
</html>

 

3、JSPから受け取ったデータをjQueryで表示する(1)。

JSPで表示させたデータを、jQueryを用いて操作します。

JSPとjQueryを同時に使う場合、「$」文字が原因でエラーが発生するので、jQueryの部分は、必ず別のファイルにしなければなりません。そのファイルを<script>タグでインポートしておくのを忘れない。

受け取ったデータは、テーブル形式で表示します。

データはjQueryのtr:even(偶数行)tr:odd(奇数行)を使って、色分けして見やすくしましょう。

まずjqshop.jsを書いておく

$(function(){ 
 	/* 偶数行と奇数行の色分け */
 	$("tr:even").css({backgroundColor:"#ffd"});
 	$("tr:odd").css({backgroundColor:"#ff3"});
 });

修正後index.jsp

<%@ page contentType="application/xhtml+xml; charset=UTF-8"  trimDirectiveWhitespaces="true" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>

<fmt:requestEncoding value="UTF-8"/>
<fmt:setLocale value="ja_JP" />
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>ktaishop</title>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
<script type="text/javascript" src="jqshop.js"></script>
</head>

<body>
<sql:setDataSource dataSource="jdbc/hanrin"/>
<sql:query var="rs" sql="select * from jq_items" />
	<table border="1">
		<tr>
			<td>商品ID</td><td>商品名</td><td>価格</td><td>在庫数</td>
		</tr>
<c:forEach items="${rs.rows}" var="i">
		<tr>
			<td>${i.id}</td><td>${i.name}</td><td>${i.price}</td><td>${i.stock}</td>
		</tr>
</c:forEach>
	</table>
</body>
</html>

これで、偶数行と奇数行とがきれいに色分けされた表が見られます。

4、JSPから受け取ったデータをjQueryで表示する(2)。

注文するユーザーをセレクトボックスで選べるようにしておきます。

「在庫数」の横の列に、注文個数を入力できる「テキストボックス」を配置します。

index.jsp(修正後)

<%@ page contentType="application/xhtml+xml; charset=UTF-8"  trimDirectiveWhitespaces="true" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>

<fmt:requestEncoding value="UTF-8"/>
<fmt:setLocale value="ja_JP" />
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<title>ktaishop</title>
		<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
		<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
		<script type="text/javascript" src="jqshop.js"></script>
	</head>
	<body>
<sql:setDataSource dataSource="jdbc/hanrin"/>
<sql:query var="rs" sql="select * from jq_items" />
<sql:query var="rs1" sql="select * from jq_customers" />
	<form action="">
		<fieldset>
			<legend>注文フォーム</legend>
				<select name="customser">
				<c:forEach var="j" items="${rs1.rows}">
					<option value="${j.id}">${j.name}</option>
				</c:forEach>
				</select>
				<label for="customer">注文者を選ぶ</label>
				<table border="1">
				<tr>
					<td>商品ID</td>
					<td>商品名</td>
					<td>価格</td>
					<td>在庫数</td>
					<td>注文個数</td>
				</tr>
				<c:forEach items="${rs.rows}" var="i">
				<tr>
					<td>${i.id}</td>
					<td>${i.name}</td>
                    <td>${i.price}</td>
                    <td>${i.stock}</td>
					<td><input type="text" class="quantity" name="quantity" size="2" value="0" /></td>
				</tr>
				</c:forEach>
				</table>
				<input type="submit" value="注文する" />
			</fieldset>
		</form>
		<div id="warn"></div>
	</body>
</html>

 

入力された値が数字でない場合、警告を出して、値を「0」にしましょう。

数字かどうかは、javascriptのisNaN()関数を使えば判断出来ます。

(jqueryの$("form").submitイベントを使い、全部数字の場合だけ、送信します)

jqshop.js(修正済み)

$(function(){ 

 /* 偶数行と奇数行の色分け */

 $("tr:even").css({backgroundColor:"#ffd"});
 $("tr:odd").css({backgroundColor:"#ff3"});
 
/* 送信前チェック submitの使用*/

 $("form").submit(function(){
 	/* クラスセレクタでテキストボックスそのものの配列を得る */
   var a=$(".quantity");
	/* 数字以外の場合、この変数に1を足してゆく */
   var message=0;
   /* eachで回し、テキストボックスの値を得る。数字以外の文字を0にして、赤で表示*/
 	$.each(a,function(){
 		if($(this).val()==="" || isNaN($(this).val())){
 			message+=1;
		    $(this).css({color:"#f00"});
 			$(this).val(0);
 		} 
 	});
   /* もし、messageが0の場合、数字だけなので、trueを返して、送信処理に移る */ 
 	if(message==0){
 		return true;
 	} 
   /* 数字以外が入力されていたら、送信をキャンセル */
 	$("#warn").html("数字以外の文字があります:"+message+"個見つかりました");
 	    return false; 
 	}); 
 });

5、JSPから受け取ったデータをjQueryで表示する(3)。

個数を入れ終わったら、小計をdivの中に表示してみましょう。

$(this)は現在カーソルがある、選択状態のテキストボックスを意味します。何も入力されていない場合と、数字以外の場合は、エラーを表示します。

単価を取得する時、parent()とprev()メソッドを使って、値を取得します。(テキストボックスの親の、前の前のtextを取得)

計算するときは、取得した値をparseIntして、Javascriptで計算出来るようにしてやらなければなりません。

キーボードを上げた時(keyup時)に、価格と数量をかけ算して、下のdivの中に小計金額を表示します。


jqshop.js(修正後)

$(function(){ 
/* 偶数行と奇数行の色分け */
$("tr:even").css({backgroundColor:"#ffd"});
$("tr:odd").css({backgroundColor:"#ff3"});
/* 送信前チェック*/
$("form").submit(function(){
var a=$(".quantity");
var message=0;
$.each(a,function(){
if($(this).val()==="" || isNaN($(this).val())){
message+=1;
$(this).css({color:"#f00"});
$(this).val(0);
}
});
if(message==0){
return true;
}
$("#warn").html("数字以外の文字があります:"+message+"個見つかりました");
return false;
}); /* 1文字入力されるたびに、数字かどうかチェックする */
$(".quantity").keyup(function(){
var sum=0;
var a=$(".quantity");
$.each(a,function(){
if($(this).val()==="" || isNaN($(this).val())){
$("#warn").html("数字以外の文字があります");
$("#sum").empty();
return false;
}else{
sum+=parseInt($(this).val()) * parseInt($(this).parent().prev().prev().text());
}
$("#sum").html(sum+"円");
});
});
});

6、データベースへの追加

追加する前に、確認画面を表示(JSPで作成)

この機能のためにデータを<input type="hidden">のvalueにセット

index.jsp(修正後)

<%@ page contentType="application/xhtml+xml; charset=UTF-8"  trimDirectiveWhitespaces="true" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>

<fmt:requestEncoding value="UTF-8"/>
<fmt:setLocale value="ja_JP" />
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>ktaishop</title>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
<script type="text/javascript" src="jqshop.js"></script>
</head>
<body>
<sql:setDataSource dataSource="jdbc/hanrin"/>
<sql:query var="rs" sql="select * from jq_items" />
<sql:query var="rs1" sql="select * from jq_customers" />
<form action="confirm.jsp" method="post">
<fieldset>
<legend>注文フォーム</legend>
<select name="customer">
<c:forEach var="j" items="${rs1.rows}">
<option value="${j.id}">${j.name}</option>
</c:forEach>
</select>
<label for="customer">注文者を選ぶ</label>
<table border="1">
<tr>
<td>商品ID</td>
<td>商品名</td>
<td>価格</td>
<td>在庫数</td>
<td>注文個数</td>
</tr>
<c:forEach items="${rs.rows}" var="i">
<tr>
<td>${i.id}</td>
<td>${i.name}</td>
<td>${i.price}</td>
<td>${i.stock}</td>
<td>
<input style="text-align:right" maxlength="2" type="text" class="quantity" name="quantity" size="2" value="0" />
<input type="hidden" name="iid" value="${i.id}" />
<input type="hidden" name="name" value="${i.name}" />
<input type="hidden" name="price" value="${i.price}" />
</td>
</tr>
</c:forEach>
</table>
<input type="submit" value="注文する" />
</fieldset>
</form>
警告:<div id="warn"></div>
小計:<div id="sum"></div>
</body>
</html>

確認画面に、受け取ったデータを表示。

もしも訂正がある場合は、戻って入力をやり直す。<c:set>を使って、<input type="hidden">から来たデータを受け取る。

もう一回、別のページ(注文確定のページ)にデータを渡す必要があるので、さらに<input type="hidden">に値をセット。

confirm.jsp

<%@ page contentType="application/xhtml+xml; charset=UTF-8"  trimDirectiveWhitespaces="true" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<fmt:requestEncoding value="UTF-8"/>
<fmt:setLocale value="ja_JP" />
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>ktaishop</title>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
</head>
<body>
<c:set var="pm" value="${param.customer}" />
<c:set var="pm1" value="${paramValues.iid}" />
<c:set var="pm2" value="${paramValues.name}" />
<c:set var="pm3" value="${paramValues.price}" />
<c:set var="pm4" value="${paramValues.quantity}" />
<form action="fix.jsp" method="post">
<fieldset>
<legend>注文確認</legend>
<table border="1">
<tr>
<td>商品ID</td>
<td>商品名</td>
<td>価格</td>
<td>注文個数</td>
</tr>
<c:forEach items="${pm1}" var="i" varStatus="x">
<tr>
<td>${i}<input type="hidden" name="iid" value="${i}" /></td>
<td>${pm2[x.index]}<input type="hidden" name="name" value="${pm2[x.index]}" /></td>
<td>${pm3[x.index]}<input type="hidden" name="price" value="${pm3[x.index]}" /></td>
<td>${pm4[x.index]}<input type="hidden" name="quantity" value="${pm4[x.index]}" /></td>
</tr>
</c:forEach>
<input type="hidden" name="uid" value="${pm}" />
</table>
<input type="submit" value="注文を確定する" />
<a href="index.jsp"><input type="button" value="戻る" /></a>
</fieldset>
</form>
</body>
</html>

7、データベースへの書き込み

確認が終わったら、insert文を発行し、データベースに反映する。

ちゃんと追加されたかどうか、確認するために、jq_orderテーブルを一覧表示しましょう。

fix.jsp

<%@ page contentType="application/xhtml+xml; charset=UTF-8"  trimDirectiveWhitespaces="true" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<fmt:requestEncoding value="UTF-8"/>
<fmt:setLocale value="ja_JP" />
<sql:setDataSource dataSource="jdbc/hanrin" />
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>ktaishop</title>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
</head>
<body>
<c:set var="pm1" value="${paramValues.iid}" />
<c:set var="pm4" value="${paramValues.quantity}" />
<c:set var="pm" value="${param.uid}" />
<sql:transaction isolation="serializable">
<c:forEach items="${pm1}" var="i" varStatus="x">
<fmt:parseNumber var="qt" value="${pm4[x.index]}" />
<c:if test="${qt > 0}">
<sql:update sql="insert into jq_orders(cid,iid,quantity) values(?,?,?);">
<sql:param value="${pm}" />
<sql:param value="${i}" />
<sql:param value="${qt}" />
</sql:update>
</c:if>
</c:forEach>
</sql:transaction>
注文を確定しました
<a href="index.jsp"><input type="button" value="戻る" /></a>
<hr />
<sql:query var="rs" sql="select * from jq_orders" />
<c:forEach var="j" items="${rs.rows}">
ID=${j.id}:
order_date=${j.order_date}:
cid=${j.cid}:
iid=${j.iid}:
quantity=${j.quantity}<br />
</c:forEach>
</body>
</html>

問題

public_html/tomcat/jqshop/に上記のようなショップアプリケーションを作ってください。

(出来れば、「ログイン認証」を付けてください。ログインしたユーザーIDなどを、セッション変数に入れて使い回す方法が良いかもしれません)

① 「index.jsp」が最初に表示されるページなので、このページだけは必ず作ってください。後は各自の自由でよいでしょう。

② なお、このアプリケーションは、在庫の処理をしていません。
商品が購入されたら、jq_itemsから、売れただけの個数を引いて下さい。


③ 注文できる一番多い数は、個数以下にするため、セレクトボックスを使うとよいでしょう。
またはjQueryを使って、注文最大数を超えた入力があった場合、警告をだして注文数を0にする方法でも良いです。そこら辺は、自由に作ってください。

④ あと、商品の画像を表示するようにしておいてください。

⑤ また、商品数が多くなる(100件200件になると、とても見にくい)ことも考えられるので、ページング(いくつかのページに分ける)も出来る人はやっておいてください。テーブルが増えることになるでしょうが。

この課題は、重要な課題評価の対象になります。(一応動いたら50点あげます)
それでは、頑張ってください!