장바구니 구현하기

wonny·2022년 9월 25일
0

수업 복습

목록 보기
4/14
post-thumbnail

0922-0923

상세보기

shoplist.jsp

상품을 클릭하면 상품 detailpage로 이동하게 해보자

<script type="text/javascript">
$(function(){
	
	//a태그에 넣은 shopnum 가져오기
	$("a.godetail").click(function(){
		var shopnum=$(this).attr("shopnum");
		//alert(shopnum);
		
	//디테일페이지로 이동
	location.href = "index.jsp?main=shop/detailpage.jsp?shopnum="+shopnum;
		
		
		
	});
});

</script>
		<a shopnum=<%=dto.getShopnum() %>  style="cursor: pointer;" class="godetail">
			<img alt="" src="shopsave/<%=photo%>" class="photo">
			<br>
			<%=dto.getSangpum() %></a>

상품명과 상품이미지에 a태그를 넣고 shopnum=<%=dto.getShopnum()%> 속성을 넣어서 shopnum(상품번호)에 맞는 detailpage로 이동할 수 있게 했다. 이동한 detailpage에서 상품의 상세정보를 확인할 수 있도록 ShopDao에서 getData()를 만들어주자.

ShopDto.java

//oneData - num에 따른 Data 반환
		public ShopDto getData(String shopnum) {
			ShopDto dto = new ShopDto();
			
			Connection conn = db.getConnection();
			PreparedStatement pstmt = null;
			ResultSet rs = null;
			
			String sql = "select * from shop where shopnum=?";

			try {
				pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, shopnum);
				rs = pstmt.executeQuery();
				
				if(rs.next()) {
					dto.setShopnum(rs.getString("shopnum"));
					dto.setCategory(rs.getString("category"));
					dto.setSangpum(rs.getString("sangpum"));
					dto.setPhoto(rs.getString("photo"));
					dto.setPrice(rs.getInt("price"));
					dto.setIpgoday(rs.getString("ipgoday"));
					
				}
				
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally {
				db.dbClose(rs, pstmt, conn);
			}
			
			
			return dto;
		}
		

이정도는 이제 눈감고도(?) 할 수 있따.
이제 detailpage.jsp를 만들고 DB의 상품 정보를 불러오면 된다. 하지만 그 전에 해야할 것이 있다. 이 detailpage에서 장바구니를 누르면 cart table에 주문 내역이 추가된다. 이때 로그인 되어 있는 id의 num 값을 받아와야 cart table에 추가될 때 어떤 회원이 주문했는지 구분할 수 있기 때문에 MemberDao.java 에서 아이디를 통해 num 값을 얻어오는 메서드를 만들어줘야 한다.

MemberDao.java

//아이디를 통해서 num 얻기(장바구니 cart에 사용)
	public String getNum(String id) {
		String num="";
		
		Connection conn = db.getConnection();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		 
		String sql = "select num from member where id=?";
		
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, id);
			rs = pstmt.executeQuery();
			
			if(rs.next()) {
				num=rs.getString("num");
				
			}
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			db.dbClose(rs, pstmt, conn);
		}
		
		return num;
		
	}

로그인 된 아이디를 통해 고유의 회원 num 값을 가져왔으니 이제 그걸 detailpage에 넘겨주고 detailpage를 완성해보자

detailpage.jsp

먼저 shopnum을 받아온다. 그리고

<%
String shopnum = request.getParameter("shopnum");
//로그인 상태인지 확인
String loginok = (String)session.getAttribute("loginok");
//로그인 한 아이디 확인
String myid = (String)session.getAttribute("myid");

//아이디에 해당하는 멤버 테이블의 시퀀스 번호(num) 가져오기
MemberDao mdao = new MemberDao();
String num = mdao.getNum(myid);

//해당 상품에 대한 데이터 가져오기
ShopDao sdao = new ShopDao();
ShopDto dto = sdao.getData(shopnum);

%>

