상세 컨텐츠

본문 제목

[캡스톤 일지] ~ 11.04(1) 웹 쿠키 이용한 장바구니 기능 구현

학부/캡스톤(a.k.a 졸작)

by ranlan 2021. 11. 8. 01:07

본문

728x90

밀린 캡스톤 일지.. 이제서야 쓰다..

이것만 해결하고 써야지 하다가 해결 못해서 며칠 고생하고 드디어 쓴다

하지만 아직도 해야할게 산더미라는거 ~..~

이제 다시 이프 출근해야되서 짱 바쁠예정

 


 

장바구니 기능 구현하기

선택한 메뉴 정보를 임시로 담고있는 장바구니 정보(메뉴 추가, 수정, 삭제 가능해야함)를 어떻게 유지해야하나 고민했다.

DB에 저장할 데이터도 아니고.. 그냥 인메모리로 들고있자니 페이지 이동되었다가 리로드됐을 때(결제 전 메뉴 수정 등) 정보 유지도 안되고..

그렇게 고민하던 중 생각난 방법이 바로 쿠키값으로 저장하는거!!

 

자바스크립트에서 쿠키를 이용하는 방법으로는

1. cookie.js (https://github.com/js-cookie/js-cookie)

 

GitHub - js-cookie/js-cookie: A simple, lightweight JavaScript API for handling browser cookies

A simple, lightweight JavaScript API for handling browser cookies - GitHub - js-cookie/js-cookie: A simple, lightweight JavaScript API for handling browser cookies

github.com

2. jQuery cookie (https://github.com/carhartl/jquery-cookie)

 

GitHub - carhartl/jquery-cookie: No longer maintained, superseded by JS Cookie:

No longer maintained, superseded by JS Cookie:. Contribute to carhartl/jquery-cookie development by creating an account on GitHub.

github.com

3. document.cookie (https://ko.javascript.info/cookie)

 

쿠키와 document.cookie

 

ko.javascript.info

 

이것저것 해보다가 난 3번 방법(document.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) 저장 및 삭제 예제보기

브라우저의 쿠키(cookie) 데이터저장소를 이용하면 최근에 본 페이지나 키워드등을 저장할 수 있습니다. 온라인쇼핑몰이라면 관심상품으로 등록할 수도 있을테고... 온라인 사전 사이트라면 기존

webisfree.com

 

++ 어디 구글링하다 봤는데 쿠키로 하니 세션으로 하니, 세션이 아니라 DB에 테이블로 쌓아야 한다느니 말이 많았지만,, 난 그냥 쿠키로,,^^

 

 

내가 작성한 cookie.js

위의 블로그를 참고하여 쿠키를 생성, 조회, 삭제하는 메서드를 작성하였다.

 

🗂 js > 📄 cookie.js

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) 과정 생략

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) 과정도 생략

function deleteCookie(name) {
    document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}

 

 

장바구니 기능과 화면 구현

내가 저장할 쿠키의 모양은 dict 형태로 OrderDetails 테이블에 저장할 정보들이다.

shoppingCart = {
    menuNo: {
        "menuNo" : {메뉴번호},
        "menuName" : {메뉴이름},
        "count" : {수량},
        "menuPrice" : {가격},
        "totalPrice" : {수량*가격}
    },
}

장바구니 변수 선언

let shoppingCartList = getCookie("shoppingCart") ? JSON.parse((getCookie("shoppingCart"))) : {};

장바구니 쿠키가 존재하면 쿠키를 json형태로 바꿔 변수(인메모리)에 저장, 없으면 {}로 초기화

 

사용자가 장바구니에 담긴 내역을 추가, 수정, 삭제하는 방법에는 여러가지가 있는데 아래와 같다.

- 메뉴 선택 후 메뉴div를 클릭하는 경우

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 이벤트로 구현

 

- 장바구니 목록에서 개수 증가, 감소 버튼을 누르거나 취소버튼을 누르는 경우

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() {
                // 해당 메뉴 삭제
        }
    })));
}

장바구니 영역에 목록을 동적으로 추가하면서 마찬가지로 클릭 이벤트로 해결하였다...

 

1. 메뉴 클릭 addShoppingCart()

1-1) 장바구니에 이미 담겨있는 메뉴를 추가했을 때

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) 메뉴 클릭 > 장바구니에 없는 새로운 메뉴를 추가하였을 때

else { // 장바구니에 담겨있지 않던 메뉴일 때
    shoppingCartList[menuNo] = {
        menuNo: menuNo,
        menuName: menuName,
        count: 1,
        menuPrice: menuPrice,
        totalPrice: menuPrice
    }
    setCookie("shoppingCart", JSON.stringify(shoppingCartList), 3);
}

사전 형태로 장바구니에 저장할 정보를 만들고 이를 쿠키에 저장

 

* 주의할 점은 인메모리 장바구니 정보는 json형식이지만 쿠키값은 string으로 저장됨으로 JSON.stringfy 해줘야함

 

stringfy 안하고 바로 저장했을 때

 

2. 장바구니 영역에서의 조정

 

2-1) 수량 증가

//수량, 가격 증가
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);

2-2) 수량 감소

// 감소된 수량이 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);    
}
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 사용하기 *

delete dictionary[key]

원하는 키값의 요소 삭제 후 삭제되면 true 반환

 

2-3) 취소

if (delete shoppingCartList[$(this).parent().attr('id')]) {
    $(this).parent().remove(); // 해당 메뉴 삭제 후 
    setCookie("shoppingCart", JSON.stringify(shoppingCartList), 3); // 다시 쿠키에 저장
}

 

 

* 계속 menuNo으로 나타나는 아래 값은

$(this).parent().parent().attr('id') // 증감버튼의 경우 div 한단계 더 아래임
$(this).parent().attr('id') // 취소 버튼

처음 메뉴 div append할때 각 메뉴 영역의 가장 상단에 아이디로 menuNo값을 설정하였기 때문이다!

 

계속 사용자가 수정함에 따라 바뀌어야하는 메뉴별 가격(orderMenuPrice)와 메뉴 수량(orderMenuQuantity)도 각 메뉴마다 아이디로 식별하기 위해 뒤에 menoNo을 달아서 구별해주었다.

 

 

 

 


 

동적으로 장바구니 영역에 할당하고 그 동적으로 할당된 곳에서 또 수정이 들어가려니까 복잡하고 꼬여서 조금 해맸다..(사실 며칠..)

근데 나중에 알고보니 내가 아이디를 잘못 매겨서 안되는거였삼 어이업서

코드가 중복되는 부분도 너무 많고 조금 난잡해서 얼른 나머지 기능들 끝내고 크게 수정좀 해야할 것 같다..

근데.. jQuery 이런식으로 쓰는게 맞는건지.. 흠....

뭐 됐으면 된거지..~

728x90

관련글 더보기

댓글 영역