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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby on Rails 5

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

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

3回答

1319閲覧

JQueryで複製した投稿フォームで、GoogleMap上に任意でマーカーを落としたい

admj

総合スコア0

Ruby on Rails 5

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

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2020/05/18 16:47

編集2020/05/19 03:39

前提・実現したいこと

Ruby on Railsを使って作った投稿フォームを、JQueryで複製して複数投稿をできるものを作っています。
投稿フォームの複製はできているのですが、複製されたフォームでGoogleMap上に任意でマーカーを落とせるようにしたいです。

発生している問題・エラーメッセージ

Uncaught TypeError: Cannot read property 'setCenter' of undefined

該当のソースコード

・・・ <!-- 投稿フォーム --> <% j = 0 %> <%= c.fields_for :travelogues do |t| %> <!-- Jqueryで複製されるフォーム部分 --> <div class="form-block" id="form-block"> <input name="del" type="button" value="この投稿を削除する" class="del del-button edit-form btn btn-md btn-danger "> <table class="table"> <tr> <th class="show-th"><%= t.label "本文",class:"th-font" %></th> <td><%= t.text_area :body, name:"body", class:"form-control" %></td> </tr> <tr> <th rowspan="2" class="show-th"> <%= t.label :address, "スポット名(Google Mapで検索)", class:"th-font" %> </th> <td> <%= t.text_field :address, placeholder: "スポット名を入力", name:"address", id:"address_#{j}" %> <input name="onclick" onclick='codeAddress("<%= j %>")' type="button", value="検索"></input> </td> </tr> <tr> <td colspan="2"> <div name="map" id="map_<%= j %>" style="height: 300px; width: 80%;"></div> </td> </tr> </table> <input type="button" value="投稿を追加する" class="add edit-form btn btn-md btn-danger"> </div> <% end %> ・・・

js

1// 動的に投稿フォームを追加する用 2let idNo = 1; 3 4// class="add"がクリックされたらフォームをクローンする 5$(document).on("click", ".add", function () { 6 // 投稿削除のボタンを表示させる 7 $("input[name=del]").removeClass("del-button"); 8 $(this).parent() 9 // フォームをコピー 10 .clone(true) 11 // idを削除 12 .removeAttr("id") 13 // 新たにidを付与 14 .find("input[name=body]") 15 .attr("id", "body" + idNo) 16 .end() 17 .find("[name=map]") 18 .attr("id", "map_" + idNo) 19 .end() 20 .find("input[name=onclick]") 21 .attr("onclick", "codeAddress(" + idNo + ")") 22 .end() 23 .find("input[name=address]") 24 .attr("id", "address_" + idNo) 25 .end() 26 // 親要素の後にinsert 27 .insertAfter($(this).parent()); 28 // ID番号加算 29 idNo++; 30}); 31// class="del"がクリックされたらフォームを削除 32$(document).on("click", ".del", function () { 33 // 2ヵ所で使うので選択された親要素を変数targetに格納 34 var target = $(this).parent(); 35 // 変数targetの親要素下の要素数が1以下だったら 36 // 変数targetを削除 37 if(target.children().length > 1){ 38 target.remove(); 39 } 40});

js

1let maps = [] //変数の定義 2let geocoder //変数の定義 3 4function initMap(){ //最初にGooglemapを表示する時のコールバック関数 5 geocoder = new google.maps.Geocoder() //GoogleMapsAPIジオコーディングサービスにアクセス 6 if(document.getElementById('map_0')){ //'map'というidを取得できたら実行 7 // 地図を複数表示させるためfor文でループ 8 for (var i = 0; i < 10; i++) { 9 maps[i] = new google.maps.Map(document.getElementById('map_' + i), { //'map'というidを取得してマップを表示 10 center: {lat: 35.6594666, lng: 139.7005536}, //最初に表示する場所(今回は「渋谷スクランブル交差点」が初期値) 11 zoom: 15, //拡大率(1〜21まで設定可能) 12 }); 13 } 14 }else{ //'map'というidが無かった場合 15 for (var i = 0; i < 10; i++) { 16 maps[i] = new google.maps.Map(document.getElementById('show_map_' + i), { //'show_map'というidを取得してマップを表示 17 center: {lat: gon.lat[i].latitude, lng: gon.lng[i].longitude}, //controllerで定義した変数を緯度・経度の値とする(値はDBに入っている) 18 zoom: 15, //拡大率(1〜21まで設定可能) 19 }); 20 marker = new google.maps.Marker({ //GoogleMapにマーカーを落とす 21 position: {lat: gon.lat[i].latitude, lng: gon.lng[i].longitude}, //マーカーを落とす位置を決める(値はDBに入っている) 22 map: maps[i] //マーカーを落とすマップを指定 23 }); 24 } 25 } 26}; 27function codeAddress(j){ //検索ボタンを押した時のコールバック関数 28 // ここは引数を渡すだけでループさせない 29 let inputAddress = document.getElementById('address_' + j).value; //'address'というidの値(value)を取得 30 geocoder.geocode( { 'address': inputAddress}, function(results, status) { //ジオコードしたい住所を引数として渡す 31 if (status == 'OK') { 32 console.log(results[0].geometry.location) 33 maps[j].setCenter(results[0].geometry.location); //検索値に最も近い結果の緯度・経度 34 let marker = new google.maps.Marker({ 35 map: maps[j], //マーカーを落とすマップを指定 36 position: results[0].geometry.location //マーカーを落とす位置を決める 37 }); 38 } else { 39 alert('該当する結果がありませんでした'); 40 } 41 }); 42};

