1. ApiUtil 클래스 설정해주기 (util임)
package shop.mtcoding.blog.util; import lombok.Data; @Data public class ApiUtil<T> { private Integer status; private String msg; private T body; //바디가 무슨 타입으로 들어올지 모르기 때문에 제네릭 사용 public ApiUtil(T body) { //제네릭 타입 this.status = 200; this.msg = "성공"; this.body = body; } public ApiUtil(Integer status, String msg) { this.status = status; this.msg = msg; this.body = null; } }
2. UserController
//아이디 중복체크 용. 이메일로 회원가입해서 email을 해줌 @GetMapping("/api/user/username-same-check") public @ResponseBody ApiUtil<?> usernameSameCheck(String email) { User user = userRepository.findByEmail(email); if (user == null) { return new ApiUtil<>(true); } else { return new ApiUtil<>(false); } }
api라서 주소창에 api를 넣어줌
3. joinForm.mustache
<form action="/user/join/1" method="post" enctype="application/x-www-form-urlencoded" onsubmit="return valid()"> <div class="d-flex form-group mt-2 mb-2"> <input type="email" name="email" class="form-control" placeholder="Enter email" id="email" value ="ssar@nate.com"> <button type="button" onclick="emailSameCheck()" class="badge bg-secondary ms-2" >중복확인</button> </div>
버튼을 클릭하면 이벤트가 발생해야 하니까,
onclick을 넣어줘서 emailSameCheck 자바 스크립트가 실행되게 설정한다.
4. joinForm.mustache에 Script 작성
<script> let isSameCheck = false; function valid() { if (isSameCheck == false) { alert("아이디 중복 체크를 해야합니다"); } return isSameCheck; } function emailSameCheck() { let email = $("#email").val(); $.ajax({ url: "/api/user/username-same-check?email=" + email, type: "get" }).done((res) => { console.log(res); if (res.body == true) { isSameCheck = true; alert("가입 가능한 아이디입니다"); } else { isSameCheck = false; alert("중복된 아이디가 존재합니다"); } }).fail((res) => { alert(res.responseJSON.msg); }); } </script>
여기서 "email"은 HTML 문서에서 id나 class를 참조해야 한다.
id를 참조하려면 "#email"을 사용하고, class를 참조하려면 ".email"을 사용해야 한다.
또한 ‘아이디 중복 체크를 해야합니다’ 라는 alert창을 띄우려면 이 msg를 가지고 있는 valid라는 function을 onsubmit="return valid()" 라고 form태그에 설정해준다.
클릭하면 valid함수를 return 해 줄 것!
화면 확인
+) 글자를 클릭해도 체크박스에 체크되게 할 수 있게
label 태그의 for 속성을 체크박스의 id와 일치시켜주면 된다. 즉, 체크박스의 id값과 label의 for값이 같아야 한다!
<div class="form-check"> <input class="form-check-input" type="checkbox" id="flexCheckChecked2" required> <label class="form-check-label" for="flexCheckChecked2"> (필수) 개인정보 수집 및 이용 동의 </label> </div>
에러 → 아이디 중복 체크를 하고 통과한 후, 바로 다른 아이디를 입력하면 중복체크를 하지 않아도 회원가입이 되어버림.
<script> let isSameCheck = false; // 아이디 필드가 변경되면 중복 체크 상태를 초기화 //이 코드가 있어야함! $("#email").on("change", function () { isSameCheck = false; }); function valid() { if (isSameCheck == false) { alert("아이디 중복 체크를 해야합니다"); return false; } return true; } function emailSameCheck() { let email = $("#email").val(); $.ajax({ url: "/api/user/username-same-check?email=" + email, type: "get" }).done((res) => { console.log(res); if (res.body == true) { isSameCheck = true; alert("가입 가능한 아이디입니다"); } else { isSameCheck = false; alert("중복된 아이디가 존재합니다"); } }).fail((res) => { alert(res.responseJSON.msg); }); } </script>
아이디 필드가 변경되었을 때 중복 체크 상태를 초기화하는 코드를 추가
이렇게 수정하면 아이디를 입력하고 중복 체크를 하면 isSameCheck는 true가 됩니다. 그런데 아이디를 다시 변경하면 'change' 이벤트가 발생하고 isSameCheck는 다시 false가 됩니다. 따라서 이를 변경한 후 중복 체크를 하지 않은 상태에서 회원 가입을 시도하면 "아이디 중복 체크를 해야합니다"라는 알림이 나타납니다.
change = 이벤트
$("#email").on("change", function () { isSameCheck = false; }); change는 JavaScript와 jQuery에서 사용되는 이벤트 타입 중 하나. 이 이벤트는 특정 입력 필드의 값이 사용자에 의해 변경되었을 때 발생한다. 위의 코드에서 $("#email").on("change", function () { ... });는 "id가 email인 요소의 값이 변경되면 이 함수를 실행해라"라는 뜻. 여기서 함수 내부의 isSameCheck = false; 코드가 실행되면서, 아이디 필드(#email)가 변경될 때마다 중복 체크 상태를 초기화하게 된다. 따라서, 이 코드는 사용자가 아이디를 입력하고 '중복확인'버튼을 누른 후 다시 아이디를 변경하면 중복 체크 상태를 다시 확인하도록 강제하는 역할을 한다!
ajj 흐름
사용자가 '중복확인' 버튼을 누르면 emailSameCheck() 함수가 호출되고, 이 함수 내부의 $.ajax() 메서드가 서버에 비동기 요청을 보낸다. 이 요청은 서버에게 "이 아이디가 이미 사용중인지 확인해달라"는 메시지를 보내는 것. 서버에서 응답이 오면, done() 메서드가 실행된다. 여기서 res.body == true 라는 조건문은 서버로부터 받은 응답의 body가 true인지 확인하는 것. 이는 보통 서버에서 해당 아이디가 사용 가능한지를 나타내는 불린 값으로 사용된다. 따라서, 만약 서버에서 "이 아이디를 사용할 수 있습니다"라는 응답이 오면 (res.body == true), isSameCheck는 true가 되고 "가입 가능한 아이디입니다"라는 알림이 뜨게 된다! 반면, 서버에서 "이 아이디는 이미 사용중입니다"라는 응답이 오면 (res.body == false), isSameCheck는 false가 되고 "중복된 아이디가 존재합니다"라는 알림이 뜨게 된다! 결과적으로, done() 메서드는 서버의 응답에 따라 isSameCheck의 값을 업데이트하고 사용자에게 해당 아이디의 사용 가능 여부를 알려준다.
동기
서버에 요청을 보낸 후 응답을 받을 때까지 기다리는 것을 동기(synchronous) 방식이라 한다. 동기 방식은 서버의 응답을 기다리는 동안 다른 작업을 진행할 수 없으므로, 응답 시간이 길어질 경우 사용자가 웹사이트에서 다른 작업을 하지 못하는 문제
비동기
웹 브라우저가 서버에 데이터를 요청하고 받아오는 과정에서, 요청을 보내고 응답을 기다리는 동안 다른 작업도 동시에 진행할 수 있는 방식이다. 이 방식에서는 서버의 응답이 오면 그 때 해당 응답을 처리하는 방식으로 작동. 이는 웹사이트가 서버의 응답을 기다리는 동안에도 사용자가 다른 작업을 계속 할 수 있다! JavaScript에서는 $.ajax(), fetch(), axios() 등의 메서드를 사용하여 비동기 요청을 보낼 수 있다.
서비스 이용약관 관련 전체 동의 누르면 모두 체크 되게!
document.getElementById('flexCheckDefault').addEventListener('change', function() { var isChecked = this.checked; ['flexCheckChecked1', 'flexCheckChecked2', 'flexCheckChecked3', 'flexCheckChecked4'].forEach(function(id) { document.getElementById(id).checked = isChecked; }); });
'flexCheckDefault' 체크박스의 상태가 변경될 때마다, 이벤트 리스너가 실행되어 'flexCheckDefault' 체크박스의 현재 체크 상태를 'isChecked' 변수에 저장한다. 그런 다음, 'flexCheckChecked1', 'flexCheckChecked2', 'flexCheckChecked3', 'flexCheckChecked4'라는 ID를 가진 다른 네 개의 체크박스를 순회하면서, 각 체크박스의 체크 상태를 'isChecked' 변수에 저장된 값으로 설정한다. 즉, 'flexCheckDefault' 체크박스가 체크되어 있다면, 나머지 네 개의 체크박스도 체크되고, 'flexCheckDefault' 체크박스가 체크 해제되어 있다면, 나머지 네 개의 체크박스도 체크 해제된다 이 스크립트는 사용자가 'flexCheckDefault' 체크박스를 통해 다른 네 개의 체크박스를 한 번에 체크하거나 체크 해제할 수 있도록 하는 기능을 제공한다.
여기서 this는 이벤트 리스너가 부착된 'flexCheckDefault' 체크박스를 가리킨다.
따라서 this.checked는 'flexCheckDefault' 체크박스의 현재 체크 상태를 나타낸다.
Share article