はじめに
ユーザーのことを思ってアプリ制作をしようシリーズ第二弾です。
railsでアプリを作り始めたころは画像投稿をする際にファイルを選択した後、ファイル名だけが表示されていることに対してなにも思わなかったんですけど、ある程度経験を積んでいくうちにプレビューがないとすごく不親切なアプリになってしまうということに気がつきました。
なので今回はそのやり方をメモ程度に書き残します。
作るもの
画像選択前
画像選択後
このような感じです!
railsの投稿フォームに画像のプレビュー機能をつけていきます。
用意しておくもの
画像ファイル投稿用のフォームのみです。
new.html.erb
<%= form_with model:@post do |f| %>
<%= f.file_field :image %>
<%= f.submit %>
<% end %>
こんな感じですね。
実装
流れ
- 選択された画像ファイルを読み込む
- 読み込んだ画像を投稿ファイルに出力する
以上です。
それではやっていきましょう!
1. 選択された画像ファイルを読み込む
選択された画像ファイルを読み込むにはJavaScriptを活用します。
new.html.erb
<%= form_with model:@post do |f| %>
<%# 変更箇所 %>
<%= f.file_field :image, id:"pac-input"%>
<%# ここまで %>
<%= f.submit %>
<% end %>
<%# 追加箇所 %>
<script>
let image = document.getElementById("pac-input");
image.addEventListener("change", function(evt){
let file = evt.target.files;
let reader = new FileReader();
reader.readAsDataURL(file[0]);
},false);
</script>
<%# ここまで %>
この記述で画像ファイルの読み込みは完了です。
2. 読み込んだ画像を投稿ファイルに出力する
new.html.erb
<%= form_with model:@post do |f| %>
<%= f.file_field :image, id:"pac-input"%>
<%# 追加箇所 %>
<div id="image"></div>
<%# ここまで %>
<%= f.submit %>
<% end %>
<%# 追加箇所 %>
<style>
img{
height: 300px;
width: 400px;
}
</style>
<%# ここまで %>
<script>
let image = document.getElementById("pac-input");
image.addEventListener("change", function(evt){
let file = evt.target.files;
let reader = new FileReader();
reader.readAsDataURL(file[0]);
// 追加箇所
reader.onload = function(){
let dataUrl = reader.result;
document.getElementById("image").innerHTML = "<img src='" + dataUrl + "'>";
}
// ここまで
},false);
</script>
ここまで来ると画像ファイルを選択したらその画像がfile_field
の下にでてきます。
ただ、このままでは投稿ボタンが表示された画像に隠れた状態になってしまう。
なので画像選択していない状態の時からfile_fieldの下にあらかじめスペースを作っておきましょう!
new.html.erb
<%= form_with model:@post do |f| %>
<%= f.file_field :image, id:"pac-input"%>
<div id="image"></div>
<%= f.submit %>
<% end %>
<style>
/* 追加箇所 */
#image{
background-color: rgba(241, 230, 220, 0.661);
height: 300px;
width: 400px;
}
/* ここまで */
img{
height: 300px;
width: 400px;
}
</style>
<script>
let image = document.getElementById("pac-input");
image.addEventListener("change", function(evt){
let file = evt.target.files;
let reader = new FileReader();
reader.readAsDataURL(file[0]);
reader.onload = function(){
let dataUrl = reader.result;
document.getElementById("image").innerHTML = "<img src='" + dataUrl + "'>";
}
},false);
</script>
これで完成!