質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.59%

画像プレビューを表示したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 977

score 7

前提・実現したいこと

画像プレビューを表示したい

現在、出品機能で商品のプレビュー機能を付けようとしています

・複数の画像の登録は出来ています
・商品の登録はデータベースで確認はできています

ファイルを入れた時だけ表示が出来ない状態を解決したいです

イメージ説明

該当のソースコード

_item.html.haml

.buy-content
  .buy-content__inner
    = form_with model:@item, local:true do |f|

      -# 出品画像
      .buy-content__inner__up
        .buy-content__inner__up__box
          .buy-content__inner__up__box__name
            .buy-content__inner__up__box__name__image
              = f.label :出品画像
              %span.have-to 必須
          %p.ten-up 最大10枚までアップロードできます
          #image-box
            #previews
              - if @item.persisted?
                - @item.images.each_with_index do |image, i|
                  = image_tag image.image.url, data: { index: i }, width: "100", height: '100'

            = f.fields_for :images do |i| 
              .js-file_group{"data-index": "#{i.index}"}
                = i.file_field :image, class: 'js-file'
                %span.js-remove 削除
                =icon("fa","camera")

              - if @item.persisted?
                = image.check_box :_destroy, data:{ index: image.index }, class: 'hidden-destroy'

            - if @item.persisted?
              .js-file_group{"data-index": "#{@item.images.count}"}
                = file_field_tag :image, name: "item[images_attributes][#{@item.images.count}][image]", class: 'js-file'
                .js-remove 削除
item.jp

$(function() {
  // 画像用のinputを生成する関数
  const buildFileField = (num)=> {
    const html = `<div data-index="${num}" class="js-file_group">
                    <input class="js-file" type="file"
                    name="item[images_attributes][${num}][image]"
                    id="item_images_attributes_${num}_image"><br>
                    <div class="js-remove">削除</div>
                  </div>`;
    return html;
  }

  // プレビュー用のimgタグを生成する関数
  const buildImg = (index, url)=> {
    const html = `<img data-index="${index}" image="${url}" width="100px" height="100px">`;
    return html;
  }

  // file_fieldのnameに動的なindexをつける為の配列
  let fileIndex = [1,2,3,4,5,6,7,8,9,10];

  // 既に使われているindexを除外
  lastIndex = $('.js-file_group:last').data('index');
  fileIndex.splice(0, lastIndex);

  $('.hidden-destroy').hide();

  $('#image-box').on('change', '.js-file', function(e) {
    const targetIndex = $(this).parent().data('index');
    // ファイルのブラウザ上でのURLを取得する
    const file = e.target.files[0];
    const blobUrl = window.URL.createObjectURL(file);
    // 該当indexを持つimgタグがあれば取得して変数imgに入れる(画像変更の処理)
    if (img = $(`img[data-index="${targetIndex}"]`)[0]) {
      img.setAttribute('image', blobUrl);
    } else {  // 新規画像追加の処理
      $('#previews').append(buildImg(targetIndex, blobUrl));
      // fileIndexの先頭の数字を使ってinputを作る
      $('#image-box').append(buildFileField(fileIndex[0]));
      fileIndex.shift();
      // 末尾の数に1足した数を追加する
      fileIndex.push(fileIndex[fileIndex.length - 1] + 1)
    }
  });

  $('#image-box').on('click', '.js-remove', function() {
    const targetIndex = $(this).parent().data('index')
    // 該当indexを振られているチェックボックスを取得する
    const hiddenCheck = $(`input[data-index="${targetIndex}"].hidden-destroy`);
    // もしチェックボックスが存在すればチェックを入れる
    if (hiddenCheck) hiddenCheck.prop('checked', true);

    $(this).parent().remove();
    $(`img[data-index="${targetIndex}"]`).remove();

    // 画像入力欄が0個にならないようにしておく
    if ($('.js-file').length == 0) $('#image-box').append(buildFileField(fileIndex[0]));
  });
});
image_uploader.rb

class ImageUploader < CarrierWave::Uploader::Base
  # Include RMagick or MiniMagick support:
  # include CarrierWave::RMagick
  include CarrierWave::MiniMagick
  process resize_to_fit: [100, 100]
  # Choose what kind of storage to use for this uploader:
  storage :file
  # storage :fog

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end
application.jp

//= require activestorage

//= require jquery
//= require jquery_ujs
//= require_tree .
Gemfile

gem 'carrierwave'
gem 'mini_magick'

gem 'jquery-rails'
gem 'jquery-ui-rails'

試したこと

https://qiita.com/jkr_2255/items/ba6bfc59457ea12a76ff

Qiitaにあった記事を参考に”Turbolinks”に問題があるのでは?
と思いましたが、具体的な解決法には至りませんでした。

javascriptにの書き方に問題がある気はするのですが、どうでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

javascriptにの書き方に問題がある気はする

src属性ですね。

//const html = `<img data-index="${index}" image="${url}" width="100px" height="100px">`;
const html = `<img data-index="${index}" src="${url}" width="100px" height="100px">`;

//img.setAttribute('image', blobUrl);
img.setAttribute('src', blobUrl);

MDN <img>: 画像埋め込み要素

開発者コンソールの Network タブ
正しくURL指定(data: や blob: の場合も)されていれば、Waterfall が表示されるはずです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/05/30 22:59

    返事が遅くなり、申し訳ございませんでした!

    記載の通り、”scr"へ書き直したところうまく表示できました!

    説明も丁寧で分かり易かったです!

    ありがとうございました!!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る