LoginSignup
21
27

More than 3 years have passed since last update.

[Rails]画像選択時にプレビュー表示

Last updated at Posted at 2020-04-05

本記事投稿のいきさつ

アプリの中で画像投稿機能を実装したとき、ただフォームを作成するだけでは画像を選択しても表示がされず何を選んだのか確認をすることが出来ません。
そこで、画像を選択した時点でプレビュー表示することができればいいなと思い、実際に機プレビュー機能を作成したため、記録として残したいと思います。
今回はユーザーのプロフィール画像の編集画面を想定します。
そのため、既に登録されている画像は最初からプレビューさせた状態で表示をさせます。

前提

  • 変種画面はprofile_edit.html.haml
  • 画像の保存先は Usersテーブル: imageカラム
  • file_field本体は隠し、画像が選択されていない時はiconを、 選択されている時はプレビュー画像をクリックすることで画像選択できるようにします。
  • jQueryを使用しますが、必要なGemのインストール等は既に出来ているとします。
  • ユーザー機能はDeviseを使用しています。
  • cssは今回の内容に含まれません。

フォーム作成

まず、今回はhamlでビューのフォームを作成します。

profile_edit.html.haml
= form_for current_user, url: {action: 'profile_update'} do |f|

    .form-group 
      .image_form
        .image_form__contents
          -# ラベルでfile_fieldとicon、プレビュー画像を紐付けます
          = f.label :image, class: 'image_label' do
            .prev-contents
              -# 既に登録されている画像があれば表示をさせます
              - if current_user.image.present?
                .prev-content
                  = image_tag current_user.image.url, alt: "preview", class: "prev-image"
              -# 既に登録されている画像がなければiconを表示させます
              - else
                = icon('fas', 'image', class: 'photo-icon')
            -# file_fieldはdisplay: none;で隠します
            = f.file_field :image, class: 'image_form__contents__field hidden_file'

FileReader

今回はFileReaderを使用します。
FileReaderとはHTML5世代の機能でユーザーのPC内にあるファイルやバッファ上の生データに対して、読み取りアクセスを行えるオブジェクトです。

jsファイルの編集

今回はimage_preview.jsを作成して、そこに記述していきます。

image_preview.js

$(document).on('turbolinks:load', function () {
  $(function () {
    // 画像をプレビュー表示させる.prev-contentを作成
    function buildHTML(image) {
      var html =
        `
        <div class="prev-content">
          <img src="${image}", alt="preview" class="prev-image">
        </div>
        `
      return html;
    }

    // 画像が選択された時に発火します
    $(document).on('change', '.hidden_file', function () {
      // .file_filedからデータを取得して変数fileに代入します
      var file = this.files[0];
      // FileReaderオブジェクトを作成します
      var reader = new FileReader();
      // DataURIScheme文字列を取得します
      reader.readAsDataURL(file);
      // 読み込みが完了したら処理が実行されます
      reader.onload = function () {
        // 読み込んだファイルの内容を取得して変数imageに代入します
        var image = this.result;
        // プレビュー画像がなければ処理を実行します
        if ($('.prev-content').length == 0) {
          // 読み込んだ画像ファイルをbuildHTMLに渡します
          var html = buildHTML(image)
          // 作成した.prev-contentをiconの代わりに表示させます
          $('.prev-contents').prepend(html);
          // 画像が表示されるのでiconを隠します
          $('.photo-icon').hide();
        } else {
          // もし既に画像がプレビューされていれば画像データのみを入れ替えます
          $('.prev-content .prev-image').attr({ src: image });
        }
      }
    });
  });
});

上記で出てくるDataURISchemeとは、
簡単にいうと、画像やらJavascriptやらそういったHTMLのコンテンツを文字列として定義出来るものです。
以上で、画像が表示されます。

終わり

最後まで見ていただきありがとうございました。

21
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
27