|
Post by jporterfield on Nov 26, 2014 16:40:52 GMT -6
Our group is trying to incorporate a google map api into our web application. We have a search bar that needs to open the map in a modal window. Our product owner wants the map to do the following things:
* Find locations based on a neighborhood search * Find locations based on zip code * Show location based on actual address information * Find locations based on category (Art, Music, etc.)
We are just having trouble getting anything to work properly. Any experience with Google API's, specifically modifying maps would be very much appreciated!
|
|
|
Post by Christine Knezevic on Nov 26, 2014 16:46:57 GMT -6
To add more context to Jenna's question, here is one of the pieces of code I've been working on:
I'd like to make the search box be on one page and the map results open in a modal. I believe this should be in google.maps.event.addDomListener(window, 'load', initialize); but I'm not sure how to change this to a modal or if it is actually in a different spot in the js and I am completely off on this.
<!DOCTYPE html> <html> <head> <title>Place Autocomplete</title> <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> <meta charset="utf-8"> <style> html, body, #map-canvas { height: 100%; margin: 0px; padding: 0px } .controls { margin-top: 16px; border: 1px solid transparent; border-radius: 2px 0 0 2px; box-sizing: border-box; -moz-box-sizing: border-box; height: 32px; outline: none; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); }
#pac-input { background-color: #fff; padding: 0 11px 0 13px; width: 400px; font-family: Roboto; font-size: 15px; font-weight: 300; text-overflow: ellipsis; }
#pac-input:focus { border-color: #4d90fe; margin-left: -1px; padding-left: 14px; /* Regular padding-left + 1. */ width: 401px; }
.pac-container { font-family: Roboto; }
#type-selector { color: #fff; background-color: #4d90fe; padding: 5px 11px 0px 11px; }
#type-selector label { font-family: Roboto; font-size: 13px; font-weight: 300; } }
</style> <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places"></script>
<script> function initialize() { var mapOptions = { center: new google.maps.LatLng(41.258327,-96.019111), zoom: 10 }; var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var input = /** @type {HTMLInputElement} */( document.getElementById('pac-input'));
var types = document.getElementById('type-selector'); map.controls[google.maps.ControlPosition.TOP_LEFT].push(input); map.controls[google.maps.ControlPosition.TOP_LEFT].push(types);
var autocomplete = new google.maps.places.Autocomplete(input); autocomplete.bindTo('bounds', map);
var infowindow = new google.maps.InfoWindow(); var marker = new google.maps.Marker({ map: map, anchorPoint: new google.maps.Point(0, -29) });
google.maps.event.addListener(autocomplete, 'place_changed', function() { infowindow.close(); marker.setVisible(false); var place = autocomplete.getPlace(); if (!place.geometry) { return; }
// If the place has a geometry, then present it on a map. if (place.geometry.viewport) { map.fitBounds(place.geometry.viewport); } else { map.setCenter(place.geometry.location); map.setZoom(17); // Why 17? Because it looks good. } marker.setIcon(/** @type {google.maps.Icon} */({ url: place.icon, size: new google.maps.Size(71, 71), origin: new google.maps.Point(0, 0), anchor: new google.maps.Point(17, 34), scaledSize: new google.maps.Size(35, 35) })); marker.setPosition(place.geometry.location); marker.setVisible(true);
var address = ''; if (place.address_components) { address = [ (place.address_components[0] && place.address_components[0].short_name || ''), (place.address_components[1] && place.address_components[1].short_name || ''), (place.address_components[2] && place.address_components[2].short_name || '') ].join(' '); }
infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address); infowindow.open(map, marker); });
// Sets a listener on a radio button to change the filter type on Places // Autocomplete. function setupClickListener(id, types) { var radioButton = document.getElementById(id); google.maps.event.addDomListener(radioButton, 'click', function() { autocomplete.setTypes(types); }); }
setupClickListener('changetype-all', []); setupClickListener('changetype-address', ['address']); setupClickListener('changetype-establishment', ['establishment']); setupClickListener('changetype-geocode', ['geocode']); }
google.maps.event.addDomListener(window, 'load', initialize);
</script> </head> <body> <input id="pac-input" class="controls" type="text" placeholder="Enter a location"> <div id="type-selector" class="controls"> <input type="radio" name="type" id="changetype-all" checked="checked"> <label for="changetype-all">All</label>
<input type="radio" name="type" id="changetype-establishment"> <label for="changetype-establishment">Establishments</label>
<input type="radio" name="type" id="changetype-address"> <label for="changetype-address">Addresses</label>
<input type="radio" name="type" id="changetype-geocode"> <label for="changetype-geocode">Geocodes</label> </div> <div id="map-canvas"></div> </body> </html>
|
|
|
Post by Mike McAllister on Nov 28, 2014 10:43:18 GMT -6
A loooong time ago I did some very basic Google maps API stuff; maybe 2005; and it's much more sophisticated now. Not sure I'm going to be much help, but I will try.
Question: var infowindow = new google.maps.InfoWindow(); Is the google.maps.InfoWindow object your modal UI, or are you needing some kind of modal panel control outside it to contain and display it? I guess what I am wondering is if you need some kind of control designed for being modal, to display what you want inside it?
Hopefully this will get the conversation started.
Update: Looks to me like what you have added as code is working nicely; but you want to encapsulate all of it in a modal pop-up opened from another page. Is that an acceptable way to state your question?
|
|
|
Post by christine on Nov 28, 2014 13:30:41 GMT -6
Yes, the code works in a way. What I want is for the search at the top of the page to be on our initial landing page and the results to show up in a new modal window, rather than on the current page. I think I need to make the map-canvas be part of a modal output, but not sure how or where to do this.
|
|
|
Post by Mike McAllister on Nov 28, 2014 16:30:06 GMT -6
Christine, I know this is not exactly what you want; but it might give you some ideas.
1. I took your code and put it in a page; named it modalPage.htm. 2. On a new page I pulled in links to jQuery and Bootstrap. 3. I used the Bootstrap classes for a modal; and made the modal content an <iframe> that is src="modalPage.htm". 4. I tried other ways of doing it, but it appeared to me that the Google maps API did not like being loaded inside of some other container. That is why I ended up just leaving it in a separate page.
Here's the code, both pages:
modalPage.htm code:
<!DOCTYPE html> <html> <head> <title>Place Autocomplete</title> <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> <meta charset="utf-8"> <style> html, body, #map-canvas { height: 100%; margin: 0px; padding: 0px; }
.controls { margin-top: 16px; border: 1px solid transparent; border-radius: 2px 0 0 2px; box-sizing: border-box; -moz-box-sizing: border-box; height: 32px; outline: none; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); }
#pac-input { background-color: #fff; padding: 0 11px 0 13px; width: 400px; font-family: Roboto; font-size: 15px; font-weight: 300; text-overflow: ellipsis; }
#pac-input:focus { border-color: #4d90fe; margin-left: -1px; padding-left: 14px; /* Regular padding-left + 1. */ width: 401px; }
.pac-container { font-family: Roboto; }
#type-selector { color: #fff; background-color: #4d90fe; padding: 5px 11px 0px 11px; }
#type-selector label { font-family: Roboto; font-size: 13px; font-weight: 300; }
} </style> <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places"></script>
<script> function initialize() { var mapOptions = { center: new google.maps.LatLng(41.258327, -96.019111), zoom: 10 }; var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var input = /** @type {HTMLInputElement} */( document.getElementById('pac-input'));
var types = document.getElementById('type-selector'); map.controls[google.maps.ControlPosition.TOP_LEFT].push(input); map.controls[google.maps.ControlPosition.TOP_LEFT].push(types);
var autocomplete = new google.maps.places.Autocomplete(input); autocomplete.bindTo('bounds', map);
var infowindow = new google.maps.InfoWindow(); var marker = new google.maps.Marker({ map: map, anchorPoint: new google.maps.Point(0, -29) });
google.maps.event.addListener(autocomplete, 'place_changed', function () { infowindow.close(); marker.setVisible(false); var place = autocomplete.getPlace(); if (!place.geometry) { return; }
// If the place has a geometry, then present it on a map. if (place.geometry.viewport) { map.fitBounds(place.geometry.viewport); } else { map.setCenter(place.geometry.location); map.setZoom(17); // Why 17? Because it looks good. } marker.setIcon(/** @type {google.maps.Icon} */({ url: place.icon, size: new google.maps.Size(71, 71), origin: new google.maps.Point(0, 0), anchor: new google.maps.Point(17, 34), scaledSize: new google.maps.Size(35, 35) })); marker.setPosition(place.geometry.location); marker.setVisible(true);
var address = ''; if (place.address_components) { address = [ (place.address_components[0] && place.address_components[0].short_name || ''), (place.address_components[1] && place.address_components[1].short_name || ''), (place.address_components[2] && place.address_components[2].short_name || '') ].join(' '); }
infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address); infowindow.open(map, marker); });
// Sets a listener on a radio button to change the filter type on Places // Autocomplete. function setupClickListener(id, types) { var radioButton = document.getElementById(id); google.maps.event.addDomListener(radioButton, 'click', function () { autocomplete.setTypes(types); }); }
setupClickListener('changetype-all', []); setupClickListener('changetype-address', ['address']); setupClickListener('changetype-establishment', ['establishment']); setupClickListener('changetype-geocode', ['geocode']); }
google.maps.event.addDomListener(window, 'load', initialize);
</script> </head> <body> <input id="pac-input" class="controls" type="text" placeholder="Enter a location"> <div id="type-selector" class="controls"> <input type="radio" name="type" id="changetype-all" checked="checked"> <label for="changetype-all">All</label>
<input type="radio" name="type" id="changetype-establishment"> <label for="changetype-establishment">Establishments</label>
<input type="radio" name="type" id="changetype-address"> <label for="changetype-address">Addresses</label>
<input type="radio" name="type" id="changetype-geocode"> <label for="changetype-geocode">Geocodes</label> </div> <div id="map-canvas"></div> </body> </html>
and then default.htm code:
<!DOCTYPE html> <html> <head> <title>Place Autocomplete</title> <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> <meta charset="utf-8">
<!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<!-- Optional: Include the jQuery library --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <!-- Optional: Incorporate the Bootstrap JavaScript plugins --> <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<style> @media screen and (min-width: 768px) {
#basicModal .modal-dialog { width: 980px; } } </style> </head> <body> <a style="margin: 8px" href="#" class="btn btn-lg btn-success" data-toggle="modal" data-target="#basicModal">Click to open Modal</a>
<div class="modal modal-wide fade" id="basicModal" tabindex="-1" role="dialog" aria-labelledby="basicModal" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">X</button> <h4 class="modal-title" id="myModalLabel">Search</h4> </div> <div class="modal-body"> <iframe src="modalPage.htm" width=945 height=400 frameborder=0 scrolling=auto></iframe> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> </div> </div> </div> </div> </body> </html>
|
|
|
Post by Mike McAllister on Nov 28, 2014 17:22:10 GMT -6
Then; I was thinking that what ever button or link you have opening the modal, could read the value of a text input on your original page; and then JS could set the src= of the <iframe> to the page, plus add a parameter you would pass on the URL; the full URL you would set as the src would be something like 'modalPage.htm?search=[the text input value]. Then the modalPage.htm page load event could parse that search parameter and search for that value as part of the Google API initialize(); function.
Something along those lines. I know you don't want to use Bootstrap; which is fine. If you already have a way to open a modal in your current parent page, then you can use it, I think, and just add the <iframe> and search= logic to your parent page and modal object.
Am I making any sense?
|
|
|
Post by christine on Dec 4, 2014 9:13:37 GMT -6
Mike,
Hey I wanted to thank you for the direction you gave me the other day. We used that direction and have taken it down a different path, but you got us off to a great start!
Thanks,
Christine
|
|