Java Script/문제일지

회원가입 약관동의 페이지(jQuery) (+마주한 오류)

이게아닌데 2022. 8. 26. 14:02

위 이미지와 같이 회원가입 시 약관 동의 페이지가 나온다.

이때 생각보다 많은 기능이 들어가 있다.

기능을 살펴보자.

 

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와 같은 웹 서버의 이해가 필요하다고 생각했다.