7주짜리 파이널 프로젝트 주제는 비대면 세탁 서비스
내가 처음 맡게 된건 '주문하기' 구현하는 것
※ 첫번째 난관 멀티셀렉트 구현
리액트를 배우기 전이었으나 멀티셀렉트 기능은 무조건 리액트로 구현하는게 편할거라는 정보를 얻었음
인도사람의 유튜브를 열심히 시청하여 리액트로 어찌저찌 작동하는 멀티셀렉트를 만들어내는데에는 성공

문제점 1. 한 상품당 1개밖에 선택을 못함
- 위 링크를 통해 사용할 수 있는 select 패키지를 사용하면 멀티셀렉트가 구현되긴 하나
한 항목당 한번씩만 선택할 수 있는 멀티셀렉트가 구현됨.

문제점 2. 스프링부트에 적용하는 방법을 모르겠음
- 한 상품당 한개씩만 주문할 수 있도록 (..) 구현을 한다쳐도
만든 jsx 를 스프링부트 프로젝트에 어떻게 가져와서 어떻게
사용해야하는지 모르겠음. 이틀정도 모든걸 stop 하고 이것만 찾았었는데 알아내는데 실패함
최종결과
여러 시도를 해봤고 3일 정도를 허비함
새로운 시도들을 했을 때 1단계인 구현은 되나 2,3 단계인 응용, 문제해결에서 시간을 크게 잡아먹혔음
일단 내가 맡은 부분은 시간내로 완성을 해야하니, 좋은 코드는 아닐지라도 의도대로 움직이게만 구현해보자 라는 결론.
jquery 와 ajax 로 구현함

