前提条件
・ruby 2.6.6
・rails 6.0.3.4
・ActiveStorageをインストール済
・deviseを使用
・画像投稿システムを実装済
概要
画像を投稿する際、特にデフォルトの設定であれば``ファイルを選択``をして画像を選ぶと、その画像の名前が表示されるだけで、どういった画像なのか確認することができません。 そこで画像プレビュー機能を実装してどういった画像が投稿されるか確認できるようにしていきます。イメージ画像を以下に添付します。
実装
では実際にコードを書いていきます。新規投稿画面にも編集画面にも両方とも使えるので 必要な箇所に活用してください。<%= form_with model: @post, local: true do |f| %>
<div class="form-group">
<div class="field">
<%= f.label :images, "写真" %><span class="must">*</span>
</div>
<p>[5MBまで、最大アップロード枚数5枚]</p>
<%= f.file_field :images, class: "push", multiple: true, onchange: "loadImage(this);" %>
</div>
<div id="post_images" style="display: none;">
<p id="preview"></p>
</div>
<% end %>
<%= render "loadimage" %>
特段注意して欲しいのが、7行目の <%= f.file_field :images, class: "push", multiple: true, onchange: "loadImage(this);" %>
の onchange: "loadImage(this);"
の部分です。この表記を入れることでjavascriptと関係付けをします。
もう一つが <div id="post_images" style="display: none;"></div>
の部分
ここに選択した画像を表示するようにjavascriptを記述していきます。記述するのは部分テンプレートとしてposts/_loadimage.html.erb
に記述していきます。
<script>
function loadImage(obj)
{
var allPreview = document.getElementById('post_images');
var newPreview = document.createElement("p");
allPreview.querySelector("p").remove();
newPreview.setAttribute("id","preview");
allPreview.insertBefore(newPreview, allPreview.firstChild);
document.getElementById("post_images").style.display = "";
for (i = 0; i < obj.files.length; i++) {
var fileReader = new FileReader();
fileReader.onload = (function (e) {
var img = new Image();
img.src = e.target.result;
document.getElementById('preview').appendChild(img);
});
fileReader.readAsDataURL(obj.files[i]);
}
}
</script>
javascriptに関係付けているid
の名前等は自身のidに置き換えてください。
4行目:<div id="post_image">
を読み込む
5行目:<p>
を生成
6行目:<div id="post_image">
の中の<p>
を削除
7行目:5行目で生成した<p>
を<p id="preview"></p>
に設定
8行目:7行目で設定した<p id="preview"></p>
を<div id="post_image">
の中の最初の要素として設定
9行目:viewの方で<div id="post_images" style="display: none;">
としてたのでstyle="display: "";
に変更して、表示させるように設定。
10~18行目:ファイル選択した画像の枚数分for文を回し、15行目でその都度<p id="preview"></p>
を生成。17行目で画像を読み込み表示させる設定を行います。
4~8行目で削除したり設定したりしていますが、これは更新するごとに画像を更新するためです。
ざっとですがコードの説明でした。
実装の手助けになれば幸いです。