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

[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


無事特定できました!

これで複製されたフォームにもそれぞれプレビューを映すことができます。

テンプレートリテラルって便利ですね!

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)