入力フォームのバリデーション

JavaScript

index.html

<!DOCTYPE html>
<html lang="ja">
<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">
    <link rel="stylesheet" href="style.css">
    <script type="text/javascript" src="main.js"></script>
    <title>フォームのバリデーション</title>
    <!-- バリデーション(Validation)とはユーザからの入力が適切な値かどうかチェックすること -->
</head>
<body>
    <div class="form-group">
        <label for="name" class="form-label">名前</label>
        <input type="text" class="form-input" id="name" name="name">
        <div class="form-error"></div>
    </div>
    <div class="form-group">
        <label for="postalcode" class="form-label">郵便番号</label>
        <input type="text" class="form-input" id="postalcode" name="postalcode">
        <div class="form-error"></div>
    </div>
</body>
</html>

style.css

/* style.css */
@charset "utf-8";

.form-group{
    margin-bottom: 20px;
}
.form-label{
    display: block;
    color: #666;
}
.form-input{
    border: 0;
    border-bottom: 1px solid #ccc;
}
.form-error{
    visibility: hidden;
}
.form-group.invalid .form-label{
    color: #c00;
}
.form-group.invalid .form-input{
    border-color: #c00;
    border-width: 2px;
}
.form-group.invalid .form-error{
    visibility: visible;
    margin: 4px 0 10px;
    color: #c00;
    font-size: 85%;
}

main.js

// main.js

// フォーム入力チェック項目
let validators = {};

/**
 * 空かどうかチェックする
 * @returns {bool, string} valid 真偽値, message エラーメッセージ
 */
validators.Required = function(){
    return function(input){
        if(input.value.length > 0){
            return { valid: true };
        }
        return { valid: false, message: "入力してください"};
    };
};

/**
 * 入力可能文字数をチェックをする
 * @param {int} len 最大入力文字数 
 * @returns {bool, string} valid 真偽値, message エラーメッセージ
 */
validators.MaxLength = function(len){
    return function(input){
        if(input.value.length <= len){
            return { valid: true };
        }
        return { valid: false, message: len + "文字以内で入力してください"};
    };
};

/**
 * 郵便番号が半角7桁かチェックする
 * @returns {bool, string} valid 真偽値, message エラーメッセージ
 */
validators.Postalcode = function(){
    return function(input){
        if(input.value.length < 1 || input.value.match(/^\d{7}$/)){
            return { valid: true };
        }
        return { valid: false, message: "半角数字7桁で入力してください"};
    };
};

// フォーム項目ごとのチェック関数設定
let validationMap = {
    "name": [validators.Required(), validators.MaxLength(10)],
    "postalcode": [validators.Postalcode()]
};

// コンテンツ読み込み後の処理
document.addEventListener("DOMContentLoaded", ()=>{
    console.log("DOM loaded.");
    for(let inputName in validationMap){
        console.log(inputName);
        let inputs = document.querySelectorAll('.form-group [name ="' + inputName + '"]');
        if(inputs.length < 1){
            continue;
        }
        [].forEach.call(inputs, function(input){
            let formGroup = input.parentElement;
            let formError;
            let validations = validationMap[inputName];
            while(!formGroup.classList.contains("form-group")){
                formGroup = formGroup.parentElement;
            }
            formError = formGroup.querySelector(".form-error");
            function validateInput(){
                for(let i=0; i<validations.length; i++){
                    result = validations[i](input);
                    if(result.valid){
                        formGroup.classList.remove("invalid");
                    }
                    else{
                        formGroup.classList.add("invalid");
                        formError.textContent = result.message;
                        break;
                    }
                }
            }
            input.addEventListener("change", validateInput);
            input.addEventListener("input", validateInput);
        });
    }
});

コメント