フリーランスのためのネットビジネス専門学校 ネットで独立開業を目指す人を応援
フリーランスのためのネットビジネス専門学校 ネットで独立開業を目指す人を応援

[JavaScript]eachメソッドなどで複製したフォームを特定する方法

プレビュー機能(JavaScript)の実装のお話です。
もっと良い方法があるかもしれませんが、
初学者の一つのやり方として大目に見てください。

問題

このような3つ連なった画像投稿フォームがあったとします。
スクリーンショット 2018-10-12 21.39.33.png

このフォームはtimesメソッドでli.list-group-itemの複製で出来ています。

## new.html.haml

- 3.times do |i|
  %li.list-group-item.col-md-4
    .image-upload
      = f.fields_for :captured_images do |image|
        %img.s-preview
        = image.file_field
        = image.hidden_field

これに、JavaScriptでプレビュー機能を追加したいと考えました。

## preview.js

$(function(){ 
  $('.sub_image_uploader').change(function(e){ 
    var file = e.target.files[0]; 
    var reader = new FileReader(); 

    if(file.type.indexOf("image") < 0){ 
      alert("画像ファイルを指定してください。");
      return false; 
    }

    reader.onload = (function(file){
      return function(e){ 
        $(.s-preview).attr("src", e.target.result); 
        $(.s-preview).attr("title", file.name); 
    };
  })(file); 
  reader.readAsDataURL(file); 
  }); 
});

こんな感じに組みましたが画像をフォームにセットすると、、、

スクリーンショット 2018-10-10 1.19.06.png

当たり前ですが全て同じ要素なので全部に同じ画像がプレビューされてしまいました。
けど複製だからそれぞれクラスなどを直接かけない…。
どうしよう…

特定しよう

複製されたフォームに対してJavaScriptの同じくeach関数で変数付IDを付与して特定します。

## new.html.haml

- 3.times do |i|
  %li.list-group-item.col-md-4
    .image-upload.sub_image_uploader
      = f.fields_for :captured_images do |image|
        %img.s-preview
        = image.file_field :content
        = image.hidden_field :status, value: "sub"

スマートではありませんが、
.image-uploadにさらに.sub_image_uploaderというクラスを付け足しました。
これをセレクタにして、li.list-group-itemが複製された分だけ次のeach関数でIDを追加して行きます。

## Preview.js

//.sub_image_uploaderをそれぞれ特定するためにIDを付与する関数
$(function(){
  $('.sub_image_uploader').each(function(i){
    i = 1 + i;
    $(this).attr("id",`image${i}`);
  })
})

$(function(){
  $('.sub_image_uploader').change(function(e){
    var file = e.target.files[0];
    var reader = new FileReader();
    var IdentifiedImg = $(this).children("img")
    console.log(IdentifiedImg)

    if(file.type.indexOf("image") < 0){
      alert("画像ファイルを指定してください。");
      return false;
    }

    reader.onload = (function(file){
      return function(e){
        IdentifiedImg.attr("src", e.target.result);
        IdentifiedImg.attr("title", file.name);
      };
    })(file);
    reader.readAsDataURL(file);
   });
});

each関数でid=image${i}を追加します。
テンプレートリテラルで囲むことで変数が使えます。

スクリーンショット 2018-10-14 11.28.36.png

無事特定できました!
これで複製されたフォームにもそれぞれプレビューを映すことができます。
テンプレートリテラルって便利ですね!

[紹介元] jQueryタグが付けられた新着投稿 – Qiita [JavaScript]eachメソッドなどで複製したフォームを特定する方法

コメント

記事に戻る

コメントを残す