로그인 상태와 로그인된 아이디를 확인하고, myid에 맞는 num 값을 가져와서 cart에 insert될 때 알맞은 num값을 넣어줄 수 있다. 그리고 detailpage에서 상세정보를 출력할 수 있게 shopnum에 맞는 dto를 출력할 수 있다.

<form id="frm">
<input type="hidden" name = "shopnum" value="<%=shopnum%>">
<input type="hidden" name = "num" value="<%=num%>">

<table style="width: 800px;">
<tr>
	<td>
		<div id="photo" style="width: 500px; margin-top: 30px;">
			<img alt="" src="shopsave/<%=dto.getPhoto()%>" class="large img=thumbnail">
		</div>
	</td>
	<td style="width: 300px;">
		<h3>카테고리: <%=dto.getCategory() %></h3>
		<h3>상품명: <%=dto.getSangpum() %></h3>
		<%
		NumberFormat nf = NumberFormat.getCurrencyInstance();
		%>
		<h3>가격: <%=nf.format(dto.getPrice()) %>원</h3>
		
		<!-- 갯수 -->
		<h3>
			<input type="number" min="1" max="10" step="1" name="cnt" value="1">
		</h3>
		
		<div style="margin-top: 100px;">
			<button type="button" class="btn btn-success" style="width: 100px;" id="btncart">장바구니</button>
			<button type="button" class="btn btn-info" style="width: 100px;" onclick="location.href='index.jsp?main=shop/shoplist.jsp'">상품목록</button>
		</div>
		
		
		
	</td>
</tr>

</table>
</form>
<input type="hidden" name = "shopnum" value="<%=shopnum%>">
<input type="hidden" name = "num" value="<%=num%>">

form 안에 hidden으로 shopnum과 num 값을 넣어줘야 한다. 그래야 표시는 안되지만 특정 상품의 detailpage 안에 shopnum과 num값이 넘어갈 수 있기 때문이다.


이제 장바구니를 클릭했을 때 cart 테이블에 해당 계정의 주문이 추가되도록 해보자.

