이전에 제품 수정기능을 만들어봤다면 이번에는 삭제 기능을 추가하고 테스트해보자!
let item = {
init: function () {
let _this = this;
$('#save-item-btn').click(function () {
alert("제품을 등록하였습니다!");
$("#save-form").submit();
});
$("#delete-item-btn").click(function (){
_this.delete();
});
$("#update-item-btn").click(function (){
alert("제품을 수정하였습니다!!!");
$("#update-item-form").submit();
});
},
delete: function () {
if (confirm("제품을 삭제하시겠습니까?")) {
let id = $("#id").val();
$.ajax({
url: '/api/item/' + id,
method: 'DELETE',
// dataType: 'json',
contentType: 'application/json; charset=utf-8'
}).done(function () {
alert("제품이 삭제되었습니다!");
location.href = '/';
}).fail(function (error) {
alert(JSON.stringify(error));
});
} else {
alert("취소하였습니다!");
}
}
}
item.init();
@DeleteMapping("/api/item/{id}")
private Long delete(@PathVariable Long id) {
itemService.deleteById(id);
return id;
}
@Transactional
public void deleteById(Long id) {
Item item = itemRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("해당 ID값이 존재하지않습니다!"));
boolean deleteResult = deleteImg(item.getImgName());
itemRepository.deleteById(id);
}
@Test
public void item_삭제()throws Exception {
//given
Item item = Item.builder()
.detail("a")
.name("b")
.stock(1)
.price(1)
.imgName("aa")
.imgPath("bb")
.member(null)
.build();
Long id = itemRepository.save(item).getId();
//when
itemService.deleteById(id);
//then
assertThat(itemRepository.findAll().size()).isEqualTo(0);
}
이번에 삭제를 진행하면서 제품을 등록할때 만들어놓았던 이미지파일이 같이 삭제되게 수정하였고
수정 기능 또한 다른 이미지로 교환했을때에는 이전의 이미지를 삭제하고 제품이 수정되도록 개선하였다!
private boolean deleteImg(String imgName){
String projectPath = System.getProperty("user.dir") + "\\src\\main\\resources\\static\\image";
File file = new File(projectPath, imgName);
return file.delete();
}
이제 본격적으로 '주문' 기능에대해서 작성해보자
먼저 주문기능은 상품 자세히 보기 페이지에서 가능하다.
자신이 등록한 상품은 자기자신이 주문할 수 없게 진행할 것이고 따라서 로그인한 사람의 정보와 상품을 등록한 정보가 같지 않을때에만 상품을 주문할 수 있는 버튼이 보이게 설정한다.
상품 주문 버튼 클릭시에 상품 주문 폼으로 이동<th:block th:if="${loginMember.email==item.memberResponseDto.email}"> <button type="button" class="btn btn-warning" id="updateForm-item-btn" th:onclick="|location.href='@{|/updateForm/item/${item.id}|}'|">수정</button> <button type="button" class="btn btn-danger" id="delete-item-btn">삭제</button> </th:block> <th:block th:if="${loginMember.email!=item.memberResponseDto.email}"> <button type="button" class="btn btn-info" id="orderForm-item-btn" th:onclick="|location.href='@{|/orderForm/${item.id}|}'|">구매</button> </th:block>
를 사용해서 사용자가 올린글이라면 수정과 삭제 버튼이 아니라면 구매버튼이 보이게 설정!
<!DOCTYPE html>
<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/default_layout}">
<div layout:fragment="content">
<div class="container mt-3">
<h2>주문하기</h2>
<div class="row">
<div class="col-sm-5">
<form action="/api/item" id="save-form" method="post" enctype="multipart/form-data">
<input type="hidden" th:value="${item.id}" name="id" id="id">
<div class="mb-3 mt-3">
<label for="name">상품명:</label>
<input type="text" class="form-control" id="name" th:value="${item.name}" name="name" readonly>
</div>
<div class="mb-3">
<label for="detail">상품 설명:</label>
<input type="text" class="form-control" id="detail" th:value="${item.detail}" name="detail"
readonly>
</div>
<div class="mb-3">
<label for="price">가격:</label>
<input type="number" class="form-control" id="price" th:value="${item.price}" name="price"
readonly>
</div>
<div class="mb-3">
<label for="stock">재고:</label>
<input type="number" class="form-control" id="stock" th:value="${item.stock}" name="stock"
readonly>
</div>
<div class="mb-3">
<label for="status">상태:</label>
<input type="text" class="form-control" id="status" th:value="${item.status}" name="status"
readonly>
</div>
<div class="mb-3">
<label for="img">사진:</label>
<br>
<img th:src="${item.imgPath}" id="img" class="form" width="304" height="236">
</div>
</form>
</div>
<div class="col-sm-1">
</div>
<div class="col-sm-5">
<h3>주문 정보</h3>
<div class="mb-3">
<form action="/api/order" method="post"></form>
<label for="order-count">개수:</label>
<input type="number" class="form-control" id="order-count" placeholder="구매하실 개수를 입력해주세요" name="count">
<br>
<br>
<h4 id="order-price">가격 : </h4>
<br>
<button type="button" id="order-save-btn" class="btn btn-info">주문하기</button>
</div>
</div>
</div>
</div>
<script th:inline="javascript">
let itemForRequest = [[${item}]];
</script>
</div>
</html>
let order = {
init: function () {
let _this = this;
$('#order-count').on('change',function () {
let price = $("#price").val();
let count = $("#order-count").val();
$("#order-price").text("가격 : " + price * count);
});
$("#order-save-btn").on('click',function (){
console.log(itemForRequest);
let data={
item:itemForRequest,
count: $("#order-count").val()
}
$.ajax({
url: '/api/order/' ,
method: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
date: JSON.stringify(data)
}).done(function () {
alert("주문이 완료되었습니다");
location.href = '/';
}).fail(function (error) {
alert(JSON.stringify(error));
});
})
},
}
order.init();
onclick 과 on('click) 차이!
- 선택자.on("click") 과 선택자.click() 의 차이점은 동적으로 이벤트를 바인딩할 수 있는지 없는지의 차이다.
- 선택자.on("click")은 동적으로 생성된 태그에 클릭을 가능하게 이벤트를 바인딩 해준다.
- 선택자.click() 은 최초에 선언된 태그에만 동작한다. 동적으로 생성된 태그에는 안먹힘.
- 선택자.on("click")이 선택자.click() 보다 메모리 관리에 좋다고한다. 이유는 미리 메모리를 할당하지 않기 때문임