회원가입 약관동의 페이지(jQuery) (+마주한 오류)
위 이미지와 같이 회원가입 시 약관 동의 페이지가 나온다.
이때 생각보다 많은 기능이 들어가 있다.
기능을 살펴보자.
1. "모두 동의" 체크박스를 누르면 개별 체크박스가 모두 선택되어야 한다.
2. 모두 동의 상태에서 하나의 개별 체크박스 해제 시 "모두 동의" 체크박스는 비활성화가 되어야 한다.
3. "개별"의 체크박스가 모두 선택되면 "모두 동의" 체크박스가 활성화된다.
4. 필수 동의 체크박스가 체크가 안되었다면 경고창 띄우고 체크 상태에서 버튼을 누르면 이동한다.
이렇게 체크박스끼리 서로 상호작용할 수 있도록 만들어야 한다.
이때 javascript와 javascript Librery인 jQuery를 사용해서 만들 수 있다.
html
우선 약관 영역은 3가지로 표현이 가능하다.
1. textarea 요소 사용
2. div 요소 사용
3. iframe 요소 사용(pre 요소를 사용한다.)
이 3가지 방법 중 3번째 방법인 iframe 요소를 사용했다.
<iframe> 요소는 다른 html 파일을 보여주는 창이다. 따라서 html 파일이 존재해야 한다.
html 전체 코드
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="style/style.css" />
</head>
<body>
<div id="wrap" class="checkbox_group">
<header id="header_total">
<input type="checkbox" name="" id="total_ckb" />
<label for="total_ckb">
이용약관 및 개인정보수집 및 이용, 쇼핑정보 수신(선택)에 모두 동의
합니다.
</label>
</header>
<!-- header#header -->
<main id="main">
<div id="TOS" class="Terms_set">
<h1>[필수] 이용약관 동의</h1>
<iframe
src="TermsOfService_txt.html"
height="180"
width="950"
style="margin-left: 4px"
></iframe>
<p>
<span>이용약관에 동의하십니까?</span>
<input type="checkbox" name="chkbox" id="TOS_ckb" />
<!-- 체크된 상태 checked 속성. 속성값이없음. 불리언타입 -->
<label for="TOS_ckb">동의함 (필수)</label>
</p>
</div>
<!--/////////////////div#TOS/////// TOS;Terms of service/////////// -->
<div id="Privacy" class="Terms_set">
<h1>[필수] 개인정보 수집 및 이용 동의</h1>
<iframe
src="Privacy_txt.html"
height="180"
width="950"
style="margin-left: 4px"
></iframe>
<p>
<span>개인정보 수집 및 이용에 동의하십니까?</span>
<input type="checkbox" name="chkbox" id="Privacy_ckb" />
<!-- 체크된 상태 checked 속성. 속성값이없음. 불리언타입 -->
<label for="Privacy_ckb">동의함 (필수)</label>
</p>
</div>
<!--/////////////////div#Privacy////////////////// -->
<div id="shopInf" class="Terms_set">
<h1>[선택] 쇼핑정보 수신 동의</h1>
<iframe
src="shoppingInformation_txt.html"
height="150"
width="950"
style="margin-left: 4px"
></iframe>
<p>
<span>쇼핑정보 수신에 동의하십니까?</span>
<input type="checkbox" name="chkbox" id="shopInf_ckb" />
<!-- 체크된 상태 checked 속성. 속성값이없음. 불리언타입 -->
<label for="shopInf_ckb">동의함 (선택)</label>
</p>
</div>
<!--/////////////////div#shopInf//////////////// -->
</main>
<!-- main#main -->
<footer id="footer">
<form action="https://www.google.com" method="get"></form>
<button type="submit" id="join">회원가입</button>
</footer>
<!-- footer#footer -->
</div>
<!-- div#wrap -->
<script src="script/jquery-3.6.0.min.js"></script>
<script src="script/script.js"></script>
</body>
</html>
이때 사용한 요소 중에 <label> </label> 요소가 작은 디테일이라고 생각하며 사용했다.
반드시 체크박스를 눌러야 하는 것이 아니라 글씨를 눌러도 체크박스의 토글이 작용하도록 라벨링을 해주는 것이다.
이때 전체를 라벨링해도 되지만 나는 for속성을 사용해보기 위해 따로 label요소를 사용했다.
<label for ="해당하는 id명"> </label>
css코드
@charset "UTF-8";
@import url(style_Reset.css);
div#wrap{
width: 960px;
height: 870px;
margin: 10px auto;
/* border: 1px solid #000; */
}
/*//////////////// header#header 시작////////////////// */
header#header_total{
/* border: 1px solid rgb(255, 0, 0); */
text-indent: 20px;
}
#header_total input#total_ckb{
width: 22px;
height: 22px;
position: relative;
top: 5px;
}
#header_total label{
font-size: 18px;
/* border: 1px solid rgb(0, 255, 128); */
}
/*//////////////// header#header 끝////////////////// */
/*//////////////// main#main 시작////////////////// */
#main .Terms_set{
margin: 40px 0;
}
#main>.Terms_set>h1{
margin: 13px 0;
font-size: 20px;
text-indent: 20px;
}
#main>.Terms_set>iframe{
border: 1px solid #aaa;
}
#main>.Terms_set p{
margin-top: 2px;
text-indent: 20px;
/* font-size: 16px; */
}
#main>.Terms_set input{
width: 20px;
height: 20px;
position: relative;
top: 4px;
}
/*//////////////// main#main 끝////////////////// */
/*//////////////// footer#footer 시작////////////////// */
footer#footer{
/* border: 1px solid rgb(255, 0, 0); */
text-align: center;
padding: 20px 0;
}
#footer>button{
padding: 5px 18px;
border: 1px solid #08f;
background-color: #08f;
border-radius: 3px;
color: #fff;
font-size: 21px;
cursor: pointer;
}
/*//////////////// footer#footer 끝////////////////// */
CSS가 안중 요한 것은 아니지만 이번에 언급할만한 기술이나 기능이 있지 않다.
JavaScript( + jQuery)
1. "모두 동의" 체크박스를 누르면 개별 체크박스가 모두 선택되어야 한다.
let inputTotal = document.getElementsByName("chkbox");
$("input#total_ckb").click(function(){
if ($("#total_ckb").is(":checked")) {
$(inputTotal).prop('checked',true);
}else{
$(inputTotal).prop('checked',false);
}
});
※ getElementsByName("name 속성 값") : Elements에서 s를 놓칠 수도 있다.
※ prop() : 요소의 속성을 초기화하거나 반환시킨다.
2. 모두 동의 상태에서 하나의 개별 체크박스 해제 시 "모두 동의" 체크박스는 비활성화가 되어야 한다.
$(inputTotal).click( function(){
let checked = $(this).is(":checked");
if (!checked) {
$("#total_ckb").prop('checked', false);
}
});
3. "개별"의 체크박스가 모두 선택되면 "모두 동의" 체크박스가 활성화된다.
$(inputTotal).click(function(){
$(this).each(function(){
let TOSckb = $("#TOS_ckb").is(":checked");
let Privacyckb = $("#Privacy_ckb").is(":checked");
let shopInfckb = $("#shopInf_ckb").is(":checked");
if (TOSckb && Privacyckb && shopInfckb) {
// alert("Privacyckb : "+Privacyckb);
$("#total_ckb").prop('checked', true);
}
});
});
※. each 메서드
each() 메서드는 일치하는 각 요소에 대해 실행할 함수를 지정합니다.
배열을 만들어버린다. 레퍼런스를 찾아보면 나오는 예시는 이렇다.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("button").click(function(){
$("li").each(function(){
alert($(this).text())
});
});
});
</script>
</head>
<body>
<button>Alert the value of each list item</button>
<ul>
<li>Coffee</li>
<li>Milk</li>
<li>Soda</li>
</ul>
</body>
</html>
이렇게 나오면 각 <li>마다 경고창이 뜬다.
4. 필수 동의 체크박스가 체크가 안되었다면 경고창 띄우고 체크 상태에서 버튼을 누르면 이동한다.
<footer id="footer">
<form action="https://www.google.com" method="get"></form>
<button type="submit" id="join">회원가입</button>
</footer>
$("#join").click(function(){
let TOSckb = $("#TOS_ckb").is(":checked");
let Privacyckb = $("#Privacy_ckb").is(":checked");
if ( TOSckb && Privacyckb ) {
$(this).prependTo("form");
} else {
alert("필수 약관 동의필요");
}
});
위와 같이 변수를 만들어서 필수 약관 체크박스가 동의가 되어있다면 form 요소의 action 속성 값으로 지정된 주소로 넘어가게 만든다.
※ prependTo( ) 메서드
선택한 요소의 시작 부분에 HTML 요소를 삽입한다.
즉 위와 같은 경우에 prependTo() 메서드가 실행된다면 아래와 같은 코드가 되는 것이다.
<footer id="footer">
<form action="https://www.google.com" method="get">
<button type="submit" id="join">회원가입</button>
</form>
</footer>
오류
오류가 발생했다. 페이지로 넘어가면서 생긴 문제인 것 같았다.
405. That’s an error.
The request method POST is inappropriate for the URL
번역기를 돌려보니
요청 방법 POST가 URL에 적합하지 않습니다.
찾아보니 URL문제인 것 같아 코드를 확인했다.
<footer id="footer">
<form action="https://www.google.co.kr" method="get"></form>
<button type="submit" id="join">회원가입</button>
</footer>
페이지에서 적용한 주소를 확인해보니 당연히 넣은 값은 같았다.
그래서 그냥 https://www.naver.com을 을 넣으니 정상적으로 이동했다.
혹시? 싶어서 google.com을 넣으니 google페이지로 정상 이동을 했다.
<footer id="footer">
<form action="https://www.google.com" method="get"></form>
<button type="submit" id="join">회원가입</button>
</footer>
http와 같은 웹 서버의 이해가 필요하다고 생각했다.