1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Filelist内の添付ファイルを削除する

Posted at

RubyでECサイトのクローンを作成中に出品画面において複数枚画像投稿機能を実装していく中で、5枚以上の画像制限を設けようとした際の学習メモです。
この記事を見れば、拙いながらも、複数枚のプレビュー機能の実装と、枚数制限を実装することができます。

####学習環境
macOS BigSur
ruby-2.6.5
Rails 6.0.3.6

mulutipleオプションで複数枚の画像投稿機能を実装

ビュー内に、file_fieldを使って画像投稿できる要素を記載します。

new.html.erb
(省略)
<%= f.file_field :images, name: 'item[images][]', id:"item-image", multiple: true %>
(省略)

multiple: trueオプションで画像を複数選択することができるようになります。(詳細はこちら)

この複数選択機能に枚数制限をかけようと思い、私が実装したのは、5枚以上の画像を選択した際に、file_field要素内のfilelistからオブジェクトを削除する方法で枚数制限をかけようと思いました。

そこで、JavaScriptを使ってfilelistからオブジェクトを削除する方法を調べたところ、このサイトを参考にして、filelistを削除することができました。

Filelistを削除するコード

document.getElementById('item-image').value = "";

先程ビューで記載したfile_fieldに設定されたdataTransferオブジェクトをgetElementByIdで取得し、そのvalueに空白を代入すると、選択ファイルを削除することができました。

拙いですが、全体のコードとしては、このような感じです。

document.addEventListener('DOMContentLoaded', function (){
  if (document.getElementById('item-image')){
    const imageList = document.getElementById("image-list");
    
    const createImageHTML = (blob) => {   
      const imageElement = document.createElement('div');
      imageElement.setAttribute('class', "image-element")
      let imageElementNum = document.querySelectorAll('.image-element').length

      const blobImage = document.createElement('img');
      blobImage.setAttribute('src', blob);
      blobImage.setAttribute('id', 'add-image');
      
      const inputHTML = document.createElement('input');
      inputHTML.setAttribute('id', `item_image_${imageElementNum}`);
      inputHTML.setAttribute('name', 'image[images][]');
      inputHTML.setAttribute('type', `file`);
      
      imageElement.appendChild(blobImage);
      imageList.appendChild(imageElement);

    };
    
    document.getElementById("item-image").addEventListener("change", function(e){
      const removeContents = document.querySelectorAll("#add-image");
      const removeElements = document.querySelectorAll('.image-element');
      if (removeContents){
        removeContents.forEach(function (removeContent){
          removeContent.remove();
        })
        removeElements.forEach(function (removeElement){
          removeElement.remove();
        })
      }
      const forNum = e.target.files.length
      if (forNum < 5){
      for (let i = 0;i < forNum; i++){
        let file = e.target.files[i];
        let blob = window.URL.createObjectURL(file);
        createImageHTML(blob);
      }}else{
        document.getElementById('item-image').value = "";
      }
    });
  }
});

画像投稿のビューはこのような感じです。

new.html.erb
    (省略)
<%= form_with model: @item, url:items_path, local: true do |f| %>
    (省略)
    <div class="img-upload">
      <div class="weight-bold-text">
        出品画像
        <span class="indispensable">必須</span>
      </div>
      <div class="click-upload">
        <div id="image-list"></div>
        <p>
          クリックしてファイルをアップロード(最大4枚まで)
        </p>
        <%= f.file_field :images, name: 'item[images][]', id:"item-image", multiple: true %>
      </div>
    </div>
    (省略)
<% end %>

###完成形

なんとか、自分が思っていたとおりの実装が実現でき、とても感動しました。
もっと勉強して、レベルアップしていきたいと思います。
プログラミングの勉強はとても楽しいです。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?