こんにちは。
Google Map APIを使って地図上のピンをクリックすると発火するイベントをHotwireで拾う方法を紹介します。
イメージが掴みにくいと思うので、まずは完成形を見てみましょう。
https://www.value-hoiku.jp/recruitments/map
このような形で、地図上のピンをクリックすると、ピンに紐づく情報を表示するような仕組みです。
1. Google Map APIの準備
まずは、Google Map APIを使えるようにします。
Google Map APIの使い方は、こちらの記事を参考にしてください。
上記の記事では、Google Map APIのAPIキーを環境変数に設定する方法を紹介しています。
2. Map IDの準備
Google Map APIを使うには、Map IDが必要になります。
Map IDは、Google Cloud Platformのコンソールから取得することができます。
以下のURLにアクセスして、Map IDを取得してください。
https://console.cloud.google.com/google/maps-apis/studio/maps
MapIDが取得できたら、credentialに登録しておきましょう。
以降、Rails.application.credentials.dig(:gcp, :map_id)
でMap IDを取得できるものとします。
3. viewファイルの準備
先ほど作成したAPIを使って、viewファイルを作成します。
= javascript_include_tag "https://maps.googleapis.com/maps/api/js?key=#{Rails.application.credentials.dig(:gcp, :maps_platform_api_key)}&callback=initMap&libraries=marker&v=beta", "data-turbo-track": "reload", defer: true
= javascript_include_tag 'map', "data-turbo-track": "reload", defer: true
= hidden_field_tag :lat, @lat || 35.681236
= hidden_field_tag :lng, @lng || 139.767125
= hidden_field_tag :map_id, Rails.application.credentials.dig(:gcp, :map_id)
#map.w-full.h-full
= turbo_frame_tag "modal"
let map;
function initMap() {
const lat = document.getElementById("lat").value;
const lng = document.getElementById("lng").value;
const mapId = document.getElementById("map_id").value;
map = new google.maps.Map(document.getElementById("map"), {
zoom: 12,
center: new google.maps.LatLng(lat, lng),
mapId: mapId,
});
const fetchJson = async () => {
const response = await fetch('/api/v1/addresses.json'); // addressの一覧を取得するAPI、lat, lngを含む
const data = await response.json();
return data;
};
fetchJson().then(data => {
eqfeed_callback(data);
});
}
// Loop through the results array and place a marker for each
// set of coordinates.
const eqfeed_callback = function (addresses) {
const element = document.querySelector('#modal')
addresses.forEach (function (address) {
const latLng = new google.maps.LatLng(address.latitude, address.longitude);
const pinViewBackground = new google.maps.marker.PinView({
scale: 1.1,
glyphColor: "white",
});
const marker = new google.maps.marker.AdvancedMarkerView({
position: latLng,
map: map,
title: address.name,
content: pinViewBackground.element,
});
marker.addListener("click", ({ domEvent, latLng }) => {
const { target } = domEvent;
element.src = `/addresses/${address.id}`;
});
});
};
window.initMap = initMap;
window.eqfeed_callback = eqfeed_callback;
上記で、Google Map APIで表示したピンに対して、クリックイベントを設定しています。
今回はクリックイベントとして、turbo_frame_tagを使って、/addresses/${address.id}
を表示するようにしています。
routes.rbやcontroller, viewは各自で作成してください。
今回はこのあたりで。