このページの本文へ

jQueryでバリデーション付きメールフォームを作ろう (2/3)

2009年12月02日 13時00分更新

文●西畑一馬/to-R

  • この記事をはてなブックマークに追加
本文印刷

 スクリプト部分は次のようになります。これまでに比べると非常に長いソースコードですが、5行ほどの小さな処理のかたまりが集まったものですので、1つずつ見ていけば大丈夫です。

サンプル01(スクリプト部分)


$(function(){
    $("form").submit(function(){
    
        //エラーの初期化
        $("p.error").remove();
        $("dl dd").removeClass("error");
        
        $(":text,textarea").filter(".validate").each(function(){
            
            //必須項目のチェック
            $(this).filter(".required").each(function(){
                if($(this).val()==""){
                    $(this).parent().prepend("<p class='error'>必須項目です</p>")
                }
            })
            
            //数値のチェック
            $(this).filter(".number").each(function(){
                if(isNaN($(this).val())){
                    $(this).parent().prepend("<p class='error'>数値のみ入力可能です</p>")
                }
            })
            
            //メールアドレスのチェック
            $(this).filter(".mail").each(function(){
                if($(this).val() && !$(this).val().match(/.+@.+\..+/g)){
                    $(this).parent().prepend("<p class='error'>メールアドレスの形式が異なります</p>")
                }
            })
            
            //メールアドレス確認のチェック
            $(this).filter(".mail_check").each(function(){
                if($(this).val() && $(this).val()!=$("input[name="+$(this).attr("name").replace(/^(.+)_check$/, "$1")+"]").val()){
                    $(this).parent().prepend("<p class='error'>メールアドレスと内容が異なります</p>")
                }
            })
            
        })
        
        //ラジオボタンのチェック
        $(":radio").filter(".validate").each(function(){
            $(this).filter(".required").each(function(){
                if($("input[name="+$(this).attr("name")+"]:checked").size() == 0){
                    $(this).parent().prepend("<p class='error'>選択してください</p>")
                }
            })
        })
        
        //チェックボックスのチェック
        $(".checkboxRequired").each(function(){
            if($(":checkbox:checked",this).size()==0){
                $(this).prepend("<p class='error'>選択してください</p>")
            }
        })
        
        // その他項目のチェック
        $(".validate.add_text").each(function(){
            if($(this).attr("checked")==true && $("input[name="+$(this).attr("name").replace(/^(.+)$/, "$1_text")+"]").val()==""){
                $(this).parent().prepend("<p class='error'>その他の項目を入力してください。</p>")
            }
        })
        
        //エラーの際の処理
        if($("p.error").size() > 0){
                $('html,body').animate({ scrollTop: $("p.error:first").offset().top-40 }, 'slow');
                $("p.error").parent().addClass("error");
                return false;
        }
    })
})


 このスクリプトは、2行目から最後の2行目まで、すべてsubmitイベント内に記述しています。submitイベントはsubmitボタン(type属性が「submmit」のinput要素)がクリックされたときに発生するイベントです(関連記事)。


$("form").submit(function(){
    //フォームバリデーションの内容
})


 submitイベントの処理では、最初に、エラーの初期化処理を記述します。送信ボタンが初めて押されたときはいいのですが、すでにボタンが押されてバリデーション処理が実行済みの場合、バリデーションエラー時の処理が適用されている場合があります。すると、エラーメッセージが何度も表示されたり、修正済みの項目のエラーメッセージが消えないなどの問題がありますので、最初に初期化しておくわけです。removeClass()(関連記事)で「error」というclass属性を取り除き、remove()(関連記事)でエラーメッセージを表示するp要素を削除しています。


$("dl dd").removeClass("error");
$("p.error").remove();


 初期化が済んだら、テキスト入力フォーム(1行テキスト入力フォームと複数行入力フォーム)のバリデーションを実行します。:textはtype属性の値が「text」のinput要素を選択するセレクターです(関連記事)。:textとtextareaをグループセレクターで取得し(関連記事)、filter()を使ってさらに絞り込みます。

 filter()はすでにセレクターで絞った要素に対して、さらに別の条件での絞り込みができるjQueryの命令です。絞り込みの条件は、括弧内にjQueryのセレクターの記法で指定します。以下のようにeach(function(){...})と組み合わせると、class属性に「validate」が付いたテキスト入力フォームに対して、バリデーション処理を適用できます。


$(":text,textarea").filter(".validate").each(function(){
    //テキスト入力フォームのバリデーション
})


 テキスト入力フォームのバリデーション処理の内容は次のようになっています。


