【画像アップロード】file_fieldデザイン変更+画像選択時にプレビュー表示する方法

プログラミング初心者の勉強ブログ #88

Railsアプリの画像アップロードで使うfile_fieldのデザイン変更と、画像選択時にプレビュー表示する方法をまとめます。デフォルトデザインを変更し、ユーザーが画像選択後すぐに画像を確認できるため、UX/UI向上が図れます。(アップローダーはcarrierwaveとmini_magickを使用して実装しております。)

 

目次

[toc]

 

実装内容

filefield

上の画像のようなfile_fieldを作成する。(デフォルトデザインの変更+画像選択直後にプレビュー表示)

 

大まかな流れ

画像アップロードで使う「file_field」についても以前まとめたラジオボックス同様、デフォルトデザインを「display: none;」で隠して、紐付けした別要素(今回の場合divタグ)でオリジナルデザインを作っていきます。

※ラジオボックスについては、【CSS】仕組みから知る!ラジオボタンを自分好みのデザインにする方法で紹介しております。

 

  1. <input type=”file”>を「display: none;」で隠す
  2. <input type=”file”>とdivタグをJavaScriptで紐づける
  3. divタグでデザイン作成
  4. JavaScriptで選択された画像を取得し、即表示させる

この流れで作成していきます。

※画像アップロード機能は「carrierwave」と「mini_magick」で実装しております。

 

デフォルトデザインを隠してdivと紐付け

form.html.erb

<div class="field image">
  <%= form_with(model: @blog, local: true) do |form| %>
    <%= form.label 'サムネイル(スクリーンショットなど)' %>

      // id "file"で、fileとdivを紐付けクリック時に連動
      <div id="img_field" onClick="$('#file').click()" >

        // 画像があるときは画像を表示する
        <% if @blog.image.url.present? %>
          <%= image_tag(@blog.image.url) %>
        <% else %>
          <i class="fas fa-image"></i><i class="fas fa-file-upload add"></i>
        <% end %>

      </div>
    
    // id "file"をつけ、「display:none;」で隠す
    <%= form.file_field :image, class: "image", style: "display:none;", id: "file"%>
  <% end %>
</div>

 

<input type=”file”>タグが構成される以下のコードで

// id "file"をつけ、「display:none;」で隠す
<%= form.file_field :image, class: "image", style: "display:none;", id: "file"%>

このようにidとstyleをつけ、

// id "file"で、fileとdivを紐付けクリック時に連動
<div id="img_field" onClick="$('#file').click()" >

inputにつけたidでdivと紐付けます。クリック時に対応したいので「onClick」でjQueryを書き込みます。

 

divに対しCSSでデザイン作成

最初に載せた画像のデザインのCSSです。

style.css

#img_field {
  font-size: 15px;
  margin-top: 10px;
  padding: 5px 8px;
  border: solid 1px #EDBC6C;
  color: #666;
  position: relative;
  padding: 0;
  border-radius: 5px;
  cursor: pointer;
  width: 400px;
  height: 250px;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
  background-color: #fff;
  overflow: hidden;
  box-sizing: border-box;
  transition: 0.3s ease-out;
}

#img_field i {
  font-size: 100px;
  color: #aaa;
  line-height: 250px;
  transition: 0.3s ease-out;
}

#img_field i.add {
  display: none;
  font-size: 50px;
  position: absolute;
  top: -90px;
  right: 15px;
}

#img_field:hover {
  background-color: #EDBC6C;
  transition: 0.3s ease-out;
  opacity: 0.9;
}

#img_field:hover i {
  transition: 0.3s ease-out;
  display: block;
  color: #fff;
}

 

画像プレビューの表示

application.js

$(function(){
  $fileField = $('#file')

  // 選択された画像を取得し表示
  $($fileField).on('change', $fileField, function(e) {
    file = e.target.files[0]
    reader = new FileReader(),
    $preview = $("#img_field");

    reader.onload = (function(file) {
      return function(e) {
        $preview.empty();
        $preview.append($('<img>').attr({
          src: e.target.result,
          width: "100%",
          class: "preview",
          title: file.name
        }));
      };
    })(file);
    reader.readAsDataURL(file);
  });
});

jsで選択された画像の取得を行います。onとchangeメソッドで「$fileField」で選択されたデータが「e」に入ります。

 

ここまでいくと、

filefield

プレビューが表示できるようになります。

 

まとめ

画像アップロードのデフォルトデザインの変更は後回しにしてた部分だったのですが、無事実装できました。jsに少しづつ慣れてきたのかもしれません。よくわかってない部分もありますが。

以上ありがとうございました。

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA