👏

rails 画像のプレビュー機能

2022/01/21に公開約3,200字

はじめに

自分が付けた方法を載せていきます。

STEP1

まずは、Tweetsテーブルにimageカラムを追加します。

$ rails g migration AddImageToTweets image:string

こちらのコードを打てば大丈夫です。

STEP2

続いては、JavaScriptを導入していきます

導入は、

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

この文章をHTMLに記述をするだけです。

記述をする場所は

app/views/layouts/application.html.erb
<head>
    <title>Aaaaaaa</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.14.0/css/all.css">
#ここに追加
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

STEP3

次は画像投稿のフォームの中身を記述していきます

app/views/tweets/new.html.erb
<%= form_for @tweet do |f| %>
  <div class="form-group">
    <div class="image_form">
      <div class="image_form__contents">
        <%= f.label :image, class: 'image_label' do %>
          <div class="prev-contents">
            <% if @tweet.image.present? %>
              <div class="prev-content">
                <%= image_tag @tweet.image.url, alt: "preview", class: "prev-image" %>
              </div>
            <% else %>
              <i class="fas fa-image"></i>
            <% end %>
          </div>
          <%= f.file_field :image, class: 'image_form_contents_field hidden_file' %>
        <% end %>
      </div>
    </div>
  </div>

  <%= f.submit "Tweetする" %>
<% end %>

STEP4

続いて、CSSを記述してファイル選択の部分を消します。

クラス名でCSSを書くのでSCSSでもCSSファイルでもどちらに記述しても大丈夫です。

app/assets/stylesheets/application.css
.image_form_contents_field {
  display: none;
}

STEP5

最後にスクリプトタグの中にJavaScriptを記述します

<script>
  $(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 });
        }
      }
    });
  });
});
</script>

STEP6

お疲れ様です。
これで以上になります。

Discussion

ログインするとコメントできます