#前提
- 既に画像を表示、登録できる状態であること
私は、gemのrefile
を使用して実装しています。
#実装
ソースコードは下記の通りです。
解説は、丁寧にやっていきます!
.....
<div class="form-group row">
<div class="col-lg-6">
<%= f.label :"スタジオ写真" %>
<%= f.attachment_field :studio_image, id: "image" %>
</div>
<div class="item-image col-lg-6">
<%= attachment_image_tag @studio, :studio_image, class: "card img-square", fallback: "no_img.png", size: "300x200" %>
</div>
</div>
<script>
$(function() {
$('#image').on('change', function() {
var selectedFile = this.files[0];
var fileReader = new FileReader();
fileReader.onload = function(event) {
var loadedImageUri = event.target.result;
$('.img-square').attr('src', loadedImageUri);
};
fileReader.readAsDataURL(selectedFile);
});
});
</script>
では、解説をします。
$('#image').on('change', function() {
まずここでは、id = "image"
の部分に変化があった場合、発火します。
<%= f.attachment_field :studio_image, id: "image" %>
ここですね。つまり、画像が選択された時に発火します。
var selectedFile = this.files[0];
this.files[0]
は、選択された画像のことです。
ここでは、selectedFile
に、選択された画像を格納しますよと宣言しています。
var fileReader = new FileReader();
ここで、FileReaderを起動してます。
fileReader.readAsDataURL(selectedFile);
ちょっと飛びますが、ここではselectedFile
(選択された画像)を base64 文字列に変換します。
HTML上で画像を表示するには画像を文字列に変換する必要があるためこの処理をします。
fileReader.onload = function(event) {
.onload
は、処理が成功したら次に行きますよっていうこと。
ここでは、画像ファイルが文字列に変換成功したらイベントが発火しますよっていうことです。
var loadedImageUri = event.target.result;
ここでは、loadedImageUri
に、文字列化した画像ファイルを格納します。
$('.img-square').attr('src', loadedImageUri);
img-square
っていうクラスがあるところのsrc
をloadedImageUri
(文字列化した画像)に置き換えてます。
<%= attachment_image_tag @studio, :studio_image, class: "card img-square", fallback: "no_img.png", size: "300x200" %>
この部分ですね。
はて、src
なんてどこにあるのかというところですが、これがHTML上で表示されると
<img class="attachment studio studio_image card img-square fallback" src="/assets/no_img-83551f2520af3f77b3cdac4e4405d3b6a66b8e2308418fb0e0793c084b8bb009.png" width="300" height="200">
このように表示されます。
今は、no_imageの画像が表示されてますが、これを選択した画像に非同期で切り替えようというのがプレビュー機能の中身なわけです。
ちなみに、.attr()
メソッドは、.attr( 属性, (変更する値) )
のように引数へ任意の属性を指定します。
また、属性を変更する場合のみ第2引数へ変更したい値を指定します。
つまり、今回でいうとsrc
の中身をloadedImageUri
に置き換えますよという処理をしているわけです。
以上で、プレビュー機能の完成です。
javascript初見の人はなんのこっちゃだと思いますが、少しずつ勉強すればわかるとおもいますので、頑張ってください!