Rails ajaxでhogehoge.js.slim(erb)を使わずにHTMLを書き換える
概要
前回の記事では、ajaxを実現するためのファイル構成は以下のようになっていた。
- controllers - photo_controller.rb - views - photo - new.html.slim - new.js.slim - _add_photo_form.html.slim
例えばviews
内にjsファイルを配置するのではなく、なるべくassets
内のjsファイルにまとめて記述したほうがシンプルで良いという場合があると思う。
今回は、このajaxアクションのために必要なnews.js.slim
をなくしてajaxを行う方法を書いてみる。
今回のファイル構成は以下のようになる。
- controllers - photo_controller.rb - views - photo - new.html.slim - \_add_photo_form.html.slim - assets - javascript - photo.js.coffee
viewファイル
viewファイルは前回とほとんど同じ。
new.html.slim
#選択したファイルのプレビューを表示 javascript: function readUploadImage(input) { if (input.files && input.files[0]) { var reader = new FileReader(); reader.onload = function (e) { $(input).next() .attr('src', e.target.result) .width(100); }; reader.readAsDataURL(input.files[0]); } } div = form_for(@user, url: form_path, html: {multipart: true}) do |f| .div =link_to 'ボタンを追加する', new_path(@user.id),remote: true,data: {role: 'add_input'} .div data-role="photo_area" - @user.photos.each do |p| .div = image_tag p.image.url(:thumb) = check_box 'delete',"#{p.id}" = label_tag "delete[#{p.id}]", '削除' = render partial: 'photo_upload' .div = f.submit "登録する"
_add_photo_form.html.slim
.div = fields_for "user[photos_attributes][#{Time.now.to_i}]" do |ff| = ff.file_field :image, onchange: "readUploadImage(this)" = image_tag ''
render json(or text) でhtmlコンテンツを返す
photo_controller.rb
def new if request.xhr? content = render_to_string(:partial => 'add_photo_form') render json: {html: content}, status: :ok end end
ajax通信があった場合、まずはrender_to_string
で読み込みたいviewファイルをstring化する。
それをjson
形式で返してあげる。(text
でも可)
photo.js.coffee
$(window).on 'load' ,-> $('[data-role="add_input"]').bind 'ajax:beforeSend', () -> console.log 'start' .bind 'ajax:complete',(e,data,status,xhr) -> if data.responseJSON? $('[data-role="photo_area"]').append data.responseJSON.html
javascriptでajaxのcallbackを使って、上記のcontroller側から返したjson
データを取得し、指定の箇所にappend
する。
以上で終わり。