Reputation: 2127
I am using a Google Places autocomplete package with Meteor and if I have the user select a location in one template, the autocomplete won't work again in a different template.
For instance, if the user picks an autocomplete location for an event they are hosting, and then they try to set their profile location in the profile settings, no autocomplete locations pop up.
In fact, if they even activate the autocomplete dropdown on one page (without even selecting one of the options), it won't work on the other page.
Here's my HTML:
<template name="userUpdate">
<script>
window.onload = function() {
var autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')),{types: ['geocode'] }
);
};
</script>
<form class="main form" autocomplete="off">
<label class="control-label" for="location">Location</label>
<div class="controls">
<div id="locationField">
<input id="autocomplete" name="userLocation" class="form-control" autocomplete="off" placeholder="Where you live." type="text">
</div>
</div>
<p>
<h4 id="setLocation">{{currentUser.profile.location}}</h4>
<input id="updateUser" type="submit" class="btn btn-primary" value="Update Profile" />
</p>
</form>
</template>
Here is the second template:
<template name="postSubmit">
<form class="main form" autocomplete="off">
<div class="form-group">
<label class="control-label" for="title">Event Name</label>
<div class="controls">
<input name="title" id="title" type="text" value="" placeholder="Event name" class="form-control"/>
</div>
</div>
<div class="form-group">
<!--begin google test-->
<script>
window.onload = function() {
var autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocompleteEventPost')),{types: ['geocode'] }
);
};
</script>
<label class="control-label" for="location">Event Location</label>
<div class="controls">
<!--<input name="location" id="url" type="text" value="" placeholder="The location of the vent" class="form-control"/>-->
<div id="locationField">
<input id="autocompleteEventPost" name="location" autocomplete="off" placeholder="Event Location" type="text">
</div>
</div>
</div>
<input type="submit" value="Submit" class="btn btn-primary"/>
</form>
</template>
I have the mrt:googlemaps
package added, and I have set a googlePlaces.js like so:
GoogleMaps.init({
'sensor': true, //optional
'key': '***my api key***', //optional
'language': 'en', //optional
'libraries': 'places'
});
It is notable to state that although the autocomplete does not function again after a file update (with server restart), it will work again after a page refresh from the client.
Basically, I would like to see a perfect example of how to get this working in multiple templates in meteor.js.
Upvotes: 1
Views: 2744
Reputation: 1061
None of the other answers worked consistently for me so I'm calling initAutoComplete() when the text input is clicked and it works better for me.
Template.myTemplate.events({
'click #autocomplete': function(e,template) {
initAutoComplete();
}
});
var initAutoComplete = function() {
var autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')),{types: ['geocode'] }
);
};
Edit: Not working so great it turns out though, getting this from time to time:
Uncaught TypeError: Cannot read property 'Autocomplete' of undefined
Upvotes: 0
Reputation: 2127
Electric Jesus' answer is the answer that worked, HOWEVER: A variable must be declared for each element that is going to use the Google Places Autocomplete API.
His solution:
var initAutoComplete = function() {
var autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocompleteEventPost')),{types: ['geocode'] }
);
};
Template.userUpdate.rendered = initAutoComplete;
Template.postSubmit.rendered = initAutoComplete;
There are two separate input fields, one on each template. So, there must be a variable for each input field you want the Places Autocomplete API to work on. I changed the input element ID's back to "autocomplete"
. Here's my solution. Note the one-to-one ratio of variables to input fields.
var initAutoComplete = function() {
var autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')),{types: ['geocode'] }
);
};
var initAutoCompletePost = function() {
var autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')),{types: ['geocode'] }
);
};
Template.userUpdate.rendered = initAutoComplete;
Template.postSubmit.rendered = initAutoCompletePost;
For others who use this solution, in my working implementation, I have removed the <script>
tags from my HTML (there is no more javascript in my templates).
Upvotes: 1
Reputation: 4486
The thing is with Google Maps is once you initialize, it only attaches itself on that current DOM instance. When you switch to another page/template, Gmaps seems to lose touch of those bindings you just created and you will have to reinitialize properly.
And you're using window.onload
.. that only runs once..
Take a look at moving the <script>
code found inside your templates to the rendered
template event(s):
var initAutoComplete = function() {
var autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocompleteEventPost')),{types: ['geocode'] }
);
};
Template.userUpdate.rendered = initAutoComplete;
Template.postSubmit.rendered = initAutoComplete;
Make sure you get the timings right though.. GoogleMaps API is async after all and may even mess up with this kind of initialization. One thing you could do to avoid this is to wrap the above code in the GoogleMaps.init
callback.
Upvotes: 1
Reputation: 1881
My guess is you should probably change it to class="autocomplete"
, id shouldn't have duplicate, so document.getElementById('autocomplete')
will always return first element it finds. Never worked with google-maps tho, but I think this can be the reason
Upvotes: 0