AJAX를 이용한 실시간 중복체크 2 (업데이트)

coding S's avatar
Apr 26, 2024
AJAX를 이용한 실시간 중복체크 2 (업데이트)
수정하려는 상품의 기존 이름을 입력해도 그 이름이 데이터베이스에 이미 존재하기 때문에 자꾸 중복 됐다고 나온다. 이 문제를 해결하기 위해, 상품명 중복 체크 시 현재 수정하고자 하는 상품의 ID를 함께 전송하여, 서버 측에서는 해당 ID의 상품을 제외한 나머지 상품들 사이에서 상품명 중복을 체크하도록 로직을 수정해야 함!

1. 상품명 중복 체크 시 상품 ID 전송하기

<!-- 상품 정보 입력 --> <div class="col-lg-6 px-xl-10"> <form action="/product/{{id}}/update" method="post"> <input type="hidden" name="productId" value="{{product.id}}"> <div class="mb-3 mt-3"> 상 품 명 : <input id="name" name="name" type="text" class="form-control" value="{{product.name}}"> <div class="alert" id="nameCheck"></div> </div> <div class="mb-3 mt-3"> 상품가격 : <input id="price" name="price" type="text" class="form-control" value="{{product.price}}"> </div> <div class="mb-3 mt-3"> 상품수량 : <input id="qty" name="qty" type="text" class="form-control" value="{{product.qty}}"> </div> <div class="d-flex justify-content-center"> <button type="submit" class="btn btn-primary mt-3">상품수정완료</button> </div> </form> </div> <!-- 상품 정보 입력 -->
💡
hidden 으로 productId 받아와줌
 

[ ProductController ]

//상품명 실시간 중복체크 (업데이트용) @GetMapping("/product/name-check/update") public @ResponseBody ResponseEntity<?> nameSameCheckUpdate(String name, Integer id) { Product product = productService.findByNameUpdate(name, id); if (product == null) { return ResponseEntity.ok(new ApiUtil<>(true)); //상품 등록 가능 } else { return ResponseEntity.ok(new ApiUtil<>(false)); //상품 등록 불가 } }
 

[ ProductService ]

//상품명 실시간 중복체크(업데이트) public Product findByNameUpdate(String name, Integer id) { Product product = productRepo.findByNameUpdate(name, id); return product; }
 

[ ProductRepository ]

//상품명 실시간 중복체크 //TODO: 레파지토리에서 try-catch를 안하고 싶은데... 어떻게 해야하지? public Product findByNameUpdate(String name, Integer id) { try { String q = """ select * from product_tb where name = ? and id != ? """; Query query = em.createNativeQuery(q, Product.class); query.setParameter(1, name); query.setParameter(2, id); Product product = (Product) query.getSingleResult(); return product; } catch (NoResultException e) { return null; } }
💡
전달받은 상품명(name)이 현재 데이터베이스에 존재하는지를 체크하되, 전달받은 상품 ID(id)에 해당하는 상품은 이 중복 체크에서 제외
 

[ update-form ]

<script> // 실시간 상품명 중복체크 $("#name").keyup(function (){ //this = 지금 현재 클릭한 것, val = 값 가져옴 var name = $(this).val(); var productId = $("input[name='productId']").val(); // 상품 ID 가져오기 // alert(name); //서버로 가서 id 중복체크 -> url과 입력 데이터는 바뀌면 안됨 -> Ajax //url -> /product/name-check //서버에서 전달되는 데이터를 result로 받음 -> 가져온 데이터가 null이면 사용 가능, 있으면 중복 var encodedName = encodeURIComponent(name); //이게 없으면 띄어쓰기 인식 안됨 $.ajax({ method: "GET", url: "/product/name-check/update?name=" + encodedName + "&id=" + productId }).done((res)=>{ console.log(res); if (res.body === true) { //res의 body값이랑 비교해야함!! $("#nameCheck").removeClass("alert-danger"); $("#nameCheck").addClass("alert-success"); $("#nameCheck").text("사용 가능한 상품명 입니다."); } else { $("#nameCheck").removeClass("alert-success"); $("#nameCheck").addClass("alert-danger"); $("#nameCheck").text("중복된 상품명 입니다."); } }).fail((res)=>{ alert("통신 오류"); }); }); $(document).ready(function() { // 가격 표시 var price = $('input[name="price"]').val(); $('input[name="price"]').val(priceToString(parseInt(price))); // 수량 표시 var qty = $('input[name="qty"]').val(); $('input[name="qty"]').val(qtyToString(parseInt(qty))); }); function priceToString(price) { return price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } function qtyToString(qty) { return qty.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } $(document).ready(function() { // 가격 입력 필드에 대한 이벤트 리스너 추가 $('#price').on('input', function() { // 입력된 값에서 숫자만 추출 var number = $(this).val().replace(/[^0-9]/g, ''); // 천 단위 구분자 적용 var changeNum = number.replace(/\B(?=(\d{3})+(?!\d))/g, ','); // 변환된 값으로 입력 필드 업데이트 $(this).val(changeNum); }); $('#qty').on('input', function() { // 입력된 값에서 숫자만 추출 var number = $(this).val().replace(/[^0-9]/g, ''); // 천 단위 구분자 적용 var changeNum = number.replace(/\B(?=(\d{3})+(?!\d))/g, ','); // 변환된 값으로 입력 필드 업데이트 $(this).val(changeNum); }); // 폼 제출 전 실행될 이벤트 $('form').on('submit', function() { // 가격과 수량 입력 필드에서 천 단위 구분자 제거 var price = $('#price').val().replace(/,/g, ''); $('#price').val(price); // 수량 필드에 대해서도 같은 처리를 수행 var qty = $('input[name="qty"]').val().replace(/,/g, ''); $('input[name="qty"]').val(qty); }); }); </script>
 

[ 결과 화면 ]

notion image
💡
바나나를 바꿔보자
notion image
notion image
💡
상품 [ 바나나 ] 를 업데이트 하는 것이기 때문에 [ 바나나 ] 는 사용 가능한 상품명이어야 함
notion image
 
Share article

codingb