formをValidateしてAjaxで通信

# やったこと

jQueryを用いて、下記の流れを作りました。

* BootStrapモーダル・ダイアログ（form入力画面）を開く
* ユーザによるform入力
* validate処理
* validateがOKの場合、AjaxでPOSTリクエスト送信
* レスポンスの結果をアラートで表示

# 内容詳細

## BootStrap モーダル・ダイアログ

![20160924185112.png](https://qiita-image-store.s3.amazonaws.com/0/109149/aaddf09f-adfc-8836-9e4e-43cc2ce1b6a1.png)

上記の画像のようなダイアログを作成します。

### ソース

長いのでform部分は省略してます。

```html
<div class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="my![20160924191256.png](https://qiita-image-store.s3.amazonaws.com/0/109149/ab030a9c-96b3-473a-c56a-7b5d0fe1ad67.png)
LargeModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <!-- モーダルのヘッダ -->
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">
                    <span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title" id="modal-label">ダイアログ</h4>
            </div>
            <!-- モーダルのボディ -->
            <div class="modal-body">

            <form id="addHotel">
              :
            </form>

            </div>
            <!-- モーダルのフッタ -->
            <div class="modal-footer">
                <div id="response_parameter" ></div>
                <button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button>
                <button type="button" id="addBtn" class="btn btn-primary">保存</button>
            </div>
        </div>
    </div>
</div>
:
<!-- モーダル開くボタン -->
<button class="btn btn-warning" data-toggle="modal" data-target=".bd-example-modal-lg">Add Hotel</button>
```

## Vaidate と Ajax

![20160924191256.png](https://qiita-image-store.s3.amazonaws.com/0/109149/5c0b5291-89ba-fe3a-5cee-b5d350aec225.png)


上記画像のような、Validate処理を**jQuery Validation Plugin**を使って実装しました。

### ソース

```javascript
//カスタムvalidateの作成
//ここでは英大文字のみを正規表現で判定
jQuery.validator.addMethod("uppercase", function(value, element) {
	return this.optional(element) || /^[A-Z]+$/.test(value);
}, "Please input uppercase");

//validateのoption作成
var hotelValid = {
    //入力欄別にルールを作成
    rules:{
        name:{
            required:true
        },
        address:{
            required:true
        },
        countryCode:{
            required:true,
            minlength:2,
            uppercase:true
        },
        cityCode:{
            required:true,
            minlength:3,
            uppercase:true
        },
        grade:{
            required:true
        },
        facility:{
            required:true
        },
        imagePath:{
            required:true,
            url:true
        },
    },
    //messageを自分好みに設定
    messages:{
        countryCode:{
            minlength:"Country code must be 2 characters."
        },
        cityCode:{
            minlength:"City code must be 3 characters."
        }
    }
}

$(function(){
    //ボタンクリックで発火
    $("#addBtn").click(function(){
        //validate実行（作成したvalidateのoptionを指定）
        $("#addHotel").validate(hotelValid);
        //失敗で戻る
        if (!$("#addHotel").valid()) {
            return false;
        };
        //Ajaxでform入力内容送信
        $.ajax( {
            type: "POST",
            url: "/hotel/add",
            dataType: "json",
            data: {
                "name" : $('#name').val(),
                "address" : $('#address').val(),
                "countryCode" : $('#countryCode').val(),
                "cityCode" : $('#cityCode').val(),
                "grade" : $('#grade').val(),
                "facility" : $('#facility').val(),
                "imagePath" : $('#imagePath').val()
            }
        //成功で作成したホテルIdをアラートで表示
        }).done(function( response ){
            alert( "Hotel Id = " + response.data.hotel.id + " added." );
        //失敗もアラートで通知
        }).fail(function( data ){
            alert( "faild" );
        });
    });
})
```

簡単なコメントを追加しておきました。
Ajaxで、下記のように```success :```のような書き方をすると非同期処理のため、```response.data.hotel.id```の部分を取得することができません。


```javascript
$.ajax({
    url: "ajax.html",
    success: function(data) {
       alert('success!!');
    },
    error: function(data) {
       alert('error!!!');
    }
});
```

callbackでうまく処理の順番を制御できるそうが、jQuery1.8以上では利用者の意図に沿った処理を**done/fail**で行うことができるので便利ですね。

便利だと思いつつ、このまま進むとcallbackの使い方をちゃんと勉強せずに進んでしまいそうなのでちゃんと仕組みも理解していきたいと思います。