Autocomplete for address using Google Maps JavaScript API - javascript

I came across a challenge and I kindly needed your help. I was developing form input with one of the fields being address / location. I wanted to harness Google Maps API, with services such as AutoComplete and Address Geocoding. I have HTML and JS files. My main issue is that I wanted to tap invalid addresses that users might type and alert them that it is an error. Like for instance, if someone types an address that has not been suggested or types incomplete address, I should be able to tell them that it is not a valid address. This works but only when I press enter, and not submit. If I press submit, it submits the form and doesn't notify.
// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places">
function initMap() {
const input = document.getElementById("location-input");
const autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.addListener("place_changed", () => {
const place = autocomplete.getPlace();
if (!place.geometry) {
// User entered the name of a Place that was not suggested and
// pressed the Enter key, or the Place Details request failed.
//window.alert("No details available for input: '" + place.name + "'");
swal("Please fill all the *Required fields","Click okay to continue", "warning");
return;
}
});
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="form.css">
<!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Libre+Franklin&display=swap" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> -->
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=places&v=weekly" defer></script>
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> -->
<!-- <script src="https://unpkg.com/axios/dist/axios.min.js"></script> -->
<title>Document</title>
</head>
<body>
<form action="" id="mform">
<div class="container">
<div class="row">
<!--Address Section-->
<div id="pac-container">
<input id="location-input" type="text" placeholder="Enter a location" />
</div>
<!--End of Address Section-->
<!--Form Submit Section-->
<div class="row fill-form">
<input name="submit" type="submit" id="submit" class="submit" value="Submit">
</div>
<!--End of Form Submit Section-->
</div>
</div>
<script src="places.js"></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
</form>
</body>
</html>
I have tried adding an submit event listener, but I cannot get what I expect

You need to first prevent the form from submitting and check place.geometry the way you check it on place_changed event. Show that nice swal message and then do whatever you want to if it's valid.
Here below is your own codes edited and checked before submit.
// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places">
function initMap() {
const input = document.getElementById("location-input");
const autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.addListener("place_changed", () => {
const place = autocomplete.getPlace();
if (!place.geometry) {
// User entered the name of a Place that was not suggested and
// pressed the Enter key, or the Place Details request failed.
//window.alert("No details available for input: '" + place.name + "'");
swal("Please fill all the *Required fields","Click okay to continue", "warning");
return;
}
});
//Check before submit
document.getElementById('mform').addEventListener('submit', function(e){
e.preventDefault(); //prevent form submit
const place = autocomplete.getPlace(); //get place from autocomplete
if (!place.geometry) { //check if valid location
swal("Please fill all the *Required fields","Click okay to continue", "warning");
return;
}
});
}

Related

How to trigger click event with enter button?

I am building a very basic magic 8 ball type 'game' using vanilla javascript. I have a text field (for a user question) and a submit button underneath. At present, I have it working fine with a event listener for the submit button but am trying to also get the same result if a user was to click enter.
I saw on w3s that you can trigger a button click upon enter, as below...
// Get the input field
var input = document.getElementById("myInput");
// Execute a function when the user presses a key on the keyboard
input.addEventListener("keypress", function(event) {
// If the user presses the "Enter" key on the keyboard
if (event.key === "Enter") {
// Cancel the default action, if needed
event.preventDefault();
// Trigger the button element with a click
document.getElementById("myBtn").click();
}
});
...but I can't seem to translate that into my own project. HTML and JS for my project below; I am trying not to use nested functions at the moment just to help with my understanding (as advised by my course mentor).
JavaScript
let question = document.querySelector('#userQuestion');
let button = document.querySelector('#shakeButton');
let answer = document.querySelector('#answer');
let options = [
'It is certain.',
'Signs point to yes.',
'Concentrate and ask again.',
'My sources say no.',
]
// Generate a random number
function generateAnswer() {
let index = Math.floor(Math.random() * 4);
let message = options[index];
answer.textContent = message;
answer.style.fontSize = '18px';
setTimeout(timeOut, 3000);
};
// Timeout function
function timeOut() {
answer.textContent = '8';
answer.style.fontSize = '120px';
};
// Enter button trigers click event
function enterButton (event) {
if (event.key === "Enter") {
event.preventDefault();
button.click();
}
};
//Event listener for button click
button.addEventListener('click', generateAnswer);
question.addEventListener("keypress", enterButton);
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Magic 8 Ball, ask it anything and it will answer.">
<!-- Stylesheet & Font Awesome Links -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Orbitron:wght#800&family=Press+Start+2P&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css">
<link rel="stylesheet" href="assets/css/style.css" type="text/css">
<!-- Stylesheet & Font Awesome Links End -->
<title>Magic 8 Ball</title>
</head>
<body>
<nav class="navbar">
<div class="container-fluid">
<a class="navbar-brand ms-auto" href="#">dc games</a>
</div>
</nav>
<!-- Header -->
<header class="heading">
<h1>The Magic 8 Ball</h1>
<p>Shake the Magic 8 Ball and it will answer your question.</p>
</header>
<!-- Header End-->
<!-- Magic 8 Ball -->
<div class="ball-black">
<div class="ball-white">
<p id="answer">8</p>
</div>
</div>
<!-- Magic 8 Ball End -->
<!-- User Question -->
<div class="user-input">
<input type="text" class="form-control mb-2 mr-sm-2" id="inlineFormInputName2 userQuestion" placeholder="What is your question?" required>
<button type="button" class="btn" id="shakeButton">Shake!</button>
</div>
<!-- User Question -->
<!-- Footer -->
<footer>
<div class="copyright fixed-bottom">
<p>Copyright © dc games 2022</p>
</div>
</footer>
<!-- Footer End -->
<!-- JavaScript Links -->
<script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
<script type="text/javascript" src="assets/js/script.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
<!-- JavaScript Links End -->
</body>
</html>
You cannot have multiple Ids on a single DOMElement. If you remove inlineFormInputName2 from the id of the user question, your code will work.
You can only have multiple identifiers for a class.
classes are used for formatting with css and Ids to specifically identify an element.

How do you make a submit button redirect to another page after the user has inputted the correct password?

could you please help me find out what's wrong? After login, it is supposed to redirect you to another page, but nothing happens. The user name is: Joshua and the password is: Joshua#123.
<html>
<head>
<title>Login: MessengerX</title>
<link rel="stylesheet" type="text/css" href="C:\Users\Tania\Documents\Website\style.css">
<meta charset="UTF-8">
<meta name="description" content="HTML website called MessengerX. Send messages to anyone who has logged in.">
<meta name="author" content="Joshua Hurley">
<meta name="keywords" content="HTML, MessengerX, Joshua Hurley, Website, Supremefilms">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/style.css" />
<script type="text/javascript">
var attempt = 3; // Variable to count number of attempts.
// Below function Executes on click of login button.
function validate() {
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
if (username == "Joshua" && password == "Joshua#123") {
alert("Login successfully");
location.replace("www.youtube.com"); // Redirecting to other page.
} else {
attempt--; // Decrementing by one.
alert("You have " + attempt + " attempt left;");
// Disabling fields after 3 attempts.
if (attempt == 0) {
document.getElementById("username").disabled = true;
document.getElementById("password").disabled = true;
document.getElementById("submit").disabled = true;
return false;
}
}
}
</script>
<script src="js/login.js"></script>
</head>
<body>
<div class="imgcontainer">
<img src="C:\Users\Tania\Documents\Website\Screenshots\face.jpg" height="500" alt="Avatar" class="avatar">
</div>
<div class="container">
<div class="main">
<h1 style="color:"><b><i>Login: MessengerX</i></b></h1>
<form id="form_id" method="post" name="myform">
<label>User Name :</label>
<input type="text" name="username" id="username" />
<label>Password :</label>
<input type="password" name="password" id="password" />
<button type="submit" value="Login" id="submit" onclick="validate()" />
</form>
<b><i>Submit</i></b>
</div>
</div>
</body>
</html>
Try this:
window.location.replace("https://www.youtube.com")
You can move code inside window.addEventListener('load' or you can move script after dom at the end
Suggestion: use the entire URL with HTTP or HTTPS.
location.replace("https://www.youtube.com");
<script type="text/javascript">
window.addEventListener('load', (event) => {
var attempt = 3; // Variable to count number of attempts.
/// code here
});
</script>
As leonardofmed mentioned, better place your script just befor </body> closing tag,
because you need to load html first, so script can see elements, otherwise at it's start there is no elements yet, so this will cause error, as for redirecting you can use:
// Simulate a mouse click:
window.location.href = "http://www.w3schools.com";
// Simulate an HTTP redirect:
window.location.replace("http://www.w3schools.com");
use <form><button type="button" ... instead
<form><button type="submit" ... has its own logic ("magic"), which is doing the problem.
use protocol in url location.replace("https://www.youtube.com"), otherwise it's relative path
BTW never validate password on client!!!

Set Postcode/ZIP From Google Auto Complete

I am attempting code that when I enter an address in to a text box it shows the address then shortens to only postcode - much like gif below..
Came across this link but does not seem to work - but on the right lines
https://www.aspforums.net/Threads/647425/Set-Postal-Code-in-TextBox-from-Google-Place-Autocomplete-result-selection-using-JavaScript/
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=key&libraries=places"></script>
<script>
google.maps.event.addDomListener(window, 'load', initialize);
function initialize()
{
var input = document.getElementById('autocomplete_search');
var options =
{
componentRestrictions: {country: 'gb'}
};
var autocomplete = new google.maps.places.Autocomplete(input, options);
var input = document.getElementById('autocomplete_search');
//var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.addListener('place_changed', function () {
var place = autocomplete.getPlace();
// place variable will have all the information you are looking for.
$('#lat').val(place.geometry['location'].lat());
$('#long').val(place.geometry['location'].lng());
});
}
</script>
<title>Google Places Autocomplete InputBox Example Without Showing Map - Tutsmake.com</title>
<style>
.container{
padding: 10%;
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-12"><h2>Google Places Autocomplete InputBox Example Without Showing Map</h2></div>
<div class="col-12">
<div id="custom-search-input">
<div class="input-group">
<input id="autocomplete_search" name="autocomplete_search" type="text" class="form-control" placeholder="Search" />
<input type="hidden" name="lat">
<input type="hidden" name="long">
</div>
</div>
</div>
</div>
</div>
</body>
</html>
When entering an address such Nevile Road, it does not show postcode (and that's all I want). Is there a way to get the postcode from the autocomplete address.
It's not currently possible to filter Place Autocomplete predictions on postcodes only. Take a look at this open feature request in Google's Issue Tracker.
But you can choose to display only the postcode for a selected place in the search box, instead of the full address. In your example, you could change the place_changed listener as follows:
autocomplete.addListener('place_changed', function() {
var place = autocomplete.getPlace();
$('#lat').val(place.geometry['location'].lat());
$('#long').val(place.geometry['location'].lng());
let postcode;
for (let i = 0; i < place.address_components.length; i++) {
let types = place.address_components[i].types;
for (let type of types) {
if (type === "postal_code") {
postcode = place.address_components[i].long_name;
}
}
}
if (!postcode) {
postcode = place.formatted_address;
}
$('#autocomplete_search').val(postcode);
});
Working jsfiddle (add your API key to run it).
With the above code implementation, now if you type in "Nevile Road" into the text field, and select the first place prediction, Nevile Road, Salford, UK, you'll get its postal_code_prefix as the only value, i.e. M7.
Likewise, if you start typing a full postcode, e.g. "M7 3PP", you'll get a Nevile Road, Salford M7 3PP, UK place suggestion, and selecting it will give you M7 3PP.
However, note that this won't always work as there are many addresses that don't have a single, specific postcode. E.g. "London, UK" won't return any postcode at all (as it obviously can't).
Hope this helps!

How to restrict google map autocomplete

Question 1) I'm attempting to search for an postcode (UK) via autocomplete code below
For example, if I search for
NE237AP- this is what I get
Annitsford Drive, Dudley, Cramlington NE23 7AP, UK
But the postcode is omitted if I search street name
Annitsford Drive - I get
Annitsford Drive, Annitsford, Cramlington, UK
Why is that.
Question 2) How can I just use the Postcode results from above into another text box.
Question 3) Is there a way to restrict to UK - seen many snippets of code but none of them seem to work, with the code below.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=key&libraries=places"></script>
<script>
google.maps.event.addDomListener(window, 'load', initialize);
function initialize() {
var input = document.getElementById('autocomplete_search');
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.addListener('place_changed', function () {
var place = autocomplete.getPlace();
// place variable will have all the information you are looking for.
$('#lat').val(place.geometry['location'].lat());
$('#long').val(place.geometry['location'].lng());
});
}
</script>
<title>Google Places Autocomplete InputBox Example Without Showing Map - Tutsmake.com</title>
<style>
.container{
padding: 10%;
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-12"><h2>Google Places Autocomplete InputBox Example Without Showing Map</h2></div>
<div class="col-12">
<div id="custom-search-input">
<div class="input-group">
<input id="autocomplete_search" name="autocomplete_search" type="text" class="form-control" placeholder="Search" />
<input type="hidden" name="lat">
<input type="hidden" name="long">
</div>
</div>
</div>
</div>
</div>
</body>
</html>
You are not getting the postcode detail because the address Annitsford Drive, Annitsford, Cramlington, UK itself is actually covered by multiple post codes such as NE23 7AP,NE23 7AX, etc.
You can refer to the sample code here that fetches the data and populates it in an address form. Note that you may need to change the components in the sample above to cater the address formats in the corresponding region.
As per this documentation:
Use the componentRestrictions option to restrict the autocomplete search to a particular country.
In your case, inside your initialize function, you can use the lines below to restrict the autocomplete predictions to UK:
var input = document.getElementById('autocomplete_search');
var options = {
componentRestrictions: {country: 'gb'}
};
var autocomplete = new google.maps.places.Autocomplete(input, options);

Firebase Anonymous Login on Form Submit Issue

I'm trying to make it so that when I user clicks the submit button on my sign in form, they will be signed in as an anonymous user in Firebase. I know my submit button is triggering the jQuery submit event because the alert in it is being displayed. However, even though the submit button triggers the jQuery submit event, the signInAnonymously method is not being called for some reason. I've also tried using a putting the signInAnonymously call in a separate function and using the form onsubmit attribute but that did not work either. Here is my code (I've omitted my config details for security purposes):
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags always come first -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Escape Room</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="resources/bootstrap/css/bootstrap.min.css">
<!-- Custom CSS -->
<link rel="stylesheet" href="styles.css">
<!-- jQuery -->
<script src="resources/jquery/jquery-3.1.1.slim.min.js"></script>
<!-- Firebase -->
<script src="https://www.gstatic.com/firebasejs/3.6.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.6.2/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.6.2/firebase-database.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.6.2/firebase-messaging.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "",
authDomain: "",
databaseURL: "",
storageBucket: "",
messagingSenderId: ""
};
firebase.initializeApp(config);
//Initialize authentication
var auth = firebase.auth();
// Handle authenticated users
auth.onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
var isAnonymous = user.isAnonymous;
var uid = user.uid;
// ...
} else {
// User is signed out.
// ...
}
// ...
});
// When the DOM has loaded
$(document).ready(function(e) {
$('#signIn').submit(function(e) {
// Prevent the page from refreshing
e.preventDefault();
alert("test");
// Authenticate user
auth.signInAnonymously().catch(function(error) {
alert('test2');
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
console.error(error);
});
});
});
</script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-12">
<form id="signIn">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" placeholder="Your Name">
</div>
<div class="form-group">
<label for="vest">Vest Number</label>
<input type="text" class="form-control" placeholder="Vest Number">
</div>
<button type="submit" class="btn btn-primary">Start</button>
</form>
</div>
</div>
</div>
<!-- jQuery first, then Tether, then Bootstrap JS. -->
<script src="resources/jquery/jquery-3.1.1.slim.min.js"></script>
<script src="resources/tether/js/tether.min.js"></script>
<script src="resources/bootstrap/js/bootstrap.min.js"></script>
</body>
</html>
I'm relatively new to Firebase and this has got me baffled, so any help would be greatly appreciated!
I found out what was going wrong. Since I never called firebase.auth().signOut() it was keeping me logged in as the same user so it did not create a new user each time I submitted the form because I was already logged in as a user. I added window.onload = auth.signOut(); to the script in my head and now a new user is created each time I press the submit button.

Categories

Resources