출처: Oline Tutorials https://youtu.be/Hi8DVOaZ0Ug

 

회원가입 등 정보를 입력하고 저장할 때 유효성 검사는 필수적으로 진행한다.

유튜브를 보다가 유효성 검사를 시각적으로 깔끔하게 보여주는게 있어서 따라해봤다.

앞으로 UI를 구성할 때 유용하게 쓸 수 있을 것 같다.

 

소스코드

- index.html

<!DOCTYPE html>
<html lang="en">
  <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="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;600;700&display=swap"
      rel="stylesheet"
    />

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer" />

    <link rel="stylesheet" href="./css/style.min.css" />
  </head>
  <body>
    <div class="box">
      <div class="inputBox">
        <input type="password" id="pswrd" placeholder="Password" onkeyup="checkPassword(value)"/>
        <span id="toggleBtn"></span>
      </div>
      <div class="validation">
        <ul>
          <li id="lower">At least one lowercase character</li>
          <li id="upper">At least one uppercase character</li>
          <li id="number">At least one number</li>
          <li id="special">At least one special character</li>
          <li id="length">At least 8 cahracters</li>
        </ul>
      </div>
    </div>

    <script>
      const pswrd = document.getElementById('pswrd');
      const toggleBtn = document.getElementById('toggleBtn');

      const lowerCase = document.getElementById('lower');
      const upperCase = document.getElementById('upper');
      const digit = document.getElementById('number');
      const specialChar = document.getElementById('special');
      const minLength = document.getElementById('length');

      // 패스워드 토글 버튼
      toggleBtn.addEventListener('click', () => {
        if(pswrd.type === 'password') {
          pswrd.setAttribute('type', 'text');
          toggleBtn.classList.add('hide');
        } else {
          pswrd.setAttribute('type', 'password');
          toggleBtn.classList.remove('hide');
        }
      });

      /** 정규식을 통한 유효성 검사 */
      const checkPassword = data => {
        const lower = new RegExp('(?=.*[a-z])');
        const upper = new RegExp('(?=.*[A-Z])');
        const number = new RegExp('(?=.*[0-9])');
        const special = new RegExp('(?=.*[!@#\$%\^&\*])');
        const length = new RegExp('(?=.{8,})');

        // 소문자 유효성 검사
        lower.test(data) ? lowerCase.classList.add('valid') :  lowerCase.classList.remove('valid')
        // 대문자 유효성 검사
        upper.test(data) ? upperCase.classList.add('valid') :  upperCase.classList.remove('valid')
        // 숫자 유효성 검사
        number.test(data) ? digit.classList.add('valid') :  digit.classList.remove('valid')
        // 특수문자 유효성 검사
        special.test(data) ? specialChar.classList.add('valid') :  specialChar.classList.remove('valid')
        // 문자열 길이 유효성 검사
        length.test(data) ? minLength.classList.add('valid') :  minLength.classList.remove('valid')
      }
    </script>
  </body>
</html>

 

- style.scss

* {
  margin: 0;
  padding: 0;
  font-family: 'Poppins', sans-serif;
  box-sizing: border-box;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background-color: #8cccff;
}

.box {
  position: relative;
  width: 300px;

  .inputBox {
    position: relative;
    width: 100%;
    background-color: #fff;
    padding: 5px;
    border-radius: 8px;
    box-shadow: 0 15px 25px rgba(0,0,0,.15);

    input {
      position: relative;
      width: 100%;
      outline: none;
      border: none;
      padding: 10px 5px;
    }

    #toggleBtn {
      display: flex;
      justify-content: center;
      align-items: center;
      position: absolute;
      background-color: rgba(0,0,0,.05);
      top: 8px;
      right: 10px;
      width: 34px;
      height: 34px;
      border-radius: 50%;
      cursor: pointer;

      &::before {
        content: '\f070';
        font-family: fontAwesome;
      }
      
      &.hide::before { content: '\f06e'; }
    }
  }

  .validation {
    background-color: #376488;
    padding: 10px;
    margin-top: 30px;
    border-radius: 8px;
    box-shadow: 0 15px 25px rgba(0,0,0,.15);
    
    ul {
      position: relative;
      display: flex;
      flex-direction: column;
      gap: 8px;

      li {
        position: relative;
        list-style: none;
        color: rgba(255, 255, 255, .5);
        font-size: .85em;
        transition: .5s;

        &:before {
          content: '\f192';
          font-family: fontAwesome;
          display: inline-flex;
          width: 20px;
          height: 10px;
        }

        &.valid {
          color: #fff;

          &::before {
            content: '\f00c';
            color: #0f0;
          }
        }
      }
    }
  }
}

 

구현결과

로그인 시 패스워드가 보였다 가렸다하는 기능은 구현해 본적은 없지만, 대충 타입 바꿔 끼우면 되겠지 했는데 내 생각이 맞았다.

어려운 기능은 아니니 다음 프로젝트 할 때 구현해 보는걸로 하고, 유효성 검사는 회원가입 UI 구성할 때 사용하면 좋을거 같다.

+ Recent posts