試したこと

console.logで見ると、複製されたフォームでも緯度・経度の取得はできていました。

補足情報(FW/ツールのバージョンなど)

・Ruby
Rails 5.2.4.1

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

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

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

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

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

Lhankor_Mhy

2020/05/19 01:22

コードを拝見する限り、なにかのフレームワークを使っていると思いますが、それを質問に記述し、場合によってはタグの変更を検討してください。 もし、フレームワークが関係のない問題であるならば、HTMLをフレームワークからの出力物に差し替えてください。
Lhankor_Mhy

2020/05/19 01:26 編集

「console.logで見ると」とのことですが、ご提示のコードにはありませんでした。 どの場所で何を見た結果か、ご提示いただけますか?
Lhankor_Mhy

2020/05/19 01:28

「投稿フォームをJQueryで複製して複数投稿をできる」とのことですが、私が見た限りご提示のコードではその部分が漏れているように感じられました。複製している部分をお示しください。
admj

2020/05/19 03:41

フレームワークの記述、console.logのコード、Jqueryでの複製コードを追記しました。
guest

回答3

0

とりあえず$(document).on("click", ".add", function () { の中でマップの定義をしていないので追加されたマップは動かないかもしれませんね。少なくともmapsにインスタンスは入っていないし、追加はできないでしょう。

投稿2020/05/19 08:33

kei344

総合スコア69606

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

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

0

自己解決

自身で色々調べて試していたら、ご返信がかなり遅くなってしまいました…すみません。
お二方のご回答を参考にして、フォームを複製した際にMapクラスのインスタンスを再作成することで解決できました!
ありがとうございました!

投稿2020/05/23 14:17

admj

総合スコア0

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

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

0

不明の部分が多いのでカンで答えますが。

html

1<input name="onclick" onclick='codeAddress("<%= j %>")' type="button", value="検索"></input>

とあり、

js

1function codeAddress(j){ //検索ボタンを押した時のコールバック関数 2//... 3 maps[j].setCenter(results[0].geometry.location); //検索値に最も近い結果の緯度・経度 4//... 5};

とあります。
ここで、jは必ず文字列ですが、mapsは配列ですから、添え字は数値である必要があります。
要素にアクセスできていないのではありませんか?

投稿2020/05/19 01:51

Lhankor_Mhy

総合スコア36960

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

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

admj

2020/05/19 03:48

ご回答ありがとうございます! 不明部分が多くすみません… 理解できなくて申し訳ないのですが、jにはHTML側で数値を定義しているため、数値を渡せていると考えているのですが、いかがでしょうか?
Lhankor_Mhy

2020/05/19 04:10

私はrailsについて素人なので逆に教えていただきたいのですが、 j = 0 の時に、 onclick='codeAddress("<%= j %>")' というテンプレートを展開すると、 onclick='codeAddress("0")' と出力されるのではないかと思うのですが、違うのですか?
admj

2020/05/19 04:34

仰る通りで、j=0の場合はonclick='codeAddress("0")'になります。 なので、maps[j]はmaps[0]となっていて数値を渡せていると思っているのですが…
Lhankor_Mhy

2020/05/19 04:48 編集

いえ、その場合、maps[j]はmaps["0"]になります。 JavaScriptでは、0 と "0" は別のものです。 Rubyでは数値と文字列の区別をしないのですか?
Lhankor_Mhy

2020/05/19 05:51

ちょっと調べてみました。 Rubyでは、添え字に整数以外の値を使うと、整数に暗黙の型変換をするようですね。 JavaScript では配列もオブジェクトのため、添え字の値が整数ではない場合、文字列などに暗黙の型変換をして、オブジェクトのアクセサとみなされます。つまり、arr["prop"] は、arr.prop と同義なんです。
admj

2020/05/19 07:24

理解不足で何度もすみません… maps[j]のjには整数が入っているのに、その整数に沿ってmapsの配列から地図を持って来れないのでしょうか? (j=0の場合、maps[0]、j=1の場合maps[1]を持ってくる等)
Lhankor_Mhy

2020/05/19 07:42

>maps[j]のjには整数が入っているのに、 jに整数が入っているなら、できます。 ですが、現在のコードではjには文字列が入っているはずなので、できません。
Lhankor_Mhy

2020/05/19 07:52

というか、コメントでできるできないを議論してても始まらないので、試してみた方が早いのではありませんか?
admj

2020/05/19 08:03

ありがとうございます! 試してはみたのですがうまくいかず、、、また自分で色々やってみます!
Lhankor_Mhy

2020/05/19 08:07

試してみた、というのは、 onclick='codeAddress("<%= j %>")' ↓ onclick='codeAddress(<%= j %>)' ですよね? 上手くいかないまでも、エラーメッセージの内容は変わりませんでしたか?
admj

2020/05/19 08:12

仰る通りです! そのようにやったのですが、同じエラーメッセージが出てしまってます。 (Cannot read property 'setCenter' of undefined)
Lhankor_Mhy

2020/05/19 08:25

うーん、そうすると、私が何か勘違いをしているのでしょうね…… お役に立てず申し訳ありません。
admj

2020/05/19 08:26

いえ、とんでもないです。 ご丁寧にありがとうございます!
Lhankor_Mhy

2020/05/19 08:30

あと、考えられそうなのは、フォームを複製した時にGoogleマップを作り直さず、maps を更新していないとか、その辺でしょうか……?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問