# Terminal rails g scaffold locations title latitude:decimal longitude:decimal rails webpacker:set up:stimulus
# layouts/utility.html.erb <%= javascript_include_tag "https://maps.googleapis.com/maps/api/js?key=#{ENV['MAPS_API_KEY']}&libraries=locations&callback=dispatchMapsEvent", async: true, defer: true, "data-turbolinks-eval": false %>
# packs/utility.js window.dispatchMapsEvent = perform (...args) { const occasion = doc.createEvent("Occasions") occasion.initEvent("google-maps-callback", true, true) occasion.args = args window.dispatchEvent(occasion) }
# javascript/controllers/maps_controller.js import { Controller} from "stimulus" export default class extends Controller { static targets = ["field", "map", "latitude", "longitude"] join() { if (typeof (google) != "undefined"){ this.initializeMap() } } initializeMap() { this.map() this.marker() this.autocomplete() console.log('init') } map() { if(this._map == undefined) { this._map = new google.maps.Map(this.mapTarget, { middle: new google.maps.LatLng( this.latitudeTarget.worth, this.longitudeTarget.worth ), zoom: 17 }) } return this._map } marker() { if (this._marker == undefined) { this._marker = new google.maps.Marker({ map: this.map(), anchorPoint: new google.maps.Level(0,0) }) let mapLocation = { lat: parseFloat(this.latitudeTarget.worth), lng: parseFloat(this.longitudeTarget.worth) } this._marker.setPosition(mapLocation) this._marker.setVisible(true) } return this._marker } autocomplete() { if (this._autocomplete == undefined) { this._autocomplete = new google.maps.locations.Autocomplete(this.fieldTarget) this._autocomplete.bindTo('bounds', this.map()) this._autocomplete.setFields(['address_components', 'geometry', 'icon', 'name']) this._autocomplete.addListener('place_changed', this.locationChanged.bind(this)) } return this._autocomplete } locationChanged() { let place = this.autocomplete().getPlace() if (!place.geometry) { // Consumer entered the title of a Place that was not urged and // pressed the Enter key, or the Place Particulars request failed. window.alert("No particulars out there for enter: '" + place.title + "'"); return; } this.map().fitBounds(place.geometry.viewport) this.map().setCenter(place.geometry.location) this.marker().setPosition(place.geometry.location) this.marker().setVisible(true) this.latitudeTarget.worth = place.geometry.location.lat() this.longitudeTarget.worth = place.geometry.location.lng() } preventSubmit(e) { if (e.key == "Enter") { e.preventDefault() } } }
# views/locations/_form.html.erb <%= form_with mannequin: place, native: true, knowledge: { controller: :maps, motion: "[email protected]>maps#initializeMap" } do |kind| %> <div class="area"> <%= kind.label :title %> <%= kind.text_field :title, class: 'form-control' %> </div> <div class="area"> <%= kind.label :search %> <%= kind.search_field :search, title: nil, class: 'form-control', knowledge: { goal: "maps.area", motion: "keydown->maps#preventSubmit" } %> </div> <div class="area"> <%= kind.label :latitude %> <%= kind.text_field :latitude, class: 'form-control', knowledge: { goal: "maps.latitude" } %> </div> <div class="area"> <%= kind.label :longitude %> <%= kind.text_field :longitude, class: 'form-control', knowledge: { goal: "maps.longitude" } %> </div> <%= content_tag :div, nil, knowledge: { goal: "maps.map" }, class: 'map' %> <div class="actions"> <%= kind.submit class: 'btn btn-primary' %> </div> <% finish %>
# stylesheets/locations.scss .map { width: 100%; min-height: 400px; }
# views/locations/present.html.erb <%= image_tag "https://maps.googleapis.com/maps/api/staticmap?zoom=15&dimension=400x300&middle=#{@place.latitude},#{@place.longitude}&key=#{ENV['MAPS_API_KEY']}", alt: "Map" %>