作成した記事内に住所が記載されている場合には、その住所にピンを立ててGoogleMapを表示する機能を実装しました。
ページ内でいくつのGoogle Mapが表示されるかわからないので動的に対応できる必要があります。
#前提
- Google Maps Javascript APIを使用できる状態にある
#環境
Ruby 2.6.3
Rails 5.1.7
#実際のコード
<li id="article-<%= article.id %>">
<% if article.address.present? %>
<div>
<span>
住所:<span id="address-<%= article.id %>"><%= article.address %></span>
</span>
</div>
<div id='map-<%= article.id %>'>
</div>
<script>
$(document).on('turbolinks:load', function() {
const geocoder = new google.maps.Geocoder();
const map = new google.maps.Map(document.getElementById('map-<%= article.id %>'), {
center: {lat: -34.397, lng: 150.644}, //任意の値
zoom: 12 //任意の値
});
const inputAddress = document.getElementById('address-<%= article.id %>').textContent;
geocoder.geocode( { 'address': inputAddress}, function(results, status) {
if (status == 'OK') {
map.setCenter(results[0].geometry.location);
const marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
});
</script>
<% end %>
</li>
div[id^="map-"]{
height: 300px; //任意の値
}
<html>
<head>
...
</head>
<body>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
<%= yield %>
</body>
</html>
#ポイント
##1. Google Mapや住所に一意のidを割り当てる
・_article.html.erb 8行目
<div id='map-<%= article.id %>'>
各Mapに一意のidを割り当てるために、記事のidを付随させました。
そしてそのidに対応するMapを作成します。
・_article.html.erb 14〜17行目
const map = new google.maps.Map(document.getElementById('map-<%= article.id %>'), {
center: {lat: -34.397, lng: 150.644}, //任意の値
zoom: 12 //任意の値
});
同様に、記事の住所にも一意のidを付与し、その文字列を取得できるようにしています。
また、それらのidに対してそれぞれstyle(heightやwidth等)を適用させる必要があります。
調べてみると、cssでは前方一致等、簡単な正規表現が使用できるそうなので以下の設定としました。
div[id^="map-"]{
height: 300px; //任意の値
}
id^="map-" とすることで、"map-"から始まる任意のid(例:map-1, map-hoge等)が付与されたdivタグに対しstyleを適用できます。
参考:
CSSでセレクターに正規表現を使うには?コード例で解説
##2. GoogleMapsAPIを使用するためのスクリプトをMap生成コードより手前に置く
・application.html.erb 5〜8行目
<body>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
<%= yield %>
</body>
ページ内で表示させるMapが1つである場合等は、scriptのsrcにコールバック関数を指定して実行するのが一般的なようです。
その場合はMapsAPIを使用するためのスクリプトをMap生成コードの下に置くことになると思いますが、今回のように、ある条件下ではMapが生成されるような、動的に表示数が変化する場合は1つのコールバック関数では対応できないのでMap生成コードより手前で、あらかじめGoogleMapsAPIを使用できる状態にしておきます。
##3. ページ読み込み時にMap生成を実行する
コールバック関数は使わないので、代わりに以下関数でページが読み込まれたら(turbolinksがロードされたら)即実行されるようにします。
$(document).on('turbolinks:load', function() {
//処理内容
});
#終わりに
最後までお読みくださりありがとうございました。
どなたかの参考になれば幸いです。