&tag(Rails/Ajax); *目次 [#n755f4d8] #contents *関連ページ [#w18db114] -[[Rails]] -[[Rails/検証]] *参考情報 [#zcba7473] -[[Rails / Ajaxを使って画面遷移しない一時保存機能をつける | Workabroad.jp:http://www.workabroad.jp/posts/2091]] -[[Ruby - RailsでAjaxを使ってインクリメンタルサーチ - Qiita:http://qiita.com/Kta-M/items/99003e6d9d98b0ba512f]] -formの内容をcommitしたい場合、jQuery Form Pluginのような便利なライブラリを使ったほうが便利。 *フォームの内容の自動保存する [#oec0ecd3] -[[Rails / Ajaxを使って画面遷移しない一時保存機能をつける - Qiita:http://qiita.com/shunwitter/items/bdad11ec7d4a99ca3d3b]]より。 **フォームの入力フィールド [#e8da407e] -class="create-temp"のdivがポイント #pre{{ <div class="blog-form"> <%= form_for(@post) do |f| %> <%= f.text_field :tilte %> <%= f.text_area :body %> <!-- for temporal saving --> <div class="create-temp"></div> <%= f.submit "送信する" %> <% end %> </div> }} **フォームの送信処理部分(JavaScript版) [#i4e5cc2d] -submit用に[[jQuery Form Plugin:http://malsup.com/jquery/form/]]を使う。 -keydownにより何か変更があったら5秒後に送信されることになる。 -spanのdeta-result属性がtrueでない場合はcreate-tempを、trueの場合はupdateを呼び出すようにする。 #pre{{ var ready, tempSubmit; ready = function() { if ($('.create-temp')) { window.tempTimer = null; return $('.blog-form form').keydown(function() { window.clearTimeout(tempTimer); return window.tempTimer = window.setTimeout(function() { return tempSubmit(); }, 5000); }); } }; tempSubmit = function() { if ($('.create-temp span').data('result') !== true) { return $(".blog-form form").ajaxSubmit({ url: '/posts/temp', type: 'post' }); } else { return $(".blog-form form").ajaxSubmit(); } }; $(document).ready(ready); $(document).on('page:load', ready); }} **routes.rb [#b1676ad0] -上記JavaScriptでPostしているrouteをを作成。 #pre{{ post '/posts/temp', to: 'posts#create_temp', as: :temp_post }} **コントローラー [#kf46062d] -createは通常の保存処理。create_tempからajaxから呼ばれるメソッド。 #pre{{ def create @post = Post.new(post_params) if @post.save redirect_to(@post) else render('new') end def create_temp @post = Post.new(post_params) @post.save end def update respond_to do |format| if @post.update(post_params) format.js {} format.html {redirect_to @post, notice: 'Post was successfully updated.'} else format.js {} format.html {render :edit} end end end }} ** レスポンス用のjs.erb[#va8d45d5] -create_temp.js.erbの内容 #pre{{ var result = <%= @post.valid? %>; var msg = ""; var notice = ""; if (result == true) { msg = "下書き保存されました"; // This is for Temporal saving // forcing the form to look update method. // Add id $('.blog-form form').prepend('<input name="post[id]" type="hidden" value="<%= @post.id %>">'); // Chnage REST method $('.blog-form input[name=_method]').remove(); $('.blog-form form').prepend('<input name="_method" type="hidden" value="patch">'); // Change URL $('.blog-form form').attr('action', '/posts/<%= @post.id %>'); } else { msg = "下書き保存のための情報が足りません"; } // Message notice = "<span data-result=" + result + ">" + msg + "</span>"; $('.create-temp span').remove(); $('.create-temp').hide().append(notice).fadeIn(); }} -update.js.erbの内容。 #pre{{ var persisted = <%= @post.persisted? %>; var result = <%= @post.valid? %>; var msg = ""; if (result == true) { msg = "下書きが更新保存されました"; } else { msg = "下書き更新保存のための情報が足りません"; } // Message notice = "<span data-result=" + persisted + ">" + msg + "</span>"; $('.create-temp span').remove(); $('.create-temp').hide().append(notice).fadeIn(); }} *flashメッセージの取り扱い [#ya8fb586] -通常のrequestと取り扱いがことなるためajax_requestで設定したメッセージが2重に表示されたりする場合がある。 -[[How do you handle Rail's flash with Ajax requests? - Stack Overflow:http://stackoverflow.com/questions/366311/how-do-you-handle-rails-flash-with-ajax-requests]] -これを回避するためにApplicationControlerにafter_filterを設定する。 #pre{{ after_filter :clear_flash private def clear_flash flash.discard if request.xhr? end }} *トラブルシューティング [#jb3edf89] **js.erbがレンダリングされない [#r8751e38] -例えばupdateメソッドでupdate.js.erbが実行されない。 -以下のようにresponde_toで、「format.js {}」を追加する必要がある。 -さらにformat.jsが、format.htmlより先にないとだめかも? #pre{{ def update respond_to do |format| if @post.update(post_params) format.js {} format.html {redirect_to @post, notice: 'Post was successfully updated.'} else format.js {} format.html {render :edit} end end end }}