■必須項目のチェック

 class属性に「required」と付いている要素を入力必須項目としてfilterで絞り込み、if文(関連記事)を使ってテキストが入力されていない場合(フォームの内容が空の場合)のみエラーメッセージを表示します。入力フォームの入力内容はval()で取得できます(関連記事)。


$(this).filter(".required").each(function(){
    if($(this).val()==""){
        $(this).parent().prepend("<p class='error'>必須項目です</p>")
    }
})


 エラーメッセージはエラーが発生した入力フォームのすぐ上に表示します。フォームのHTMLは以下のようになっていますので、チェックしたinput要素の親要素(dd要素)に移動し、dd要素の内部の最初にエラーメッセージを挿入します。指定した要素から親要素へ移動するには、jQueryのparent()という命令を使います。


<dd><input type="text" name="name" size="100" class="validate required" /></dd>


 要素内部の最初にHTMLを挿入するのはprepend()(関連記事)です。prepend()でp要素を挿入すると、バリデーションエラー時には以下のようなHTMLに変わります。


<dd>
    <p class='error必須項目です</p>
    <input type="text" name="name" size="100" class="validate required" />
</dd>


エラーメッセージ

デフォルト時とバリデーションエラー時の比較。dd要素の最初にp要素でエラーメッセージが追加される

■数値のチェック

 class属性が「number」の要素には、入力された値が数値かどうか、チェックします。数値のチェックには、isNaN()というJavaScriptの命令を使います。isNaN()をif文の条件に設定すると、値が数値ではない場合に正しくなり、if(){...}内の命令を実行します。エラーメッセージの追加は、先ほどの必須項目の場合と同じ処理です。


$(this).filter(".number").each(function(){
    if(isNaN($(this).val())){
        $(this).parent().prepend("<p class='error'>数値のみ入力可能です</p>")
    }
})


■メールアドレスのチェック

 class属性が「mail」の要素には、入力されているテキストがメールアドレスかどうかをチェックします。メールアドレスのチェックは正規表現(関連記事)を使って、一般的なメールアドレスの書式に合致するか調べます。ただし、メールアドレスの書式は厳格にチェックしようとすると非常に複雑な正規表現になってしまいますし、メールアドレスの中には規格外のものも存在するため、簡単ではありません。そのため、クライアント側では簡易的なチェックでよいでしょう。

 指定したパターンとテキストが一致しているか調べるには、match()という命令を使います。match()内に「/.+@.+\..+/g」と記述すると、「@(アットマーク)を含み、その後の内容に.(ドット)が存在するか」を調べられます。$(this).val().match(...)の前に!(エクスクラメーションマーク)を付けると、指定した書式と入力されているテキストの内容が異なる場合に、if(){...}内の命令が実行されます。


$(this).filter(".mail").each(function(){
    if($(this).val() && !$(this).val().match(/.+@.+\..+/g)){
        $(this).parent().prepend("<p class='error'>メールアドレスの形式が異なります</p>")
    }
})


■メールアドレス確認のチェック

 class属性に「mail_check」と付いている要素に対しては、前に入力したメールアドレス欄と内容が一致しているか照合します。

 照合先のフォームは、name属性の値を使って指定します。「メールアドレス確認」の入力フォームのname属性の値を取得し、取得した値から「_check」を取り除いたname属性を持つ要素が照合先のフォーム部品です。name属性から_checkを取り除くのはreplace()(関連記事)で、name属性が付いている要素は属性セレクター(関連記事)で取得できます。


$(this).filter(".mail_check").each(function(){
    if($(this).val() && $(this).val()!=$("input[name="+$(this).attr("name").replace(/^(.+)_check$/, "$1")+"]").val()){
        $(this).parent().prepend("<p class='error'>メールアドレスと内容が異なります</p>")
    }
})


 今回のサンプルでは、「メールアドレスの確認」のname属性は「mail_check」ですので、「_check」を取り除いた「mail」というname属性を持つ入力フォームと照合しています。


<!--メールアドレスの入力フォーム-->
<input type="text" value="" size="100" name="mail" class="validate mail"/>
<!--メールアドレス確認用の入力フォーム-->
<input type="text" value="" size="100" name="mail_check" class="validate mail mail_check"/>


 以上で、テキスト入力フォームのバリデーション処理は完成です。次は、ラジオボタンとチェックボックスのバリデーション処理です。

この連載の記事

一覧へ

この記事の編集者は以下の記事をオススメしています