orderMake.jsp
<div class="orderInfo-order-select-wrapper">
<div class="title-select">세탁물 선택</div>
<c:import url="/laundryService/order/orderMakeSelect">
<c:param name="categoryGroup" value="1"></c:param>
</c:import>
<div id="categoryDiv">
<div id="categoryNameDiv" class="categoryDiv-div">상품</div>
<div id="categoryPriceDiv" class="categoryDiv-div">금액</div>
<div id="categoryQTYDiv" class="categoryDiv-div">수량</div>
<div id="categoryTotalDiv" class="categoryDiv-div">총금액</div>
</div>
<div id="order-item-form-div">
<div class="order-item-Div"></div>
</div>
<div id="totalPriceDiv">
총 : <input type="text" name="totalPriceMake" id="totalPriceMake"
value=""></input>원
</div>
</div>
orderMakeSelect.jsp
<div class="orderInfo-order">
<div class="order-select-wrap">
<select class="mulit-select" name="order-item" id="order-item">
<option value="" selected>선택하세요</option>
<c:forEach var = "vo" items ="${list }">
<option value="${vo.no} ">${vo.categoryName} </option>
</c:forEach>
</select>
<div class="addBtnWrap"><button class="addBtn" id="orderAddBtn">추가</button> <i class="fa-solid fa-circle-plus" id="plusI"></i></div>
</div>
</div>
js
- select option value 에 상품 번호를 넣어놓고
'추가' 버튼을 눌렀을 때 no에 해당하는 vo 를 가져와서 (이때 ajax 를 처음으로 사용해봄. ajax 배우기 전)
appendTo 하여 사용자가 선택한 상품의 정보를 볼 수 있도록 한다
- 이 때 배열에에 선택한 상품의 번호들을 넣어놓아 같은 상품이 중복으로 선택되는 것을 방지한다
- 새로운 상품이 추가될때마다 input 태그의 class 가 .priceByQty 인 것의 value 를 배열에 넣고,
반복문으로 배열 안의 값들을 모두 더해 사용자가 총 가격을 볼 수 있도록한다
$('#orderAddBtn').click(function () {
var itemNo = $('#order-item').val();
var itemInfo = {"no": itemNo};
$.ajax({
url: '/launer/laundryService/order/optionInfo',
type: 'GET',
data: itemInfo,
success: function (vo) {
//모든 input 태그의 value를 배열에 저장
//이미 배열에 값이 있다면 return false
//없다면 새로운 input 태그 생성
const list = new Array();
$("input[name=no]").each(function (index, item) {
list.push($(item).val());
});
var cNo = (vo.no).toString();
const isInArray = list.includes(cNo);
if (isInArray) {
alert("이미 선택된 상품입니다");
return false;
}
var tagAdd = "<div class ='testForm'><input type = 'hidden' name = 'no' class ='tagInputAdd' value=" + vo.no + ">"
+ "<input type ='text' name = 'itemName' class ='tagAddDiv' readonly value=" + vo.categoryName + ">"
+ "<input type = 'text' name = 'itemPrice' class ='tagAddDiv' readonly value=" + vo.price + ">"
+ "<select class='mulit-select' name='order-num' id='order-num'>"
+ "<c:forEach var ='cnt' begin ='1' end='10' step='1'>"
+ "<option >${cnt}</option>"
+ "</c:forEach>"
+ "</select>"
+ "<input type ='text' name='priceByQty' class = 'priceByQty' readonly style='border:none' value=" + vo.price + " >"
+ "<div id ='xWrap' style='display:inline-block'><a href=# onclick='event.preventDefault()' id='delBtn'><i class='fa-solid fa-xmark' id ='XDel'></i></a></div>"
+ "</div>";
$(tagAdd).appendTo(".order-item-Div");
const totalPriceMake = new Array();
let sum = 0;
$(".priceByQty").each(function (index, item) {
totalPriceMake.push($(item).val());
});
for (let i = 0; i < totalPriceMake.length; i++) {
const intTotalPrice = Number(totalPriceMake[i]);
sum += intTotalPrice;
}
$("#totalPriceMake").attr("value", sum);
},
error: function () {
alert("상품을 선택하세요");
}
});
});
나의 계획 조건에 만족하는 멀티셀렉트를 구현했다.
여기서 두번째 난관
그래서 주문정보를 어떻게 넘길건데 ?
바로 생각나는 방법이있었으나.. 별로 사용하고 싶지않은 방법이었음
뭐 결론만 말하자면 결국 처음에 떠올린 그 방법을 사용했음
※ 두번째 난관 vo list 를 컨트롤러로 넘기기
상품 추가 버튼을 누르면 아래 testForm 이 .order-item-div 안에 생성된다
주문하기 버튼을 눌렀을때 아래의 방식으로 생성된 여러개의 testForm 데이터를 컨트롤러로 넘겨야하는것
var tagAdd = "<div class ='testForm'>
<input type = 'hidden' name = 'no' class ='tagInputAdd' value=" + vo.no + ">"
+ "<input type ='text' name = 'itemName' class ='tagAddDiv' readonly value=" + vo.categoryName + ">"
+ "<input type = 'text' name = 'itemPrice' class ='tagAddDiv' readonly value=" + vo.price + ">"
+ "<select class='mulit-select' name='order-num' id='order-num'>"
+ "<c:forEach var ='cnt' begin ='1' end='10' step='1'>"
+ "<option >${cnt}</option>"
+ "</c:forEach>"
+ "</select>"
+ "<input type ='text' name='priceByQty' class = 'priceByQty' readonly style='border:none' value=" + vo.price + " >"
+ "</div>";
$(tagAdd).appendTo(".order-item-Div");
방법은 뻔하다
각 input 의 value 를 변수에 저장하고 이를 연결하여 문자열로 컨트롤러에 보내는 것
상품번호, 상품명, 상품가격, 수량, 총가격 | 상품번호, 상품명, 상품가격, 수량, 총가격 | 상품번호, 상품명, 상품가격, 수량, 총가격 ...
이런 모양으로 컨트롤러에 보내게 되는 것이다 (.. ㅠ )
js
$('#orderBtn').click(function () {
if ($("input[name=itemName]").length < 1) {
alert("상품을 선택해주세요");
event.preventDefault();
return false;
}
let dataArr = [];
let dataList = $(".testForm");
console.log(dataList);
var param_string ="";
$.each(dataList, (idx, item) => {
let no = item.childNodes[0].defaultValue;
let name = item.childNodes[1].defaultValue;
let price = item.childNodes[2].defaultValue;
let qty = item.childNodes[3].value;
let sum = item.childNodes[4].defaultValue;
param_string+=
no +","+name+","+price+","+ qty + "," + sum + "|"
});
console.log("param_string = "+param_string);
$('#param').val(param_string);
$('form[name=frm]').attr('action',"<c:url value='/laundryService/order/orderConfirm'/>");
$('form[name=frm]').attr('method','post');
});
orderController 컨트롤러
- (,), (|) 기준으로 문자열(String param) 을 split 하여 map 에 저장하고, 각 map 을 list 에 add 하여
뷰 (결제전 최종확인 창) 로 내려보냄
@PostMapping("/orderConfirm")
public String orderConfirm_post(@RequestParam String param, Model model, HttpSession session) {
logger.info("결제전 최종확인 화면, param_string 파라미터 = {}",param);
//회원정보 불러오기
int no = (int) session.getAttribute("no");
logger.info("결제전 최종확인 화면, 파라미터 userid ={}", no);
UserVO vo = userService.selectById(no);
logger.info("회원정보조회 vo={}",vo);
//회원 주소 정보 불러오기
HashMap<String,Object> mapAddress = userService.selectByIdAddress(no);
logger.info("회원주소조회={}",mapAddress);
//주문정보확인
List<Map<String, Object>> list= new ArrayList<>();
logger.info("파라미터 param={}", param);
String paramString[] = param.split("[|]");
String setParamString[];
for(String str : paramString) logger.info("분리 후 str={}", str);
int paramPrice = 0;
for(int i=0;i<paramString.length;i++) {
Map<String, Object> map = new HashMap<>();
setParamString = paramString[i].split(",");
map.put("categoryNo", setParamString[0]);
map.put("name", setParamString[1]);
map.put("price", setParamString[2]);
map.put("quan", setParamString[3]);
map.put("sum", setParamString[4]);
//총 결제금액 int 로 실어보내기
paramPrice += Integer.parseInt( setParamString[4]);
list.add(map);
}
logger.info("최종금액 ={}",paramPrice);
model.addAttribute("userVo", vo);
model.addAttribute("list", list);
model.addAttribute("paramPrice", paramPrice);
model.addAttribute("param", param);
model.addAttribute("map", mapAddress);
return "/laundryService/order/orderConfirm";
}
이후 주문정보를 db에 넣는 과정은 어려움 없이 진행했다.
분명 .. 더좋은 방법이있을꺼다 json 을 이용한다던지 하는 ..
사실 json 사용 방법을 알게된 지금도 명확하게 떠오르는 방법은 없다
개인적으로 토이프로젝트를 만들어볼 계획인데 같은걸 더 좋은 방법으로 시도해볼꺼다.
=> 지금 같은 문제를 마주친다면 ?
해결 1 ) DataType 을 json 로 설정해서 ajax 로 넘긴다 ! ==> XX
- ajax 로 넘길 시 json 객체로 만들어야 하는데, 컨트롤러에서 요청을 받고 다른 뷰페이지로 넘길 수 없음
(방법있나 .. ? 현재로서는 모르겠음) 인줄 알았는데 이게 되네
해결 2 ) vo list 에 데이터들을 저장 후 post 방식으로 컨트롤러에 전달 ! ==> OO
1. 프로퍼티를 저장하는 VO 객체를 만든다. (해당 객체를 VO vo)
2 List<vo>를 담고있는 VO 객체를 만든다. (해당 객체를 VOs vos)
3. Controller에 넘겨줄 input의 name을 'vos[i].프로퍼티명' 형태로 정한다.
4. submit이 될 경우 Controller에서는 'ModelAtturibete VOs ~~' 로 받아준다.
clear !
★★★ 해결 3 ) view 에서 view 로 데이터를 넘기기
- 지금까지 view 에서 view 로 데이터를 넘길 때 항상
view => controller => view 방식으로 데이터를 넘겼었다.
컨트롤러에서 데이터를 가공하는것도 아닌데 view => view 방법을 몰라서 !
빛권순
: localStorage 를 사용하면 해결됨
sessionStorage : 브라우저 상에 데이터를 저장할 수 있는 웹 스토리지.
- String 형식만 지원함
- 세션 스토리지는 웹페이지의 세션이 끝날 때 저장된 데이터가 지워짐
참조 : https://www.daleseo.com/js-web-storage/
$("#resultbtn").click(() => {
let formData = [];
document.querySelectorAll("#park div").forEach(item => {
let tempData = {
name: $(item).find("input[name=name]").val(),
price: $(item).find("input[name=price]").val(),
sum: $(item).find("select[name=sum]").val()
}
console.log(tempData);
formDate.push(tempData);
});
console.log(formData);
console.log(JSON.stringify(formDate));
//
sessionStorage.setItem("json", JSON.stringify(formData)); //객체를 문자열로 변환, 그 후 저장
location.href = "/test/2";
// $("#park form").submit();
});
1. input 파라미터를 JSON 형태로 만들어준다 (tempData) -- sessionStorage는 문자열만 저장하기 때문
2. 문자열로 변환 후 sessionStorage에 저장한다
3. location.href 사용하여 페이지 리다이렉트
4. test/2 페이지에서 이런형식으로 받으면 json 형식으로 view <=> view 데이터를 전달할수있게된다
let temp = JSON.parse(sessionStorage.getItem("json"));
console.log(temp);
'프로젝트' 카테고리의 다른 글
| [ Spring Boot 프로젝트 ] 결제하기 / 결제완료 문자발송 (0) | 2022.07.14 |
|---|---|
| [ Spring Boot 프로젝트 ] 포인트 로직 (0) | 2022.07.12 |
| [개인프로젝트_항공예약프로그램] (0) | 2022.05.07 |
| [개인프로젝트_항공예약프로그램] DB연결 메서드 (0) | 2022.04.24 |
| [개인프로젝트_항공예약프로그램] 개요 / DB설계 (0) | 2022.04.24 |