echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

JavaScriptで動的なバリデーション表示

オレは会社をやめたぞ!ジョジョーーッ!

という訳で、今まで色々書いてきた会社のことですが、とうとう辞めました。
今まで色々あったのですが、「こんな奴の下にずっといたら、絶対ダメになるな…」という決定的なことがあったので、案の定「辞めてもらってもいいんだよ」と言われた時に「はい、じゃあ辞めます。」って言いました。
向こうはまさか辞めるとは思ってなかったようですが、そんな事知ったことじゃないし、それにDirectXの件は要望通りのものは一通り完成させましたし(このブログでは、小出しにしてますけどね…)
C#VC++、両方分かる人が僕しかいない会社でしたが、あれはあの後どうなるんだろうな…


で、今週は訳あって、依頼された簡単な問い合わせシステムをPHPで作成してたのですが、今までWebシステムの入力検証って、定番通りサーバーで行ってエラー内容をヘッダとかに表示させてました。
ただ、最近は色々なWebサイトで見られる通り、クライアント側で行って動的にHTMLなどを作成して…というのが多いですよね。

例えば、
f:id:Makky12:20160826202128p:plain
エラーがない場合は、こんな感じなんですが、


f:id:Makky12:20160826202137p:plain
入力内容がエラーだと、HTMLなどを動的に作成して、こんな風にわかりやすく表示してくれるやつです。

もともと「どうやって作ってるんだろうな」と思っていましたが、いい機会だったので、自分で作ってみました。
(もっと良いやり方もあるのでしょうが、時間の関係もあり、とりあえず今回はこんな感じです。)

<!-- HTML側のコード(一部抜粋) -->
<tr>
    <th>
        お名前<span class="must">必須</span>
    </th>
    <td class="td" id="td_name">
        <input type="text" class="form-control" name="name" id="form_name"
        value="" maxlength="10" placeholder=" 例)山田 太郎" 
        onchange="validate('td_name', 'form_name');">
    </td>
</tr>|


// JavaScript側のコード
function validate(objTd, objId)
{
    var objCtrl = document.getElementById(objId);
    var objRegExp = null;
    var msg = "";

    switch(objId)
    {
        // 本当は他にもあるけど、今回は省略。
        case 'form_name':

            if("" == objCtrl.value) {
                msg = "お名前は必須です。";
            }else{
                if (objCtrl.value.length > 10) {
                    msg = "お名前は10文字以内で入力して下さい。";
                }else{

                    // 正規表現による文字チェック
                    objRegExp = new RegExp(/^[\sa-zA-Z0-9!#$%&=-~^@+.ぁ-んーァ-ヶー一-龠1-9A-Za-z!#$%&=-~^@+.、。?-]+$/);
                    if (!objRegExp.test(objCtrl.value)) {
                        msg = "お名前の値が不正です。";
                    }
                }
            }

            break;
    }

    displayErrorInfo(objTd, objId, msg);
}

function displayErrorInfo(objTd,objId, msg){

    var objParent = document.getElementById(objTd);
    var objCtrl = document.getElementById(objId);

    // objIdの文字を末尾に追加しているのは、他のコントロールで使用した際IDがかぶるのを防ぐため。
    var objChild = document.getElementById('form_childDiv' + objId);

    // 同じエラーメッセージが何個も表示されないように、既存のエラーメッセージは削除する。
    if(null != objChild)
    {
        objParent.removeChild(objChild);
    }

    if("" != msg) {
        // エラーが有る場合
        objCtrl.style.backgroundColor = "#FADBDA";

        var errorNode = document.createElement("div");
        errorNode.id = "form_childDiv" + objId;
        errorNode.style.color = "#FF0000";
        errorNode.innerText = msg;
        objParent.appendChild(errorNode);
    }else{
        // エラーがない場合
        objCtrl.style.backgroundColor = "#FFFFFF";
    }
}

最初は難しそうだな、と思っていたけど、appendChild()の仕組みを理解すれば、表示の変更自体はそこまで難しくなかった。
ていうか、むしろ正規表現が厄介だった…
RegExp()の引数をクオーテーションで囲む必要がない、ってことになかなか気づかなかった…(Zendの「Zend_Validate_Regex」だと、囲む必要があったはずだけど…)

まあ、この辺は要調査ですね。