javascript form 유효성검사 연습

남예지·2023년 8월 13일
0

TIL

목록 보기
41/47

form 유효성 검사 javascript로 해보자..

우선 내가 생각한 순서는 이렇다.

  1. 버튼 클릭 시 클릭 이벤트가 발생하면 필수 입력해야하는 창이 비어있는지 확인해본다.
const comp_submitBtn = document.getElementById("comp_submit");
const comp_required = document.querySelectorAll(".comp_required");


comp_submitBtn.addEventListener("click", () => {
  console.log(
    comp_required[0].value,
    comp_required.map((el, index) => comp_required[index].value)
  );
});

처음엔 위 코드처럼 map을 이용해서 필수 입력해야하는 이들의 value를 가져오고 비었으면 빠꾸시키려했는데 자꾸 map을 쓸 때마다 오류가 났다.
그래서 그냥 comp_required만 console에 출력해보니 다음과 같이 NodeList라고 한다.

제로초님 강의에서 들었던게 기억난다. NodeList나 arguments는 배열처럼 보이는 유사배열이고, 사실 객체라고, 객체라서 배열에 쓰이는 메소드가 안먹힐 때가 있다고 했다.

그럼 객체에서 사용되는 방법을 써먹어 보자.
이 블로그를 참고해서 보면

NodeList 객체에서 제공하는 프로퍼티와 메서드

  • length : 결과 값의 전체 갯수 정보가 담겨져 있음.
  • item() : 결과 값을 항목별로 접근할 때 사용함.
  • childNodes : 모든 자식 노드의 정보가 담겨져 있음.
  • parentNode : 부모 노드의 정보가 담겨져 있음
  • previousSibling.previousSibling : 현 위치에서 이전 형제 노드
  • nextSibling.nextSibling : 현 위치에서 이후 형제 노드

이렇게 사용할 수 있다고 한다. 아래 코드처럼 적용해보니 잘 나왔다.

comp_submitBtn.addEventListener("click", () => {
  for (let i = 0; i < comp_required.length; i++) {
    // item() : 찾은 노드에서 n번째 노드에 접근하는 메서드.
    let div = comp_required.item(i);
    console.log(div.value);
  }
});

이제 순서도를 조금 바꿔서 버튼을 비활성화 후 모든 조건이 충족되면 활성화를 시켜야겠다.

input 태그 안에 disabled="true"를 넣어주고, css로 input:disabled{background: #ddd}를 해주었다.

그리고 클릭 이벤트가 아닌 change이벤트에 넣어주기로 하자.
다만 이때 input이 여러개라서 인풋 하나하나를 변수로 잡고 change이벤트를 주겠다.

아... 이러면 어떻게 해야하는지 모르겠어서 다시 선회해야겠다.
button 클릭 시 검증하는 걸로 다시 우회하자.
순서도를 다시 수정해보았다.

comp_submitBtn.addEventListener("click", () => {
  for (let i = 0; i < comp_required.length; i++) {
    // item() : 찾은 노드에서 n번째 노드에 접근하는 메서드.
    let valid = comp_required.item(i);
    if (!valid.value) {
      valid.focus();
      comp_required.item(i).style.backgroundColor = "rgba(255, 156, 156, 0.1)";
      return;
    }
  }
  if (!comp_email.value.includes("@")) {
    comp_email.style.backgroundColor = "rgba(255, 156, 156, 0.1)";
    comp_email.focus();

    return;
  }

  if (cb1.checked) {
    console.log("확인, 진짜 문의 하시겠습니까?");
    confirmation(true);
  } else {
    comp_emptyMessage.textContent = "개인정보처리방침에 동의해주세요.";
    return;
  }
});

이메일은 "@"도 걸러줘야해서 for문 안에 할까 밖에 할까 고민하다가 나중에 리팩토링 할 때 생각하려고 우선 밖에 놨고, 아래 버튼 클릭 시 체크박스 체크 여부도 걸리게끔 해서 체크가 안되어있으면 체크박스 아래에 문구가 뜨도록 설정했다.
화면은 아래와 같다.

그리고 개인정보 체크까지 하고 모두 통과 시 모달이 떠서 확인한다. 2번이나!


코드의 일부는 아래와 같다.

  <head>
	<script>
      function confirmation(isOpen) {
        $("#modalConfirm").css("display", isOpen ? "block" : "none");
      }

      // 제출 성공 안내 모달
      function successMessage(isOpen) {
        $("#modalSuccess").css("display", isOpen ? "block" : "none");
      }
    </script>
    <title>document</title>
  </head>
  <body>
    <div id="contact_wrap">
      <div id="header_"></div>

      <div class="modal-overlay" id="modalOverlay">
        <div class="modal-content">
          <h2>개인정보 처리방침 동의</h2>
          <button id="closeModalButton" onclick="viewInfo(false);"></button>
          <p>
            1. 개인정보의 수집 및 이용 목적 문의 및 요청사항에 대한 서비스를
            지원하기 위해 개인정보를 수집하고 있으며, 수집된 개인정보는 정해진
            목적 이외의 용도로는 이용되지 않으며 수집 목적이 변경될 경우 사전에
            알리고 동의를 받을 예정입니다. <br />2. 개인정보의 보유 및 이용기간
            원칙적으로 개인정보의 수집목적 또는 제공받은 목적이 달성된 때에는
            귀하의 개인정보를 지체 없이 파기합니다. 다만 발송내역의 자료를
            확인하기 위해 1년간 보유합니다. ...
          </p>
        </div>
      </div>

      <div id="modalSuccess">
        <div class="modalSuccess_content">
          <h3>문의가 정상적으로 처리되었습니다.</h3>
          <a onclick="successMessage(false);">확인</a>
        </div>
      </div>

      <div id="modalConfirm">
        <div class="modalConfirm_content">
          <h3>문의를 제출하시겠습니까?</h3>
          <div>
            <a onClick="confirmation(false);">아니오</a>
            <a onclick="confirmation(false); successMessage(true);">확인</a>
          </div>
        </div>
      </div>
      
      ...

스크립트를 직접 짜는 건 역시 공부가 많이 되는 것 같다. 재밌었다.
리액트만 한동안 하느라 뇌와 손이 굳었는데 오랜만에 순서도도 짜면서 스크립트 짜는 재미를 좀 봤다.
주말을 들인 보람이 있다.
좀 더 멋있고, 미니멀해서 가독성이 좋은 코드를 짜고 싶다. 컴포넌트화를 더 해서 가져다 쓰고싶다.
나는 아직 멀었다.ㅠ.ㅠ

profile
총총

1개의 댓글

comment-user-thumbnail
2023년 8월 13일

유익한 자료 감사합니다.

답글 달기