자바스크립트 Form Validator 만들기

버건디·2022년 9월 21일
0
post-thumbnail

📌 완성 됐을 때의 모습


🔍 기능 설계 해보기


🔍 HTML 구성해보기

Web Developer Tool 을 이용해서 CSS 를 지워보면 이런 HTML 구조가 나오는데, 이런 구조에 맞춰서 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>Form Validator</title>
</head>

<body>
    <div id="container">
        <form id="form" class="form">
            <h2>Register With Us</h2>
            <div class="form-control">
                <label for="Username">Username</label>
                <input id="userName" type="text" placeholder="Enter username">
                <small>Error Message</small>
            </div>
            <div class="form-control">
                <label for="Email">Email</label>
                <input id="email" type="email" placeholder="Enter email">
                <small>Error Message</small>
            </div>
            <div class="form-control">
                <label for="password">Password</label>
                <input id="password" type="password" placeholder="Enter password">
                <small>Error Message</small>
            </div>
            <div class="form-control">
                <label for="Confirmpassword">Confrim Password</label>
                <input id="confirmPassword" type="password" placeholder="Enter password again">
                <small>Error Message</small>
            </div>

            <button>Submit</button>
        </form>

    </div>
</body>

❓ HTML 에서 label 속성이란 ❓

HTML 에서 label 은 form 요소에서의 이름표라고 생각하면 된다.

form 안에서 input 칸들이 여러개 놓여져 있을때, 이 input 칸들을 각각 필요한 네이밍으로 나누어줌으로써

input 과의 연계성을 조금 더 유연하게 만든다.

예를 들어서 label 없이 input 창만 있다면

정확히 이 input 칸을 클릭해서 값을 입력해야하지만 label 을 사용해서 나누어 놨다면

저 Username 이 쓰여져있는 칸만 클릭해도 인풋칸이 클릭 되는걸 확인할 수 있다.

❗️ input 창의 id와 label for = ' ' 안에 들어가는 값이 같아야한다 ❗️


❓ HTML 에서 small 속성이란 ❓

small 태그는 크기가 작은 텍스트를 나타낼때 쓰는 태그이다.

<p>일반 글자 크기</p>
<small>small 태그를 사용한 글자 크기</small>


🔍 CSS 구성해보기

:root{ /* 가상 선택자*/
    --success-color : #2ecc71;
    --error-color : #e74c3c;
}

*{
    box-sizing: border-box; /* box의 사이즈를 테두리 기준으로 정한다 */
}


body{
    font-family: 'Open Sans', sans-serif;
    background-color: #f9fafb;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
}

.container{
    background-color: #fff;
    border-radius: 5px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
    width: 400px
}


h2{
    font-size: 24px;
    text-align: center;
    margin: 0 0 20px;
}

.form{
    padding: 30px 40px;
}

.form-control{
    margin-bottom: 10px;
    padding-bottom: 20px;
    position: relative;
}

.form-control label{
    color: #777;
    display: block;
    margin-bottom: 5px;
}

.form-control input{
    border: 2px solid #f0f0f0;
    border-radius: 4px;
    display: block; /* 해당 라인 다  차지 */
    width: 100%;
    padding: 10px;
    font-size: 14px;
}

.form-control input:focus{ /* 인풋창에 값 입력하려 할때 */
    outline: 0;
    border-color: #777;
}


.form-control.success input{
    border-color: var(--success-color);
}

.form-control.error input{
    border-color: var(--error-color);
}

.form-control small{
    color : var(--error-color);
    position: relative;
    bottom: 0;
    left: 0;
    visibility: hidden;
}

.form-control.error small{
    visibility: visible;
}

.form button{
    cursor: pointer; /* 마우스 커서 버튼에 가져다 댔을때 */
    background-color: #3498db;
    border: 2px solid #3498db;
    border-radius: 4px;
    color: #fff;
    display: block;
    font-size: 16px;
    padding: 10px;
    margin-top: 20px;
    width: 100%;
}

❓ :root 이란 ❓

CSS 내에서 변수를 설정해주는 방법인데, Validator 내에서 값을 잘못 입력했을때는 빨간색, 잘 입력했다면 초록색 테두리를 띄어줘야 하므로 그 색깔을 담은 변수를 설정해줌으로써 중복을 줄일 수 있다.


🔍 자바스크립트 기능 구현하기

document.addEventListener('DOMContentLoaded', () => {
    const form = document.querySelector('#form');
    const userName = document.querySelector('#userName');
    const email = document.querySelector('#email');
    const password = document.querySelector('#password');
    const confirmPassword = document.querySelector('#confirmPassword');

    // 확인 함수

    function checkRequired(inputArr){
        inputArr.forEach((input) => {
            if(input.value.trim() === ''){
                showError(input, toUpperFirstStr(input) + ' is required');
            } else{
                showSuccess(input);
            }
        })
    }

    // 에러 띄울 함수

    function showError(input, message){
        const formControl = input.parentElement;
        formControl.className ='form-control error';
        const small = formControl.querySelector('small');
        small.innerText = message;
    }

    //성공 했을때 만들어줄 함수

    function showSuccess (input){
        const formControl = input.parentElement;
        formControl.className = 'form-control success';
    }

    // 이메일 확인 함수

    function checkEmail(input){
        const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        if(re.test(input.value.trim())){
            showSuccess(input);
        } else{
            showError(input, 'Email is not valid');
        }
    }

    // 패스워드 일치하는지 확인하는 함수

    function checkPasswordsMatch(input1, input2){
        if(input1.value !== input2.value){
            showError(input2, 'Passwords do not match');
        }
    }

    // 첫 글자 대문자 만드는 함수

    function toUpperFirstStr(input){
       return input.id.charAt(0).toUpperCase() + input.id.slice(1); // 리턴중요
    }

    //길이 확인 함수


    function checkLength(input, min, max){
        if(input.value.length < min){
            showError(input, toUpperFirstStr(input) + ' must be at least ' + min + ' characters')
        } else if(input.value.length > max){
            showError(input, toUpperFirstStr(input)+ ' must be less than '+ max + ' characters')
        } else{
            showSuccess(input);
        }
    }
  
  // 폼에서 submit 이벤트가 발생했을때 
    form.addEventListener('submit', (e) =>{
        e.preventDefault();
        
        checkRequired([userName, email, password, confirmPassword]);
        checkEmail(email);
        checkLength(userName, 3, 15);
        checkLength(password, 6, 25);
        checkPasswordsMatch(password, confirmPassword);   
    })
})
profile
https://brgndy.me/ 로 옮기는 중입니다 :)

0개의 댓글