I am using laravel livewire for my website and on that web, I created a multi-step form where I have to fetch google maps API in the first step. as I know I have to use wire: ignore when using third-party JavaScript library in Livewire component. but the problem comes when I switch from form step 2 to step 1, where google Maps is not rendered.
This is my livewire view.
<div wire:ignore>
<div id="address-map-container" class="mt-2" style="width:100%;height:320px; ">
<div style="width: 100%; height: 100%" id="address-map"></div>
</div>
</div>
<!-- End Google Maps -->
<!-- Seach in google maps -->
<input type="text" wire:model.lazy="address_address" id="address-input"
class="mt-4 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md map-input"
placeholder="Search in Google Maps">
<input type="hidden" wire:model.lazy="address_latitude" id="address-latitude" value="0" />
<input type="hidden" wire:model.lazy="address_longitude" id="address-longitude" value="0" />
<!-- End in Seach google maps -->
This is my javascript code.
<script>
function initialize() {
$('form').on('keyup keypress', function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode === 13) {
e.preventDefault();
return false;
}
});
const locationInputs = document.getElementsByClassName("map-input");
const autocompletes = [];
const geocoder = new google.maps.Geocoder;
for (let i = 0; i < locationInputs.length; i++) {
const input = locationInputs[i];
const fieldKey = input.id.replace("-input", "");
const isEdit = document.getElementById(fieldKey + "-latitude").value != '' && document.getElementById(fieldKey + "-longitude").value != '';
const latitude = parseFloat(document.getElementById(fieldKey + "-latitude").value) || -6.251855;
const longitude = parseFloat(document.getElementById(fieldKey + "-longitude").value) || 106.978942;
const map = new google.maps.Map(document.getElementById(fieldKey + '-map'), {
center: {lat: latitude, lng: longitude},
zoom: 15
});
const marker = new google.maps.Marker({
map: map,
position: {lat: latitude, lng: longitude},
});
marker.setVisible(isEdit);
const autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.key = fieldKey;
autocompletes.push({input: input, map: map, marker: marker, autocomplete: autocomplete});
}
for (let i = 0; i < autocompletes.length; i++) {
const input = autocompletes[i].input;
const autocomplete = autocompletes[i].autocomplete;
const map = autocompletes[i].map;
const marker = autocompletes[i].marker;
google.maps.event.addListener(autocomplete, 'place_changed', function () {
marker.setVisible(false);
const place = autocomplete.getPlace();
geocoder.geocode({'placeId': place.place_id}, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
const lat = results[0].geometry.location.lat();
const lng = results[0].geometry.location.lng();
setLocationCoordinates(autocomplete.key, lat, lng);
}
});
if (!place.geometry) {
window.alert("No details available for input: '" + place.name + "'");
input.value = "";
return;
}
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17);
}
marker.setPosition(place.geometry.location);
marker.setVisible(true);
});
}
}
function setLocationCoordinates(key, lat, lng) {
const latitudeField = document.getElementById(key + "-" + "latitude");
const longitudeField = document.getElementById(key + "-" + "longitude");
latitudeField.value = lat;
longitudeField.value = lng;
Livewire.emit('lat')
}
</script>
And this is my livewire controller
// Form properties
public $currentPage = 1;
public $property_name;
public $address_address;
public $postal_code;
public $property_phone_number;
public $number_of_rooms;
public $pages = [
1 => [
'heading' => 'General Information',
'subheading' => 'Enter',
],
2 => [
'heading' => 'Property Detail',
'subheading' => 'Enter',
],
];
private $validationRules = [
1 => [
'property_name' => ['required', 'min:3'],
'address_address' => ['required', 'min:3'],
'postal_code' => ['required', 'min:3'],
'property_phone_number' => ['required', 'min:3'],
'number_of_rooms' => ['required'],
],
2 => [
'password' => ['required', 'string', 'min:8'],
'confirmPassword' => ['required', 'string', 'same:password', 'min:8'],
],
];
public function updated($propertyName)
{
$this->validateOnly($propertyName, $this->validationRules[$this->currentPage]);
}
public function goToNextPage()
{
$this->currentPage++;
}
public function goToPreviousPage()
{
$this->currentPage--;
}
Can someone help me how to emit the google maps API and listen to it in JavaScript, therefore, google maps will always be rendered? Thanks
My livewire version : v2.4.3