//장바구니 눌렀을 때 
$("#btncart").click(function(){
	var formdata = $("#frm").serialize();
	console.log(formdata);

장바구니 버튼을 눌렀을 때 frm의 name값을 serialize()로 읽어온다. 그리고 제대로 읽어오는지 console에서 확인한다. 제대로 넘어오면 shopDao.java에 insert 메서드를 추가해준다.

shopDao.java

//cart insert
		public void insertCart(CartDto dto) {
				
				Connection conn = db.getConnection();
				PreparedStatement pstmt= null;
				 
				String sql = "insert into cart (shopnum, num, cnt, cartday) values(?,?,?, now())";
				
				try {
					pstmt = conn.prepareStatement(sql);
					pstmt.setString(1, dto.getShopnum());
					pstmt.setString(2, dto.getNum());
					pstmt.setInt(3, dto.getCnt());
							
					pstmt.execute();
					
					
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally {
					db.dbClose(pstmt, conn);
				}
				
			}

cartdetailproc.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<jsp:useBean id="dao" class="data.dao.ShopDao"/>
<jsp:useBean id="dto" class="data.dto.CartDto"/>
<jsp:setProperty property="*" name="dto"/>

<%
dao.insertCart(dto);	
%>

이렇게 간단하게 useBean으로 넘겨도 되고

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%
request.setCharacterEncoding("utf-8");

String shopnum = request.getParameter("shopnum");
String num = request.getParameter("num");
int cnt = Integer.ParseInt(request.getParameter("cnt"));

//dto에 넣기
CartDto dto = new CartDto();
dto.setShopnum(shopnum);
dto.setNum(num);
dto.setCnt(cnt);

//dao를 통해서 insert
ShopDao dao = new ShopDao();
dao.insertCart(dto);

%>    

이렇게 풀어 써도 좋다..
이제 다시 detailpage.jsp 장바구니 클릭했을 때 로그인 된 아이디의 장바구니에 추가되는 ajax를 만들어준다.

detailpage.jsp

<script type="text/javascript">
//장바구니 눌렀을 때 
$("#btncart").click(function(){
	var formdata = $("#frm").serialize();
	console.log(formdata);
	
	 $.ajax({
	      
	      type:"get",
	        dataType:"html",
	        url:"shop/cartdetailproc.jsp",
	        data:formdata,
	        success:function(){

	         alert("success");
	      
	           }, statutsCode:{
	           404:function(){
	              alert("파일을 찾을 수 없습니다.");
	           },500:function(){
	              alert("서버오류, 오타");
	           }
	        }
	     }); 
	
});

</script>

장바구니에 제품들을 추가하긴 했는데, 카트에는 모든 장바구니 추가제품이 한번에 들어가있다. 즉, 모든 아이디가 추가한 장바구니 제품들이 한번에 다 들어가있다. 하지만 로그인 되어 있는 계정이 추가한 장바구니만 따로 봐야하니까 내가 볼 장바구니를 조회해보자.

mysql

select c.idx, s.sangpum, s.shopnum, s.photo, s.price, c.cnt, c.cartday
from cart c, shop s, member m
where c.shopnum = s.shopnum and c.num = m.num;

cart에 있는 shopnum과 shop에 있는 shopnum이 일치하면서, cart에 있는 num(회원num)과 member에 있는 num일치하는 조건

sql문을 실행하면 위처럼 나오는데 아직은 모든 id의 장바구니 추가가 다 조회된다. 내가 원하는 id에 해당하는 장바구니 데이터를 확인하기 위해서는 ShopDao.java에서 해당 id에 대한 것만 나오도록 조건을 주는 메서드를 만들어야 한다.

ShopDao.java

//cart 출력(아이디별로)  
//list에 Dto를 cart, shop, member을 넣어야 하니까 hashmap으로 준다

		public List<HashMap<String, String>> getCartList(String id){
			List<HashMap<String, String>> list = new ArrayList<>();
			
			Connection conn = db.getConnection();
			PreparedStatement pstmt = null;
			ResultSet rs = null;
			
			String sql = "select c.idx, s.sangpum, s.shopnum, s.photo, s.price, c.cnt, c.cartday "
					+ "from cart c, shop s, member m "
					+ "where c.shopnum = s.shopnum and c.num = m.num and m.id=?";
			
			try {
				pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, id);
				rs = pstmt.executeQuery();
				
				while(rs.next()) {
					HashMap<String, String> map = new HashMap<>();
					
					map.put("idx", rs.getString("idx"));
					map.put("sangpum", rs.getString("sangpum"));
					map.put("shopnum", rs.getString("shopnum"));
					map.put("photo", rs.getString("photo"));
					map.put("price", rs.getString("price"));
					map.put("cnt", rs.getString("cnt"));
					map.put("cartday", rs.getString("cartday"));
					
					list.add(map);
				}
				
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally {
				db.dbClose(rs, pstmt, conn);
			}
					
			
			return list;
			
			
		}
		
public List<HashMap<String, String>> getCartList(String id)

보통 List<~Dto>를 넣는데 여기에는 shop, member, cart 세개의 Dto값이 들어가기 때문에 HashMap을 넣어준다. Map은 key 값에 따른 value값을 구하는 것으로, HashMap<String,String>은 key값과 value값을 모두 String으로 얻을 것이라는 뜻이다.
그리고 로그인 된 id에 대한 것만 나오게 getCartList()에 String id를 넣어준다.

String sql = "select c.idx, s.sangpum, s.shopnum, s.photo, s.price, c.cnt, c.cartday "
					+ "from cart c, shop s, member m "
					+ "where c.shopnum = s.shopnum and c.num = m.num and m.id=?";

아까 전체 장바구니 조회했던 sql문 마지막에 m.id=?를 추가해서 id별 장바구니 조회를 가능하게 해준다. 이제 mycart.jsp를 만들어서 장바구니를 클릭했을 때 장바구니에 제품을 추가하고, 장바구니로 바로 이동하게 해보자.

<script type="text/javascript">
//장바구니 눌렀을 때 
$("#btncart").click(function(){
	var formdata = $("#frm").serialize();
	console.log(formdata);
	
	 $.ajax({
	      
	      type:"get",
	        dataType:"html",
	        url:"shop/cartdetailproc.jsp",
	        data:formdata,
	        success:function(){

	         //alert("success");
	         //장바구니로 이동
	          var a = confirm("상품을 장바구니에 담았습니다.\n장바구니로 이동하시겠습니까?")
	          if(a){
	             location.href="index.jsp?main=shop/mycart.jsp";
	          }
	         
	         
	           }, statutsCode:{
	           404:function(){
	              alert("파일을 찾을 수 없습니다.");
	           },500:function(){
	              alert("서버오류, 오타");
	           }
	        }
	     }); 

	
});


</script>

아까 만들어줬던 클릭 이벤트의 ajax에서 성공 후 mycart.jsp로 이동하게 한다.

mycart.jsp

장바구니 목록을 볼 수 있는 mycart.jsp를 만들어보자.

<%
//로그인 되어있는 아이디 가져오기
String id = (String)session.getAttribute("myid");
//id에 맞는 장바구니 목록 불러오기
ShopDao dao = new ShopDao();
List<HashMap<String,String>> list = dao.getCartList(id);
%>

지금 로그인 되어 있는 아이디를 가져오고,
id에 맞는 장바구니 목록을 불러오기 위해 dao.getCartList()에 위에서 불러온 id를 넣어준다.
일단 목록이 나올 수 있도록 html을 작성해준다.

body>
<h4 class="alert alert-warning" style="width: 1000px;"><%=id %>님의 장바구니</h4>
<table class="table table-striped" style="width: 1000px;">

	
	<tr>
		<th style="width: 30px;"><input type="checkbox" id="allcheck"></th>
		<th style="width: 500px;">상품 정보</th>
		<th style="width: 200px;">상품 가격</th>
	</tr>
	
	<%
	NumberFormat nf = NumberFormat.getCurrencyInstance();
	int allmoney=0;
	
	for(int i=0;i<list.size();i++){
		HashMap<String, String> map = list.get(i); //put으로 넣어놓은걸 get(i)로 가져온다
		%>
		<tr>
		<td>
			<input type="checkbox" name="idx" class="idxchk" idx="<%=map.get("idx")%>">
		</td>
		
		<td>
			<div shopnum=<%=map.get("shopnum") %> class="sangpum">
			<img alt="" src="shopsave/<%=map.get("photo")%>" class="photo" style="float: left; margin-right: 20px;">
			<h4>상품명: <%=map.get("sangpum") %></h4>
			<h4>가격: <%=map.get("price") %>원</h4>
			<h4>갯수: <%=map.get("cnt") %>개</h4>
			<h4>주문날짜: <%=map.get("cartday") %></h4>
			</div>
		</td>
			
			<td>
			<%
			int price = Integer.parseInt(map.get("price"));
			int cnt = Integer.parseInt(map.get("cnt"));
			int tot = price*cnt;
			allmoney+=tot;
			%>
			<h4 style="float: right;">가격: <%=nf.format(tot) %>원  <span class="cartdel glyphicon glyphicon-trash" idx="<%=map.get("idx")%>"></span></h4>
			
			</td>
		</tr>	
		
	<%}
	%>
	
		<tr>
		<td colspan="3">
			<button type="button" class="btn btn-danger" id="btndel">선택상품 삭제</button>
			<span> <b style="color: green; font-size: 1.5em; float: right;" >총 금액: <%=nf.format(allmoney) %>원</b></span><br>

		</td>
		</tr>

</table>
</body>

그리고 장바구니에 추가되어 있는 제품 이미지나 제품명을 클릭하면 제품 상세보기로 넘어가는 스크립트를 작성한다.

//상품 누르면 상세보기 들어가가ㅣ
	$("div.sangpum").click(function(){
		var shopnum = $(this).attr("shopnum");
		location.href="index.jsp?main=shop/detailpage.jsp?shopnum="+shopnum;
		
	});

그리고 만들어 놓은 체크박스에 대해서 전체선택을 눌렀을 때 전체선택/해제가 되도록 해준다.

//전체 체크하기
	$("#allcheck").click(function(){
		//전체 체크
		var chk = $(this).is(":checked");
		console.log(chk);
		
		//전체 체크값을 글 앞의 체크에 일괄 전달
		$(".idxchk").prop("checked",chk);
		
	});

장바구니 삭제

mycart.jsp 페이지를 완성했으면 이제
1) 삭제 버튼 눌렀을 때 체크된 제품 삭제
2) 제품 옆 삭제 그림을 눌렀을 때 데이터가 삭제되도록 해보자.
일단ShopDao.jsp에서 삭제 메서드를 만들어준다.

ShopDao.java

//delete
		public void deleteCart(String idx) {
			Connection conn = db.getConnection();
			PreparedStatement pstmt = null;
			
			String sql = "delete from cart where idx=?";
			
			try {
				pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, idx);
				pstmt.execute();
				
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally {
				db.dbClose(pstmt, conn);
			}
				
			
		}

그리고 deleteCart를 수행할 cartdelete.jsp를 만들어준다.

cartdelete.jsp

<%
String idx = request.getParameter("idx");
ShopDao dao = new ShopDao();
dao.deleteCart(idx);
%>

이제 1) 삭제 버튼 눌렀을 때 체크 제품 삭제하기 2) 삭제 그림 눌렀을 때 해당 제품 삭제하기를 해줘야 하는데, 둘 다 같은 dao에서 같은 delete처리이기 때문에 사용자 함수에 ajax로 삭제를 주고 호출하면 편하다.

