Ruby on Rails 7中Google Maps Places经纬度无法填充表单
问题:Rails 7 + Google Places Autocomplete 无法填充经纬度字段
我有一个Ruby on Rails 7应用,用Google Maps Places Autocomplete API自动填充表单里的酒吧名称、地址、网站等字段,之前运行正常。现在想添加纬度(lat)和经度(lng)字段到表单,保存到数据库后在站点其他地方显示地图标记,但经纬度就是填不到表单里。我已经加了文本字段用来测试(生产环境会改成隐藏字段),控制台里能看到Google Places返回了经纬度数据,但就是没法填充到表单。
相关代码
1. Stimulus控制器 /app/javascript/controllers/places_controller.js
import { Controller } from "@hotwired/stimulus"; export default class extends Controller { static targets = [ "field" ] connect() { if (typeof(google) != "undefined") { this.initPlaces() } } initPlaces() { this.autocomplete = new google.maps.places.Autocomplete(this.fieldTarget) this.autocomplete.setFields(['address_components', 'geometry', 'website', 'name']) this.autocomplete.addListener('place_changed', this.fillInAddress.bind(this)) } placeChanged() { let place = this.autocomplete.getPlace() if (!place.geometry) { window.alert(`No details available for input: ${place.name}`) return } } keydown(event) { if (event.key == "Enter") { event.preventDefault() } } fillInAddress() { const place = this.autocomplete.getPlace(); console.log("Place selected:", place); if (place.geometry && place.geometry.location) { const lat = place.geometry.location.lat(); const lng = place.geometry.location.lng(); console.log("Latitude before setting field:", lat); console.log("Longitude before setting field:", lng); document.querySelector("#bar_info_latitude").value = lat; document.querySelector("#bar_info_longitude").value = lng; console.log("Latitude after setting field:", document.querySelector("#bar_info_latitude").value); console.log("Longitude after setting field:", document.querySelector("#bar_info_longitude").value); } else { console.log("Selected place does not have geometry or location"); } let bar_info_addressline1 = ""; document.querySelector("#bar_info_barname").value = place.name document.querySelector("#bar_info_website").value = place.website for (const component of place.address_components) { const componentType = component.types[0]; switch (componentType) { case "street_number": { bar_info_addressline1 = `${component.long_name} ${bar_info_addressline1}`; break; } case "route": { bar_info_addressline1 += component.short_name; break; } case "postal_code": { document.querySelector("#bar_info_zip").value = component.long_name; break; } case "locality": document.querySelector("#bar_info_city").value = component.long_name; break; case "administrative_area_level_1": { document.querySelector("#bar_info_state").value = component.short_name; break; } } } document.querySelector("#bar_info_addressline1").value = bar_info_addressline1; document.querySelector("#bar_info_addressline2").focus(); } }
2. 表单部分代码 _form.html.erb
<div class="row"> <div class="col-md 6"> <%= form_with(model: @bar_info, local: true, data: { controller: "places" }) do |f| %> <%= render 'shared/error_messages', object: f.object %> <%= f.label "Bar Name (required)" %> <%= f.text_field :barname, placeholder: "Bar name here", class: "form-control", size: "70x1", data: { places_target: "field", action: "keydown->places#keydown" } %> <% if is_an_admin? || cmdr_user? %> <!-- Only admin and cmdr_user gets to use autocomplete feature, to save on google cloud costs --> <div class="form-group"> <%= f.label :address %> <%= f.text_field :addressline1, class: 'form-control' %> <%= f.label "Address Line 2" %> <%= f.text_field :addressline2, placeholder: "Street Address 2", class: "form-control", size: "70x1" %> <% end %> <%= f.label "City (required)" %> <%= f.text_field :city, placeholder: "City", class: "form-control", size: "70x1" %> <%= f.label "State (required)" %> <%= f.text_field :state, placeholder: "State", class: "form-control" %> <% if is_an_admin? || cmdr_user? %> <%= f.label :zip %> <%= f.text_field :zip, placeholder: "Postal Code", class: "form-control", size: "70x1" %> <% end %> <p class="mt-2">Not required, but would love to have the information below too!</p> <%= f.label :website %> <%= f.url_field :website, placeholder: "https://www.example.com", class: "form-control" %> <%= f.label :instagram %> <div class="input-group mb-3"> <span class="input-group-text" id="basic-addon1">@</span> <%= f.text_field :instagram, placeholder: "username", class: "form-control" %> </div> <br> <%= f.text_field :latitude %> <%= f.text_field :longitude %> </div> <% if is_an_admin? || cmdr_user? %> <span class="image"> <p>Upload an image of Bar here!</p> <%= f.file_field :image, accept: "image/jpeg,image/gif,image/png", data: { controller: "image-upload", image_upload_target: "image", action: "change->image-upload#checkSize" }, class: "form-control mb-3", id: "formFile" %> </span> <% end %> <%= f.submit "Submit", class: "btn btn-primary" %> <% end %> </div> </div>
3. 经纬度字段的HTML输出
<input type="text" name="bar_info[latitude]" id="bar_info_latitude"> <input type="text" name="bar_info[longitude]" id="bar_info_longitude">
4. Google Places API返回的经纬度数据
"geometry" : { "location" : { "lat" : 34.0532482, "lng" : -118.2505517 },
已确认的情况
- 控制台能看到API返回了正确的经纬度数据
- 表单其他字段(名称、地址、网站等)均可正常自动填充
- JS中使用的选择器与经纬度字段的ID完全匹配
内容的提问来源于stack exchange,提问作者Splohr
相关产品推荐
相关产品推荐

