RailsではフォームのAjax化を機能として提供してくれるが、あえてそれを使わないパターンを試してみる
ポイントはcsrf対策向けの処理を自分で書かなければならないというところか
user_controller.rb
# POST /users
# POST /users.json
def create
@user = User.new(user_params)
respond_to do |format|
if @user.save
format.html { redirect_to @user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: @user }
else
format.html { render :new }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
user.html.erb
<form id="the-form" action="/users.json" method = "POST">
<input type="text" name="user[name]" value="">
<button>submit</button>
</form>
http://ginpen.com/2013/05/07/jquery-ajax-form/
を参考にAjaxの処理を追加。
CSRFトークンをページから読み取り追加してあげる。
users.js
jQuery(function($) {
$('#the-form').submit(function(event) {
// HTMLでの送信をキャンセル
event.preventDefault();
// 操作対象のフォーム要素を取得
var $form = $(this);
// 送信ボタンを取得
// (後で使う: 二重送信を防止する。)
var $button = $form.find('button');
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
var token;
if (!options.crossDomain) {
token = $('meta[name="csrf-token"]').attr('content');
if (token) {
return jqXHR.setRequestHeader('X-CSRF-Token', token);
}
}
});
// 送信
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
data: $form.serialize(),
timeout: 10000, // 単位はミリ秒
// 送信前
beforeSend: function(xhr, settings) {
// ボタンを無効化し、二重送信を防止
$button.attr('disabled', true);
},
// 応答後
complete: function(xhr, textStatus) {
// ボタンを有効化し、再送信を許可
$button.attr('disabled', false);
},
// 通信成功時の処理
success: function(result, textStatus, xhr) {
// 入力値を初期化
$('tbody').append(result.name);
},
// 通信失敗時の処理
error: function(xhr, textStatus, error) {}
});
});
});