밀린 캡스톤 일지.. 이제서야 쓰다..
이것만 해결하고 써야지 하다가 해결 못해서 며칠 고생하고 드디어 쓴다. 하지만 아직도 해야할게 산더미라는거 ~..~
이제 다시 이프 출근해야되서 짱 바쁠예정
장바구니 기능 구현
선택한 메뉴 정보를 임시로 담고있는 장바구니 정보(메뉴 추가, 수정, 삭제 가능해야함)를 어떻게 유지해야하나 고민했다.
DB에 저장할 데이터도 아니고.. 그냥 인메모리로 들고있자니 페이지 이동되었다가 리로드됐을 때 정보 유지도 안되고..
그렇게 고민하던 중 생각난 방법이 바로 쿠키
에 저장하는거!!
자바스크립트에서 쿠키를 이용하는 방법으로는
cookie.js
https://github.com/js-cookie/js-cookie)jQuery
cookie (https://github.com/carhartl/jquery-cookie)document.cookie
(https://ko.javascript.info/cookie)
이것저것 해보다가 난 3번 방법(document.cookie)을 선택했다.
어디 구글링하다 봤는데 쿠키로 하니 세션으로 하니, DB에 테이블로 쌓아야 한다느니 말이 많았지만.. 난 그냥 쿠키로.. ^^
내가 작성한 cookie.js
[참고] 자바스크립트 쿠키(Cookie) 저장 및 삭제 예제보기 https://webisfree.com/2015-02-04/[%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8]-%EC%BF%A0%ED%82%A4(cookie)-%EC%A0%80%EC%9E%A5-%EB%B0%8F-%EC%82%AD%EC%A0%9C-%EC%98%88%EC%A0%9C%EB%B3%B4%EA%B8%B0
위의 블로그를 참고하여 쿠키를 생성, 조회, 삭제하는 메서드를 작성하였다.
cookie.js
1
2
3
4
5
6
7
function setCookie (cookie_name, value, minutes) {
const exdate = new Date();
exdate.setMinutes(exdate.getMinutes() + minutes);
// const cookie_value = escape(value) + ((minutes == null) ? '' : '; expires=' + exdate.toUTCString());
const cookie_value = value + ((minutes == null) ? '' : '; expires=' + exdate.toUTCString()); // 암호화 끔
document.cookie = cookie_name + '=' + cookie_value;
}
쿠키값 저장 시 저장 기간 단위는 분으로 받음(3분으로 할까 생각중), 인코딩(escape) 과정 생략
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function getCookie(cookie_name) {
var x, y;
var val = document.cookie.split(';');
for (var i = 0; i < val.length; i++) {
x = val[i].substr(0, val[i].indexOf('='));
y = val[i].substr(val[i].indexOf('=') + 1);
x = x.replace(/^\s+|\s+$/g, ''); // 앞과 뒤의 공백 제거하기
if (x == cookie_name) {
// return unescape(y); // unescape로 디코딩 후 값 리턴
return y; // 암호화 끔
}
}
}
위에서 인코딩 과정을 생략했기 때문에 디코딩(unescape) 과정도 생략
1
2
3
function deleteCookie(name) {
document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}
장바구니 기능과 화면 구현
내가 저장할 쿠키의 모양은 dict 형태로 OrderDetails 테이블에 저장할 정보들이다.
1
2
3
4
5
6
7
8
9
shoppingCart = {
menuNo: {
"menuNo" : {메뉴번호},
"menuName" : {메뉴이름},
"count" : {수량},
"menuPrice" : {가격},
"totalPrice" : {수량*가격}
},
}
장바구니 변수 선언
1
let shoppingCartList = getCookie("shoppingCart") ? JSON.parse((getCookie("shoppingCart"))) : {};
장바구니 쿠키가 존재하면 쿠키를 json형태로 바꿔 변수(인메모리)에 저장, 없으면 {}로 초기화
사용자가 장바구니에 담긴 내역을 추가, 수정, 삭제하는 방법에는 여러가지가 있는데 아래와 같다.
- 메뉴 선택 후 메뉴div를 클릭하는 경우
1 2 3 4 5 6 7 8 9 10
function addMenuList(result) { $('#menuList').empty(); $.each(result, function(index, data){ $('#menuList').append($('<div />', { class: 'menu', id: data.menuNo, click: function () { addShoppingCart(data.menuNo, data.menuName, data.menuPrice); } }).
ajax로 카테고리별 메뉴들을 불러와 메뉴 div를 append할때 click 이벤트로 구현
- 장바구니 목록에서 개수 증가, 감소 버튼을 누르거나 취소버튼을 누르는 경우
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
for (key in shoppingCartList) { $('#orderList').append($('<div />', { class: 'orderMenu', id: key // 여기서 shoppingCartList의 key는 menuNo }).append($('<div />', { class: 'orderMenuName', text: shoppingCartList[key]["menuName"] })).append($('<div />', { class: 'orderMenuPrice', text: shoppingCartList[key]["totalPrice"], id: 'price' + key })).append($('<div />', { class: 'orderQuantity', }).append($('<div />', { text: '▼', class: 'orderMenuQuantityDec', click: function() { // 개수 증가 } })).append($('<div />', { text: shoppingCartList[key]["count"], class: 'orderMenuQuantity', id: "cntNum" + key })).append($('<div />', { text: '▲', class: 'orderMenuQuantityInc', id: 'orderMenuIc', click: function() { // 개수 감소 } }))).append($('<div />', { class: 'orderMenuCancel', text: 'CANCEL', click: function() { // 해당 메뉴 삭제 } }))); }
장바구니 영역에 목록을 동적으로 추가하면서 마찬가지로 클릭 이벤트로 해결하였다…
- 메뉴 클릭 addShoppingCart()
- 장바구니에 이미 담겨있는 메뉴를 추가했을 때
1 2 3 4 5
if(menuNo in shoppingCartList) { // 장바구니에 담긴 메뉴일 때 shoppingCartList[menuNo]["count"]++; // 1개씩 추가 shoppingCartList[menuNo]["totalPrice"] += shoppingCartList[menuNo]["menuPrice"]; setCookie("shoppingCart", JSON.stringify(shoppingCartList), 3); // 쿠키에 변경 사항 새로 저장 }
해당 메뉴의 count와 totalPrice를 증가시켜준 뒤 다시 쿠키값으로 저장
처음에는 쿠키를 delete하고 set해줬는데 지우지 않고 그냥 set만 해줘도 덮어씌워지는 듯 함! - 메뉴 클릭 > 장바구니에 없는 새로운 메뉴를 추가하였을 때
1 2 3 4 5 6 7 8 9 10
else { // 장바구니에 담겨있지 않던 메뉴일 때 shoppingCartList[menuNo] = { menuNo: menuNo, menuName: menuName, count: 1, menuPrice: menuPrice, totalPrice: menuPrice } setCookie("shoppingCart", JSON.stringify(shoppingCartList), 3); }
사전 형태로 장바구니에 저장할 정보를 만들고 이를 쿠키에 저장
주의할 점은 인메모리 장바구니 정보는 json형식이지만 쿠키값은 string으로 저장됨으로 JSON.stringfy 해줘야함
stringify 안하고 바로 저장했을 때
- 장바구니에 이미 담겨있는 메뉴를 추가했을 때
- 장바구니 영역에서의 조정
- 수량 증가
1 2 3 4 5 6 7 8 9 10
//수량, 가격 증가 shoppingCartDict[menuNo]["count"] += 1; shoppingCartDict[menuNo]["totalPrice"] += shoppingCartDict[menuNo]["menuPrice"]; // 증가된 수량과 가격으로 바꿔줌 $('#cntNum' + $(this).parent().parent().attr('id')).text(shoppingCartList[$(this).parent().parent().attr('id')]["count"]); $('#price' + $(this).parent().parent().attr('id')).text(shoppingCartList[$(this).parent().parent().attr('id')]["totalPrice"]); // 쿠키 다시 저장 setCookie("shoppingCart", JSON.stringify(shoppingCartList), 3);
- 수량 감소
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// 감소된 수량이 0 이하일 때 if (orderMenuDec($(this).parent().parent().attr('id'), shoppingCartList == false)) { if (delete shoppingCartList[$(this).parent().parent().attr('id')]) { // 쿠키값과 이어지는 메모리변수에서 해당 메뉴 삭제 $(this).parent().parent().remove(); // 화면에서 삭제 setCookie("shoppingCart", JSON.stringify(shoppingCartList), 3); } } else { // 보여지는 화면에서 수량과 가격 수정 $('#cntNum' + $(this).parent().parent().attr('id')).text(shoppingCartList[$(this).parent().parent().attr('id')]["count"]); $('#price' + $(this).parent().parent().attr('id')).text(shoppingCartList[$(this).parent().parent().attr('id')]["totalPrice"]); // 쿠키 새로 저장 setCookie("shoppingCart", JSON.stringify(shoppingCartList), 3); }
1 2 3 4 5 6 7 8 9
const orderMenuDec = (menuNo, shoppingCartDict) => { if (shoppingCartDict[menuNo]["count"] == 1) { return false; } else { shoppingCartDict[menuNo]["count"] -= 1; shoppingCartDict[menuNo]["totalPrice"] -= shoppingCartDict[menuNo]["menuPrice"]; return true; } }
메뉴의 수량이 현재 1개여서 감소하면 0개로 아예 삭제되어야할 경우를 구별하기 위해 추가해준 내용
javascript에서 dict 사용하기
1
delete dictionary[key]
원하는 키값의 요소 삭제 후 삭제되면 true 반환
- 취소
1 2 3 4
if (delete shoppingCartList[$(this).parent().attr('id')]) { $(this).parent().remove(); // 해당 메뉴 삭제 후 setCookie("shoppingCart", JSON.stringify(shoppingCartList), 3); // 다시 쿠키에 저장 }
- 수량 증가
계속 menuNo 으로 나타나는 아래 값은
1
2
$(this).parent().parent().attr('id') // 증감버튼의 경우 div 한단계 더 아래임
$(this).parent().attr('id') // 취소 버튼
처음 메뉴 div append할때 각 메뉴 영역의 가장 상단에 아이디로 menuNo값을 설정하였기 때문이다!
계속 사용자가 수정함에 따라 바뀌어야하는 메뉴별 가격(orderMenuPrice)와 메뉴 수량(orderMenuQuantity)도 각 메뉴마다 아이디로 식별하기 위해 뒤에 menoNo을 달아서 구별해주었다.
동적으로 장바구니 영역에 할당하고 그 동적으로 할당된 곳에서 또 수정이 들어가려니까 복잡하고 꼬여서 조금 해맸다..(사실 며칠..)
근데 나중에 알고보니 내가 아이디를 잘못 매겨서 안되는거였삼 어이업서
코드가 중복되는 부분도 너무 많고 조금 난잡해서 얼른 나머지 기능들 끝내고 크게 수정좀 해야할 것 같다.
근데.. jQuery 이런식으로 쓰는게 맞는건지.. 뭐 됐으면 된거지..~