This is the code I am working from:
http://jsfiddle.net/DYfbg/12/
If you click "map" then try typing a placename it gives you autocomplete suggestions. Then if you click on one of these suggestions it tells you the co-ordinates in an alert box.
What I want to do is capture what is in the input box when the autocomplete option is clicked, and then store it as a variable. Then in the alert box, along with the co-ordinates, I want to print the input box variable into it.
I know this all sounds pretty simple but I am new to javascript so I would really appreciate some input.
This is the segment of code:
google.maps.event.addListener(autocomplete, 'place_changed', function() {
var place = autocomplete.getPlace();
**// Store input box as variable**
if (!place.geometry) {
current_place = null;
alert('Cannot find place');
return;
} else {
current_place = place;
alert('Place is at:' + place.geometry.location);
**// Print input box varaible aswell**
} });
EDIT: This is as close as I could get without getting stuck:
// Set Autocomplete Location Variable equal to #loc input
$("#loc").val(ac_location);
// Print Autocomplete Variable
alert(ac_location);
In the "place" object returned with
var place = autocomplete.getPlace();
you have all info you need
Add a console.log and you'll see all infos returned.
For example:
var place = autocomplete.getPlace();
console.log(place);
window.myGlobalVar = place.name;
Edit based on notes below:
it seems original value of inputbox is actually stored in this property:
autocomplete.gm_accessors_.place.lf.d
Related
Hi I just wondering if i can get some pointers with my code, I am trying to capture and save the input value of a textarea. I am fairly new to JavaScript and I have been wrecking my brain trying to figure it out. My issue is regarding the saveEntry() function, which isn't complete I have only posted how my code is right now, and isn't causing errors/unwanted effects. Any tips or hints would be fantastic, as I keep getting errors
function addTextEntry(key, text, isNewEntry) {
// Create a textarea element to edit the entry
var textareaElement = document.createElement("textarea");
textareaElement.rows = 5;
textareaElement.placeholder = "(new entry)";
// Set the textarea's value to the given text (if any)
textareaElement.value = text;
// Add a section to the page containing the textarea
addSection(key, textareaElement);
// If this is a new entry (added by the user clicking a button)
// move the focus to the textarea to encourage typing
if (isNewEntry) {
textareaElement.focus();
}
// Create an event listener to save the entry when it changes
// (i.e. when the user types into the textarea)
function saveEntry() {
// Save the text entry:
// ...get the textarea element's current value
var currentValue = document.getElementById('textarea').value;
// ...make a text item using the value
// ...store the item in local storage using the given key
localstroage.setItem(key, item);
}
// Connect the saveEntry event listener to the textarea element 'change' event
textareaElement.addEventListener("change", saveEntry());
}
function addImageEntry(key, url) {
// Create a image element
var imgElement = new Image();
imgElement.alt = "Photo entry";
// Load the image
imgElement.src = url;
// Add a section to the page containing the image
addSection(key, imgElement);
}
/**
* Function to handle Add text button 'click' event
*/
function addEntryClick() {
// Add an empty text entry, using the current timestamp to make a key
var key = "diary" + Date.now();
var text = "";
var isNewEntry = true;
addTextEntry(key, text, isNewEntry);
I was told to utilise something similar to this code below, but not exactly the same as I need to capture the data value of the user input text, not pre-created data.
function createDemoItems() {
console.log("Adding demonstration items to local storage");
var item, data, key;
// Make a demo text item
data =
"Friday: We arrived to this wonderful guesthouse after a pleasant journey " +
"and were made most welcome by the proprietor, Mike. Looking forward to " +
"exploring the area tomorrow.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000001";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo text item
data =
"Saturday: After a super breakfast, we took advantage of one of the many " +
"signed walks nearby. For some of the journey this followed the path of a " +
"stream to a charming village.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000002";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo image item
data = window.DUMMY_DATA_URL;
item = makeItem("image", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000003";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo text item
data =
"Sunday: Following a tip from Mike we drove to a gastropub at the head of " +
"the valley - a great meal and fabulous views all round.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000004";
// Store the item in local storage
localStorage.setItem(key, item);
}
You are very close, you just have to make some adjustments here and there!
Just as a disclaimer, I had to re-create your addSection() function, in order to have it properly working. If you already had one, you could discard mine
When we create a new entry, in order to make it distinguishable, I have assigned it the id of the key. Before, you were trying to call getElemenyById("textarea"), but no element had id textarea, which is in fact the tag name of the textarea element that you created. Read more about getElementByTagName if you want.
I have changed the way the event listener is set to:
textareaElement.addEventListener(
'input',
function () { saveEntry(); },
false
);
The difference between change and input are that change will fire only when you are done with the changes and click outside of the textarea, whilst input will fire everytime that you input something. Now you know, so of course, feel free to change it to what you would like it to behave.
Lastly, I have made the just-created item to be retrieved immediately and logged to console. This will be useful just for testing, you can comment out those lines when you are happy.
Beware that the snippet below is playable, but it won't actually save data to LocalStorage because of SO limitations, so you won't be able to fully test it on this page.
function addSection(key, element) {
element.id = key;
var test = document.querySelector("#test");
test.appendChild(element);
}
function addTextEntry(key, text, isNewEntry) {
// Create an event listener to save the entry when it changes
// (i.e. when the user types into the textarea)
function saveEntry() {
// Save the text entry:
// ...get the textarea element's current value
var currentValue = document.getElementById(key).value;
// ...store the item in local storage using the given key
localStorage.setItem(key, currentValue);
//Testing if we can retrieve the item, comment out when you're happy
var item = localStorage.getItem(key);
console.log(item);
}
// Create a textarea element to edit the entry
var textareaElement = document.createElement("textarea");
textareaElement.rows = 5;
textareaElement.placeholder = "(new entry)";
// Set the textarea's value to the given text (if any)
textareaElement.value = text;
// Add a section to the page containing the textarea
addSection(key, textareaElement);
// If this is a new entry (added by the user clicking a button)
// move the focus to the textarea to encourage typing
if (isNewEntry) {
textareaElement.focus();
}
textareaElement.addEventListener(
'input',
function () { saveEntry(); },
false
);
// Connect the saveEntry event listener to the textarea element 'change' event
//textareaElement.addEventListener("change", saveEntry());
}
function addImageEntry(key, url) {
// Create a image element
var imgElement = new Image();
imgElement.alt = "Photo entry";
// Load the image
imgElement.src = url;
// Add a section to the page containing the image
addSection(key, imgElement);
}
/**
* Function to handle Add text button 'click' event
*/
function addEntryClick() {
// Add an empty text entry, using the current timestamp to make a key
var key = "diary" + Date.now();
var text = "";
var isNewEntry = true;
addTextEntry(key, text, isNewEntry);
}
window.onload = () => addEntryClick();
<html>
<head>
</head>
<body>
<div id="test"></div>
</body>
</html>
There are a number of things wrong with the way you're doing things, but you know that: that's why you're here!
You have a typo: localstroage should be localStorage
You create a text area but don't give it an ID. In your saveData function you attempt to find it, but you're searching for it by tag name. There's no need to search: your event handler will already have this set to the element.
In your event handler you refer to your function as saveData(). This will invoke the function immediately and assign its return value as an event handler. Just pass the function name.
Here's a demonstration of concept for you:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Explore local storage</title>
</head>
<body>
<textarea id="txt" placeholder="Enter text and press TAB"></textarea>
<script>
"use strict";
let txtKey = "someKey"
// Save the data. No need to search for the text area:
// the special value 'this' is already set to it.
function saveEntry() {
localStorage.setItem(txtKey, this.value);
}
// Look fr the previous text and if it exists, put it in the textarea
let storedText = localStorage.getItem(txtKey);
if (storedText) {
document.getElementById('txt').value = storedText;
}
// Now add the event listener.
tArea.addEventListener('change', saveEntry); // Pass just the function name
</script>
</body>
</html>
This code uses a hard-coded value for txtKey. Your code might need to generate and track some value for the key, otherwise you risk overwriting earlier data with later data.
I am using the Google Maps' Places API for autocompletion of location as user types. But how can I restrict the suggestions to a particular country?
Here is my javascript:
function initAutocomplete() {
// Create the search box and link it to the UI element.
var input = document.getElementById('autocomplete-input');
var searchBox = new google.maps.places.SearchBox(input);
// [START region_getplaces]
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
});
}
Fixed it by changing SearchBox to Autocomplete and passing an options with the requirements..Here is the code if someone needs.
function initAutocomplete() {
// Create the search box and link it to the UI element.
var input = document.getElementById('autocomplete-input');
var options = {
componentRestrictions: {country: 'fr'}
};
var searchBox = new google.maps.places.Autocomplete(input, options);
// [START region_getplaces]
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
});
}
Note: I'm using Google Maps API v3 (v3.30.13)
#Abhilash's approach to the problem was nice to try with. But with his answer, I faced a problem: the autocomplete was working fine, but it didn't triggering the places_changed method. And there's no console error too.
Then with the answer by #geocodezip in another thread, I figured out that, the event fired up with Autocomplete is not places_changed, but place_changed (note the difference of singular form).
And there are other changes required if you want to proceed with place_changed, because with place_changed it return only a single place, not an array of places. So:
instead of .getPlaces() you have to use .getPlace()
instead of places.forEach(function(place) { ... } you have to work with place directly.
var input = document.getElementById('pac-input');
var restrictOptions = {
componentRestrictions: {country: 'bd'}
};
var searchBox = new google.maps.places.Autocomplete(input, restrictOptions);
searchBox.addListener('place_changed', function() {
var place = searchBox.getPlace();
if (place.length == 0) {
return;
}
if (!place.geometry) {
console.log("No details available for input: '" + place.name + "'");
return;
}
// ...
});
Caveat
The limitation is: with .SearchBox() google places search work even with random string, but with .Autocomplete() random string cannot find out any .geometry, hence cannot pinpoint to any matched area on the map. With .SearchBox() if you type "Name of a place", hit enter, it can point to Placename, Locality. But with .Autocomplete() without choosing from the autosuggestion[s] it cannot trigger the place's .geometry. The following console.log(place) displays the difference between random string and autocomplete chosen item:
Aftermath
I's not satisfied with the outcome how .Autocomplete() worked for me. So until having a nicer solution, I decided to stick to the .SearchBox() method - though it's not restricting the search suggestions. But binding with bounds_changed it binds the search result a little bit, though it's not strict and satisfactory, but at least something's better than nothing. ¯\_(ツ)_/¯
// Bias the SearchBox results towards current map's viewport.
front_end_map.addListener('bounds_changed', function() {
searchBox.setBounds(front_end_map.getBounds());
});
I, desperately am, looking forward for a bulletproof solution...
This question already has answers here:
Google Maps API: How do you ensure that the Google Maps Autocomplete text is an actual address before submitting? [duplicate]
(2 answers)
Closed 2 years ago.
I am using Google Maps API and the Autocomplete search feature. Currently, you must begin typing a location(city, state, zip, etc.) and then select a result from the dropdown for the map to center at that location. However, I would like to make this fool proof and set it up so that if someone types just a city or just a state and hits "enter" without selecting an Autocomplete result, it will still work. For instance, if someone types "New York" and hits "enter" without selecting a result in the dropdown, it will still center on New York.
I'm assuming this is accomplished by grabbing the first result from the Autocomplete dropdown if one is not selected manually.
I've added an event listener for the submission of the form, but not sure how to pass the first result into the "place" variable.
Here is my code:
function searchBar(map) {
var input = document.getElementById('search-input');
var searchform = document.getElementById('search-form');
var place;
var options = {componentRestrictions: {country: 'us'}};
var autocomplete = new google.maps.places.Autocomplete(input, options);
//Add listener to detect autocomplete selection
google.maps.event.addListener(autocomplete, 'place_changed', function () {
place = autocomplete.getPlace();
center = new google.maps.LatLng(place.geometry.location.lat(),place.geometry.location.lng());
map.setCenter(center);
map.setZoom(5);
});
//Add listener to search
searchform.addEventListener('submit', function() {
center = new google.maps.LatLng(place.geometry.location.lat(),place.geometry.location.lng());
map.setCenter(center);
map.setZoom(5);
});
//Reset the inpout box on click
input.addEventListener('click', function(){
input.value = "";
});
};
And here is a JSFiddle for experimentation.
There is no implemented way to access the places in the dropdown. Basically what you see in the dropdown are not places, there are only predictions. The details for a prediction will be loaded when you select a prediction.
So you must select a prediction programmatically.
How to achieve it:
Another way than clicking on a prediction is to use the down-key, the keycode is 40. The API listens to keydown-events of the input.
So when you hit enter:
trigger keydown with a keycode 40(down)
trigger keydown with a keycode 13(enter)
google.maps.event.addDomListener(input,'keydown',function(e){
if(e.keyCode===13 && !e.triggered){
google.maps.event.trigger(this,'keydown',{keyCode:40})
google.maps.event.trigger(this,'keydown',{keyCode:13,triggered:true})
}
});
Note: to avoid a infinite loop for the enter I've added a custom property triggered, so I'm able to bypass the triggered keydown inside the function.
Demo: http://jsfiddle.net/4nr4tdwz/1/
I added a filter to avoid keydown being triggered when user has already select any result from the autocomplete:
google.maps.event.addDomListener(input,'keydown',function(e){
if(e.keyCode===13 && $('.pac-item-selected').length == 0 && !e.triggered){
google.maps.event.trigger(this,'keydown',{keyCode:40})
google.maps.event.trigger(this,'keydown',{keyCode:13,triggered:true})
}
});
Helper function for setting initial/default location programmatically - e.g. from geolocation API.
var triggerLocation = function(autocompleteInput, addressString) {
var $locationInput = $(autocompleteInput).val(addressString).trigger('focus');
var maxTries = 500;
var autocompleteSelectionInterval = setInterval(function() {
if (!--maxTries) {
clearInterval(autocompleteSelectionInterval);
}
if ($('.pac-container .pac-item').length) {
google.maps.event.trigger($locationInput[0], 'keydown', {
keyCode : 40
});
google.maps.event.trigger($locationInput[0], 'keydown', {
keyCode : 13
});
clearInterval(autocompleteSelectionInterval);
}
}, 10);
};
Example:
var autocomplete = new google.maps.places.Autocomplete($('#location')[0]);
triggerLocation('#location', 'New York');
I am loading markers from a database to display on a google map by this below. This is working fine however, I would like to implement the option of pressing a particular button somewhere else on the page, and then map would dynamically change to only show markers pertaining to what was clicked.
Basically, I would like to filter by the 'type' column in my database but still keep all types loaing by default. eg. Page loads, Map loads and displays all types, User clicks on a button which causes the map to only show markers that have type1 as the value in the db. Kind of like a toggle with a check box.
Any ideas of how to go ahead with this, I don't think reloading markers from the db is the most efficient way, can I simply just hide markers which have this property?
map = new google.maps.Map(document.getElementById("google_map"), googleMapOptions);
//Load Markers from the XML File, Check (map_process.php)
$.get("map_process.php", function (data) {
$(data).find("marker").each(function () {
var name = $(this).attr('name');
var address = '<p>'+ $(this).attr('address') +'</p>';
var type = $(this).attr('type');
var description ='<p>'+ $(this).attr('description') +'</p>';
var point = new google.maps.LatLng(parseFloat($(this).attr('lat')),parseFloat($(this).attr('lng')));
var icon1 = customIcons[type] || {};
create_marker(point, name, address, false, false, false, icon1.icon);//"http://sanwebe.com/assets/google-map-save-markers-db/icons/pin_blue.png");
});
});
You can't just hide some specific markers according to their tag or type, you have to hide/remove them all first and then add those that you need on your map
Here are the functions that you need:
var all_markers = [];
var show_markers = [];
function setMarkers(map) {
for (var i = 0; i < show_markers.length; i++) {
show_markers[i].setMap(map);
}
}
function showMarkers(type) {
setMarkers(null);
show_markers = []
for (var i = 0; i < all_markers.length; i++) {
if (all_markers[i].type == type){
show_markers.push(all_markers[i])
}
}
setMarkers(map);
}
Here is the idea: Load all your markers into the all_markers, on your first loading the markers show_markers must be equal to all_markers. Hitting the button for showing specific markers must trigger function showMarkers which will clear your map and reload just specific ones.
I am making a form with yandex maps integration. I need the value of input to be changed after user picks some point on map. Here is code:
function setPlace(c){
//c - coordinates
var geocoder = ymaps.geocode(c, {kind: "locality"});
geocoder.then(function(res){
var city = res.geoObjects.get(0).properties.get("name");
var inpCity = document.getElementById(idCity);
inpCity.value = city;
});
}
So the problem is I am setting value of input properly (checked in console). But on the page input always shows previous chosen value.