🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Slim

SlimはPHPアプリケーションを開発するための軽量なマイクロフレームワークです。

Q&A

解決済

1回答

2938閲覧

JavaScriptの関数の実行タイミングを一番最後にしたい

m-88888888

総合スコア14

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Slim

SlimはPHPアプリケーションを開発するための軽量なマイクロフレームワークです。

0グッド

0クリップ

投稿2019/12/30 13:17

やりたいこと

Ruby on Railsを使ってWebアプリケーションを作成しています。
nested_form_fieldsというgemを使って、動的に画像アップロードフォームを含めた入力フォームを動的に追加できる機能を実装しており、この追加された画像アップロードフォームのそれぞれに対して画像プレビュー機能をつけたいと考えています。

イメージ画像
イメージ説明

slim

1// _form.html.slim 2= f.nested_fields_for :gears, wrapper_tag: :div do |g| 3 .item 4 .row 5 .col-6 6 .form-group 7 = g.label :gear_image 8 - if g.object.gear_image? 9 = image_tag(g.object.gear_image.url, id: 'preview__nested_field_for_replace_with_index__', class: 'gear_image') 10 - else 11 = image_tag('nofile.jpg', id: 'preview__nested_field_for_replace_with_index__', class: 'gear_image') 12 = g.file_field :gear_image, class: "form-control-file gear-file-form" 13 .col-6 14 .form-group 15 = g.label :name 16 = g.text_field :name, class: "form-control" 17 .form-group 18 = g.label :brand 19 = g.text_field :brand, class: "form-control" 20 .form-group 21 = g.label :kind 22 = g.select :kind, gear_type_list, { include_blank: true }, class: "form-control" 23 .form-group 24 = g.label :model_year 25 = g.text_field :model_year, class: "form-control" 26 = g.remove_nested_fields_link '削除', class: 'btn btn-danger', role: 'button' 27= f.add_nested_fields_link :gears, '+', class: 'btn btn-primary', role: 'button', id: 'add-form'

javascript

1// application.js 2document.addEventListener('DOMContentLoaded', function () { 3 var index = 1; 4 var fuga = '#preview'; 5 6 document.getElementById('add-form').addEventListener("click", function () { 7 index += 1; 8 // とりあえず以下2通り試しましたがフォーム作成前に実行されてしまいます。 9 hogehoge(index); // 1 10 window.onload = hogehoge(index); // 2 11 }, false); 12 13 // 関数① 14 function hogehoge(index) { 15 for (var i = 0; i < index; i++) { 16 (function (j) { 17 fuga += j.toFixed(); 18 var id = 'article_gears_attributes_' + j + '_gear_image'; 19 document.getElementById(id).addEventListener("change", function (evt) { 20 var file = evt.target.files; 21 var reader = new FileReader(); 22 reader.readAsDataURL(file[0]); 23 reader.onload = function () { 24 document.querySelector(fuga).src = reader.result; 25 } 26 }, false); 27 }(i)); 28 } 29 }; 30 window.onload = hogehoge(index); 31});

問題点

JavaScriptで

  1. フォームの数だけ画像アップロードフォームにイベントを追加する関数hogehogeを定義・・・①
  2. ページ読み込み時に①を実行
  3. フォームの追加ボタン(画像では+ボタン)を押下した時に①の関数hogehogeを再実行

という流れを思い浮かべていたのですが、3.でフォームがnested_form_fieldsによって追加される前に
①の関数hogehogeが実行されてしまい、Uncaught TypeError: Cannot read property 'addEventListener' of nullを吐いてしまいます。

フォームが追加された後に関数hogehogeを実行させるようにしたいのですが、なにか良いやり方はないでしょうか?

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは、m-88888888さん

質問拝見しました。

早速ですが、問題点の3は、おそらくwindow.onloadに、hogehogeメソッドを実行した返り値を渡すようになっているからだと思います。
window.loadに渡せるのは、関数自体になるので、質問と同じ条件でindexを渡した状態で関数を渡したいのであれば、bindメソッドを利用すると良いと思います。
こうすれば、 DOMContentLoadedイベント時に、window.onloadがセットアップされ、loadイベントが完了したあとに、indexを捕捉した状態でhogehogeメソッドが実行されます。

window.load
Function.prototype.bind()

// application.js document.addEventListener('DOMContentLoaded', function () { ...(省略) window.onload = hogehoge.bind(this, index); });

以上、参考になれば、幸いです。

投稿2019/12/30 13:52

gentamura

総合スコア406

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m-88888888

2019/12/31 08:39

ご指摘の通り、bindメソッドを使用したところエラーの表示までは解消されましたが、肝心の関数hogehogeは実行された形跡が見られませんでした。 おそらく今回の問題とはまた別?だと思うので、こちらは自分で取り組んでみます。 この度はご回答いただき誠にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問