JavaScriptフレームワークのバリデーション機能を関数提供する実装


フレームワークによくあるバリデーション機能を関数で提供する

※こちらでフレームワークっぽく色々実装したバージョンを公開しました
https://qiita.com/ikuo0/items/dd0bda8a84cdd1ae43e2

JavaScriptフレームワークによくあるオートバリデーション機能を作ります。
フレームワーク全体の使い方を覚えるのは面倒だけどオートバリデーションは欲しいという人向けに一例として1行テキストの場合の実装例だけを書きます。
フレームワークを使わずに済むなら使いたくないというひねくれた人向けのお話です。JQueryを使っています。

実装

function addAutoSyncronizedToText(obj, id, opt) {
    var $elm = $(id);
    var minLength = "min" in opt ? opt["min"]: false;
    var maxLength = "max" in opt ? opt["max"]: false;
    obj[id] = "value" in opt ? opt["value"]: "";
    var $warn = $("<div>", {// 警告メッセージ用のDIV
        "css": {
            "display": "none",
            "position": "absolute",
            "border-style": "solid",
            "border-width": "2px",
            "border-radius": "5px",
            "border-color:": "#000000",
            "background-color": "#ffffff",
            "color": "#ff0000",
            "font-weight": 800,
        }
    });
    $("body").append($warn);
    $elm.on("change", function() {
        $warn.hide();
        var val = $elm.val();
        obj[id] = val;
        var warnText = false;
        if(minLength && val.length < minLength) {
            warnText = String(minLength) + "文字以上必要です";
        }
        if(maxLength && val.length > maxLength) {
            warnText = String(maxLength) + "文字以下です";
        }

        if(warnText !== false) {
            var pos = $elm.offset();
            var x = pos.left;
            var y = pos.top + $elm.outerHeight();
            $warn.text(warnText);
            $warn.css({"top": y, "left": x});
            $warn.show();
        }

        if("onChange" in obj) {
            obj["onChange"].apply(obj, [id, val]);
        }
    });
}

使い方

// 使い方
var obj = {
    "onChange": function(id, value) {
        console.log("id", id);
        console.log("value", value);
    }
};
addAutoSyncronizedToText(obj, "#name", {"min": 1, "max": 15});

変数 obj に "#name" 等のIDと完全に連動したキーで値が保存されます、全体を一括でバリデーションする事はできませんが1つ1つについては自動的にバリデーションして警告を出す事が可能です。
改造してエラーの有無を obj に残しても良いと思います。

実際の見え方

以上です。