//사용자 함수 - 삭제
function del(idx){
	
	$.ajax({
		
		type:"get",
		url:"shop/cartdelete.jsp",
		dataType:"html",
		data:{"idx":idx},
		success:function(){
			
		}
		
	});
}

1) 삭제 그림 눌렀을 때 해당 제품 삭제

<span class="cartdel glyphicon glyphicon-trash" idx="<%=map.get("idx")%>"></span>

해당 span에 idx값이 넣어져 있어야 해당 데이터를 정확하게 삭제할 수 있다.

$("span.cartdel").click(function(){
		var idx = $(this).attr("idx");
		//alert(idx);
		
		var a = confirm("삭제하시겠습니까?");
		if(a){
			del(idx);
			location.reload(); //새로고침
		}
		
	});

idx 속성을 받아와서 그림을 눌렀을 때 잘 넘어오는지 확인하고, del(idx) 사용자 함수를 호출한다.

2) 체크한 제품 삭제하기

	//선택된 상품 장바구니에서 삭제하기
	$("#btndel").click(function(){
		//체크된 길이 구하기
		var len = $(".idxchk:checked").length;
		if(len==0){
			alert("장바구니에서 삭제할 상품을 선택해주세요");
			return;
		}
			var a = confirm(len+"개의 상품을 삭제하시겠습니까?");
			
			$(".idxchk:checked").each(function(i,ele){
			
			 var idx = $(this).attr("idx");
			 //console.log(idx); //이걸 넣어도 idx 값은 안넘어오고 전체체크박스에 대한 true/false값만 나온다..?
			 
			 //선택한 제품 모두 삭제하기
			 del(idx);
			 
		 });
		 
		 //페이지 새로고침
		 location.reload();
			
			
		
	});
	

체크된 제품들에 한해서 idx 값을 확인하고 del(idx)를 호출하는 것을 반복한다.

오류)) 체크한 제품 삭제를 실행할 때 n개의 상품을 삭제하시겠습니까? 도 나오고 새로고침까지 됐는데 삭제가 전혀 안먹혔다. 코드를 확인해보니 제품 옆에 있는 체크박스 input 태그에 idx="<%=map.get("idx")%>"가 아니라 value="<%=map.get("idx")%>로 되어 있어서 idx 값을 읽어오지 못한 것이었다.

profile
하다 보면 되겠지요..!

0개의 댓글