画面遷移せずに、非同期通信によってビューに画像を表示したいときがあります。
基本的にはコメントと同じく以下の流れのように編集すればいいのですが、
ところどころコメントと異なり、少しクセがあります。
・画像を取得できるようにフォームを作る。hamlを編集
・画像を非同期通信で取得する。jsを編集
・ajax通信を成功させる。コントローラを編集
・画像を表示できるようにする。ビューを編集
【工程-1】画像を取得できるようにフォームを作る。hamlを編集
まず画像を投稿できるようにフォームを作ります。
file_field :imageを使います。
= form_for [@chatgroup, @comment] ,html: {class: 'form'} do |f|
= f.submit "Send", class: 'chat-contents__type-message__button'
.chat-contents__type-message__box
%label
= f.file_field :image
【工程-2】画像を非同期通信で取得する。jsを編集
以下の記述でformの内容を非同期通信します。
file_field :imageがあれば、画像のデータもこの中に含まれます。
イベントを発生させ、ajax通信を開始し、成功したらhtmlを変更し、
フォームの内容と入力欄をリセットするという記述です。
$('.form').on("submit", function(e) {
e.preventDefault();
var formdata = new FormData($(this).get(0));
$.ajax({
type: 'POST',
url: window.location.href,
data: formdata,
dataType: 'json',
contentType: false,
processData: false,
disabled: false
})
.done(function(data){
buildHTML(data);
var textField = $('.chat-contents__type-message__box__message')
$(textField).val('')
$('.chat-contents__type-message__button').removeAttr("disabled");
alert('送信が成功しました')
})
.fail(function(error){
alert('error')
});
});
【工程-3】ajax通信を成功させる。コントローラを編集
controllerにformat.jsonを記述します。
def create
@comment = @chatgroup.comments.new(comment_params)
if @comment.save
respond_to do |format|
format.html { redirect_to chatgroup_comments_path }
format.json
end
else
flash.now[:alert] = "メッセージ送信失敗!"
render :index
end
end
imageを渡せるようにjbuilderにも記述します。
json.image @comment.image
【工程-4】画像を表示できるようにする。ビューを編集
ページを読み込んだときに表示できるようにhamlに記述します。
mcommentテーブルのimageをとってくるだけなので、簡単ですね。
=image_tag(comment.image, size: 256)
次に非同期通信に対応するように、jsに記述します。
img src = '${data.image.url}' width="256" height="256"
コントローラーにimageがparamsとして渡っているのと、
jbuilderにjson.image @comment.imageと記述があることを前提としています。
ここまでで画像が表示できるようにはなっていると思います。
【調整-1】画像がないときにも対応できるように調整
画像は表示できるようになりましたが、このままでは画像がないときにも画像が収まる枠が表示されてしまいます。
両方に対応できるように条件分岐をしましょう。
var html = `hoge`
if (data.image.url == null){
html = $(html).append(`</li>`)
} else {
html = $(html).append(`<div class = 'hoge'><img src = '${data.image.url}' width="256" height="256"}</div></li>`)
}
$('.chat-contents__body__comments').append(html)
src = '${data.image.url}'とありますが、これはデータ属性を持たせるための記述です。非同期通信で画像を追加する前のものと比較するためです。
【調整-2】gitに画像のアップロードが認識されないよう、.gitignoreに記述を加える。
画像を投稿するごとにpublic/uploads/comment/imageに画像がどんどんストックされていきます。このままでは、gitに変更したものと認識されてしまうので、変更対象として認識されないようになります。.gitnoreに記述を加えることで、認識されないようにします。
.gitignoreはアプリケーションのディレクトリ直下にあります。私は最初、.gitignoreがあるのを知らず、command + newで自分で作ろうとしていました。自分で作ろうとしても拡張子使えんよって言われるので、やめましょう。
なお、.gitignoreについては、このリンク先がすごく詳しいです↓
.gitignoreの末尾に/imageと/tmpを記入
Ignore all logfiles and tempfiles.
/log/*
!/log/.keep
/image
/tmp
以上になります。