I am using google maps in my asp.net project. When I type some address, i get suggestions, I pick one of them and map is shown related to that address. This works fine. But I want that user types address in a custom textbox on page 1 and i take that input and populate maps textbox on page 2 as well as show map on page 2 related to address.
here is how I am doing it
$(document).ready(function() {
// Empty the value on page load
$("#formattedAddress").val("");
// variable to indicate whether or not enter has been pressed on the input
var enterPressedInForm = false;
var input = document.getElementById("inputName");
var options = {
componentRestrictions: {country: 'uk'}
};
autocomplete = new google.maps.places.Autocomplete(input, options);
$("#formName").submit(function(e) {
// Only submit the form if information has been stored in our hidden input
return $("#formattedAddress").val().length > 0;
});
$("#inputName").bind("keypress", function(e) {
if(e.keyCode == 13) {
// Note that simply triggering the 'place_changed' event in here would not suffice, as this would just create an object with the name as typed in the input field, and no other information, as that has still not been retrieved at this point.
// We change this variable to indicate that enter has been pressed in our input field
enterPressedInForm = true;
}
});
// This event seems to fire twice when pressing enter on a search result. The first time getPlace() is undefined, and the next time it has the data. This is why the following logic has been added.
google.maps.event.addListener(autocomplete, 'place_changed', function () {
// If getPlace() is not undefined (so if it exists), store the formatted_address (or whatever data is relevant to you) in the hidden input.
if(autocomplete.getPlace() !== undefined) {
$("#formattedAddress").val(autocomplete.getPlace().formatted_address);
}
// If enter has been pressed, submit the form.
if(enterPressedInForm) {
$("#formName").submit();
}
});
});
Regards,
Asif Hameed
You can send variables to other pages (or the same page) with the hashtag. Anything to the right hand side of the # is ignored by the server, but can be read/set by javascript.
Like on page 1 you have
25
50
This value can be read by page2, like this:
var pos = location.hash.substr(1);
Here is an example with your form
page1.htm
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Page 1 - type address</title>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script>
$( function() {
$('#formName').on('submit', function(e) {
// read address
var address = $('#formattedAddress').val();
// add hash to page 2
window.location = 'page2.htm#' + address;
// prevent real submit
e.preventDefault();
return false;
});
});
</script>
</head>
<body>
<form id="formName">
<input id="formattedAddress" placeholder="Enter address"/>
<input type="submit" value="submit" />
</form>
</body>
</html>
page2.htm
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Page 2 - populate map</title>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script>
$( function() {
if(location.hash) {
var address = location.hash.substr(1);
$('#test').html(address);
}
});
</script>
</head>
<body>
<div id="test"></div>
</body>
</html>
Tell me if you have difficulties applying this to a Google Maps webpage.
Try out passing coordinates to page2.
like "page2.htm#50.24/4.45" =>
var variables = location.hash.substr(1);
var position = variables.split('/');
var lat = Number(position[0]);
var lng = Number(position[1]);
Or pass the search string. That should work too.
Related
I'm trying to implement Google sign-in on my web application, as an add-on to normal server-side authentication. The problem is,I'm not able to redirect the page to a Servlet to go to the user homepage. Instead, whenever I try to redirect ONCE,I get continuous requests to the next Servlet(I used print statements on the Servlet to check this).It seems as if the page reloads after every request sent to the Servlet. I also tried using form data to fix this, but that doesn't work either.
How do I stop this from happening? I'm a newbie, so any dumbing down will be much appreciated. In case this is a duplicate, please do send the link. I have tried to find a similar question, but have had no luck so far.
Note: I have removed all irrelevant lines of code.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id"
content="CLIENT_ID_HERE">
<script>
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
//document.cookie = "emailId=" + profile.getEmail();
redirectPost(profile.getEmail());
//window.location = "http://localhost:8080/auth/gmailhome";
}
function redirectPost(data) {
var inputElement = document.getElementById('emailId');
var form = document.getElementById("gmailLoginForm");
inputElement.value = data;
form.submit();
}
</script>
</head>
<body>
<form method="post" action="gmaillogin" id="gmailLoginForm">
<input type="hidden" id="emailId" name="emailId">
</form>
<div class="g-signin2" data-onsuccess="onSignIn"></div>
</body>
</html>
I figured out how to solve this issue, and it just occurred to me that I can leave this here in case someone needs it in the future.
The problem we have is that onSignin() gets called as long as the user is signed in, and the status of the user doesn't reflect that they are signed in. I'm not sure why the state isn't changed automatically-perhaps there is some other purpose to this, or this is just low-priority right now.
So, what we do is add a listener that monitors whether or not the user is signed-in.
Something like this
function onLoad() {
gapi.load('auth2', function () {
gapi.auth2.init();
gapi.auth2.isSignedIn.listen(function (isSignedIn) {
this.setState({ status: isSignedIn })
})
})
}
I am trying to instantiate a Google Places Autocomplete input within an Angular 2 component. I use this code to do it:
loadGoogle() {
let autocomplete = new google.maps.places.Autocomplete((this.ref.nativeElement), { types: ['geocode'] });
let that = this
//add event listener to google autocomplete and capture address input
google.maps.event.addListener(autocomplete, 'place_changed', function() {
let place = autocomplete.getPlace();
that.place = place;
that.placesearch = jQuery('#pac-input').val();
});
autocomplete.addListener()
}
Normally, I believe, I would use the callback function provided by the Google API to ensure that it is loaded before this function runs, but I do not have access to it within a component's scope. I am able to load the autocomplete input 90% of the time, but on slower connections I sometimes error out with
google is not defined
Has anyone figured out how to ensure the Google API is loaded within a component before instantiating.
Not sure whether this will help, but I just use a simple script tag in my index.html to load Google API and I never get any error. I believe you do the same as well. I post my codes here, hope it helps.
Note: I use Webpack to load other scripts, except for Google Map API.
<html>
<head>
<base href="/">
<title>Let's Go Holiday</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Google Map -->
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=<your-key>&libraries=places"></script>
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>
And then in your component:
...
declare var google: any;
export class SearchBoxComponent implements OnInit {
ngOnInit() {
// Initialize the search box and autocomplete
let searchBox: any = document.getElementById('search-box');
let options = {
types: [
// return only geocoding results, rather than business results.
'geocode',
],
componentRestrictions: { country: 'my' }
};
var autocomplete = new google.maps.places.Autocomplete(searchBox, options);
// Add listener to the place changed event
autocomplete.addListener('place_changed', () => {
let place = autocomplete.getPlace();
let lat = place.geometry.location.lat();
let lng = place.geometry.location.lng();
let address = place.formatted_address;
this.placeChanged(lat, lng, address);
});
}
...
}
I used it the same way as explained above but as per google page speed i was getting this suggestion,
Remove render-blocking JavaScript:
http://maps.googleapis.com/…es=geometry,places®ion=IN&language=en
So i changed my implementation,
<body>
<app-root></app-root>
<script src="http://maps.googleapis.com/maps/api/js?client=xxxxx2&libraries=geometry,places®ion=IN&language=en" async></script>
</body>
/* Now in my component.ts */
triggerGoogleBasedFn(){
let _this = this;
let interval = setInterval(() => {
if(window['google']){
_this.getPlaces();
clearInterval(interval);
}
},300)
}
You can do one more thing, emit events once the value(google) is received,& trigger your google task
inside them.
I have a use case where I have a component (like a database) that I would like to expose all the information as bindable properties. However, only a few of those properties will be need by any particular client who uses it. There could be 1000's of entries in the database. How can I figure out which ones are actually needed by the client.
For example:
Polymer('database,
{
observer : {
name : function(oldVal, newVal) { onDataChanged('name', newVal);},
addr : function(oldVal, newVal) { onDataChanged('addr', newVal);},
tel.main : function(oldVal, newVal) { onDataChanged('tel.main',
etc....
}
});
In this case I would like to dynamically create observe handlers only for the data bindings that are actually needed on the fly.
If you are willing to have your clients extend your component to specify the desired database fields then you can dynamically create observers only for the fields they specify.
Example
Component
<link rel="import" href="../../webcomponents/bower_components/polymer/polymer.html">
<polymer-element name=demo-dynamicproperties >
<template>
<h2>dynamic properties</h2>
See the console for changes
</template>
<script>
Polymer({
// Validate that it is an attribute that is allowed
// For the example we will allow anything starting with validitem
isValidAttribute: function(name) {
return (name.match('^validitem'));
},
// Get attributes
created: function() {
for (name in this.publish) {
console.log("Trying: "+name);
// Verify that it is one of the dynamic attributes
if (this.isValidAttribute(name)) {
console.log("Accepting: "+name);
this[name]="Pull from DB";
// References:
// https://www.polymer-project.org/0.5/docs/polymer/node_bind.html
// https://github.com/Polymer/NodeBind/blob/master/tests/tests.js
// https://github.com/polymer/observe-js
var observer = new PathObserver(this,name);
observer.open(makeHandler(this,name));
}
}
/************* TEST **********************************/
// Verify that dynamic updates worked by updating
this.job('update_validitem1', function() {
this.validitem1="Updated after 10 seconds";
}, 10000);
/************ End Test ******************************/
}
});
// Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
function makeHandler(element, property) {
function handler(newval,oldval) {
console.log("element" + element,"property:" + property,"from:"+oldval,"to:"+newval);
}
return handler;
}
</script>
</polymer-element>
Usage
<!DOCTYPE HTML>
<html lang="en">
<head>
<script src="../../webcomponents/bower_components/webcomponentsjs/webcomponents.min.js"></script>
<link rel="import" href="../../webcomponents/bower_components/polymer/polymer.html">
<link rel="import" href="demo-dynamicproperties.html">
<title>demo-dynamicproperties test page</title>
</head>
<body>
<polymer-element name=demo-usedb extends="demo-dynamicproperties" attributes="validitem1 validitem2 invaliditem" noscript>
</polymer-element>
<h1>Demo</h1>
<template is="auto-binding">
<h2>Dynamic tag</h2>
<demo-usedb validitem1="{{item1choice2}}" item2="setthis"></demo-usedb>
<h2>Input</h2>
<input type="text" value="{{item1choice2}}">
<h3>Produces</h3>
{{item1choice2}}
</template>
</body>
</html>
It looks like the answer to the questions is that it cannot be done. There does not appear to be any hooks or events that a component can use to get notified when properties are bound (or attempted to be bound) to it. I filed a bug/enhancement request here
https://github.com/Polymer/polymer/issues/1303
to request that this feature be supported in the future.
ok so heres my code
<html>
<head>
<title></title>
<body>
<script>
<!--
/*
Cookie Redirect. Written by PerlScriptsJavaScripts.com
Copyright http://www.perlscriptsjavascripts.com
Free and commercial Perl and JavaScripts
*/
// page to go to if cookie exists
go_to = "http://www.cookieisthere.com";
// number of days cookie lives for
num_days = 365;
function ged(noDays){
var today = new Date();
var expr = new Date(today.getTime() + noDays*24*60*60*1000);
return expr.toGMTString();
}
function readCookie(cookieName){
var start = document.cookie.indexOf(cookieName);
if (start == -1){
} else {
window.location = go_to;
}
}
readCookie("seenit");
// -->
</script>
</body>
</html>
This page will load on a page through a iframe... if the cookie is their i want the parent window to go to http://www.cookieisthere.com not the original page. After reading up on it a bit some people say use _top where the link is but i dont know how to do this. All help is much appreciated :)
Try this instead
<html>
<head>
<title></title>
<body>
<script>
<!--
/*
Cookie Redirect. Written by PerlScriptsJavaScripts.com
Copyright http://www.perlscriptsjavascripts.com
Free and commercial Perl and JavaScripts
*/
// page to go to if cookie exists
go_to = "http://www.cookieisthere.com";
// number of days cookie lives for
num_days = 365;
function ged(noDays){
var today = new Date();
var expr = new Date(today.getTime() + noDays*24*60*60*1000);
return expr.toGMTString();
}
function readCookie(cookieName){
var start = document.cookie.indexOf(cookieName);
if (start == -1){
} else {
window.top.location = go_to;
}
}
readCookie("seenit");
// -->
</script>
</body>
</html>
Does "Here" maps support country highlighting, something like in the following example: https://google-developers.appspot.com/chart/interactive/docs/gallery/geochart_06d031f6a0bf088f1320a975cdefa0e3.frame
There is no library support for Choropleth maps (which is what I think you are after), but it is possible to create one using jQuery + HERE Maps if you have access to a KML file holding the boundaries of the countries or regions you need.
Updated WKT solution now available
Access to KML shapes is no longer required, since the Geocoder API now offers an IncludeShapes attribute which returns the shape of a country in WKT format. A WKT parser can be found here.
A simple WKT choropleth example can be found here.
KML Solution
Hint: try something like http://geocommons.com/overlays/119819 - Country borders are a political minefield, and this is probably the reason why HERE doesn't do this sort of thing directly.
The problem falls into four parts:
Asynchronously load but do not parse a KML document to read in the "countries of the world"
Manipulate the KML to remove unwanted countries, alter the intensity of colours and so on.
Taking the <Document> element only call nokia.maps.kml.Manager.parse() to transfrom your modified KML into mapObjects and place them on the map.
By default the KML will display an Infobubble when a <PlaceMark> is clicked, an additional listener is required if you want to get the Infobubble to display on hover as in the example you linked to.
Here is an example screenshot, it just highlights countries beginning with "A" or "B" but you should get the idea:
The code is as follows (use your own app id and token):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>KML Country color test</title>
<meta http-equiv="X-UA-Compatible" content="IE=7; IE=EmulateIE9"/>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<script type="text/javascript" charset="UTF-8" src="http://api.maps.nokia.com/2.2.3/jsl.js?with=all"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<div style="height:800px" id="mapContainer"></div>
<script type="text/javascript" id="exampleJsSource">
nokia.Settings.set( "appId", "YOUR APP ID");
nokia.Settings.set( "authenticationToken", "YOUR TOKEN");
// Get the DOM node to which we will append the map
var mapContainer = document.getElementById("mapContainer");
var infoBubbles = new nokia.maps.map.component.InfoBubbles();
// Create a map inside the map container DOM node
var map = new nokia.maps.map.Display(mapContainer, {
center: [0, 0],
zoomLevel: 3,
components: [
// We add the behavior component to allow panning / zooming of the map
new nokia.maps.map.component.Behavior(),new nokia.maps.map.component.TypeSelector(),new nokia.maps.map.component.ZoomBar(),
infoBubbles
]
});
map.addListener("mouseover", function (evt) {
var coord = map.pixelToGeo(evt.targetX, evt.targetY);
var objects = map.getObjectsAt( evt.targetX, evt.targetY) ;
for(var i=0;i<objects.length;i++){
var object=objects[i];
if(object instanceof nokia.maps.map.Polygon ){
object.dispatch( new nokia.maps.dom.Event({type: "click", target: object}));
evt.stopImmediatePropagation();
}
}
});
var kml = new nokia.maps.kml.Manager();
var resultSet;
var container = new nokia.maps.map.Container();
var doc;
// We define a callback function for parsing kml file,
// and then push the parsing result to map display
var onParsed = function (kmlManager) {
//console.debug("onParsed");
var
boundingBox;
// KML file was successfully loaded
if (kmlManager.state == "finished") {
// KML file was successfully parsed
resultSet = new nokia.maps.kml.component.KMLResultSet( kmlManager.kmlDocument, map);
// Add the container to the map's object collection so it will be rendered onto the map.
map.objects.add(container = resultSet.create());
}
};
// Add an observer to kml manager
kml.addObserver("state", onParsed);
function err (){
alert("An Error has occurred.");
}
function parseXml(xml)
{
$(xml).find("Placemark").each(function(){
var countryName = $(this).children("name").text();
/* YOU CAN MANIPULATE STUFF HERE.
var newName = document.createElement('name');
newName.appendChild(document.createTextNode(" Additional Text" ));
var newDesc = document.createElement('description');
newDesc.appendChild(document.createTextNode(countryName));
$(this).children("name").replaceWith(newName);
$(this).children("description").replaceWith(newDesc);*/
if (countryName.indexOf("A")!= 0 && countryName.indexOf("B")!= 0 ){
$(this).remove();
}
});
doc = xml.getElementsByTagName('Document')[0];
kml.parse( doc);
}
// doc-simple-limited is my KML file of country borders.
$.ajax({
type: "GET",
url: "../doc-simple-limited.kml" ,
dataType: "xml",
success: parseXml,
error : err
});
</script>
<body>
</html>