Open weather API - html

So, I'm making a bunch of webpages for different communities, and on each I want to have a little weather box that I can customize, just with the name of the town, the current temperature, and the current weather condition. I want to be able to style it all exactly how I want. I found this site called Open Weather Map that seems to do exactly what I want. The problem is that I don't know how to use JSON. It's probably easy, but I seem to have gotten lost on any online tutorials I've tried.
This is an example of a URL for the page, that loads some JSON. http://api.openweathermap.org/data/2.5/weather?q=London,uk
I could just include this in my file and dynamically change the city and the country code to get the city I want. But how do I load this into my weather box? Let's say this is what I have:
<div class="weatherbox">
<strong class="city>{CITY NAME HERE}</strong>
<span class="temperature">{X} °C</span>
<p class="weatherdescription>{WEATHER DESCRIPTION HERE}</p>
</div>
Then how do I access the data from the JSON? I want it to be done as simply as possible. Do I include the file like this to have access to the object, or is it more complicated?
<script type="javascript" src="http://api.openweathermap.org/data/2.5/weather?q=London,uk"></script>

from your line of code:
<script type="javascript" src="http://api.openweathermap.org/data/2.5/weather?q=London,uk"></script>
this is incorrect, the api is returning JSON, it is not a javascript file so you don't access it in such a manner. Note that their API appears to take the city and country as a part of the URL parameters, so this you will need to plug in for the appropriate city/country.
For your specific question you could do something like:
var jsonData;
$(document).ready(function ()
{
$.getJSON('http://api.openweathermap.org/data/2.5/weather?q=London,uk', function(data) {
jsonData = data;
$('.city').text(jsonData.name);
// etc
});
});
See http://jsfiddle.net/jsxm7j3n/1/ for it in action.
Note in order to understand the JSON, you can run it through a JSON parser such as the one at http://json.parser.online.fr/ - this will allow you to better understand the make up of what you're receiving back, and how to parse it.
Double note: forgot to mention this solution uses JQuery - i believe there are purely javascript ways to pull it off, but it will be much more verbose and (in my opinion) harder to understand.

Assuming jQuery:
<script>
// Load the data through ajax, not by including it like a script:
$.get('http://api.openweathermap.org/data/2.5/weather?q=London,uk', function(data) {
$('.weatherbox .temperature').text(data.main.temp);
});
</script>
When you look at the response headers from the URL to the API, it is sending 2 important headers:
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Origin: *
This means:
Return JSON object, not just a file. You don't have to use JSON.parse() or $.getJSON then.
Allow anyone to request it via ajax (security aspect of Ajax).
Because Ajax by default is async, (that's what the A stands for), you need to wrap your assignment into a function, which is executed after the request has finished.

The following Code runs. You must only change the Api Key
A full Tutorial: https://www.revilodesign.de/blog/sonstiges/wetterdaten-mit-openweathermap-api-in-eigene-webseite-einbinden/
// API URL
var apiUrl = 'https://api.openweathermap.org/data/2.5/weather?q=London,uk&units=metric&APPID=YOUR_API_KEY';
// AJAX
jQuery.ajax ({
url: apiUrl,
type: 'GET',
dataType: 'jsonp',
success: function(data) {
console.log(data);
// COORDINATES
var coordLat = data.coord.lat;
var coordLng = data.coord.lon;
// WEATHER
var weatherId = data.weather[0].id;
var weatherMain = data.weather[0].main;
var weatherDesc = data.weather[0].description;
var weatherIcon = '<img src="https://openweathermap.org/img/w/' + data.weather[0].icon + '.png" />';
var weatherBg = data.weather[0].icon;
// BASE
var baseData = data.base;
// TEMP
var mainTemp = data.main.temp;
var mainPressure = data.main.pressure;
var mainHumidity = data.main.humidity;
var mainTempMin = data.main.temp_min;
var mainTempMax = data.main.temp_max;
// VISIBILITY
var visibility = data.visibility;
// WIND
var windSpeed = data.wind.speed;
var windDeg = data.wind.deg;
// CLOUDS
var clouds = data.clouds.all;
// DT
var dt = data.dt;
// SYS
var sysType = data.sys.type;
var sysId = data.sys.id;
var sysMessage = data.sys.message;
var sysCountry = data.sys.country;
var sysSunrise = data.sys.sunrise;
var sysSunset = data.sys.sunset;
// ID
var id = data.id;
// NAME
var name = data.name;
// COD
var cod = data.cod;
jQuery('#city').html( name );
jQuery('#temp').html( mainTemp + '° C' );
jQuery('#desc').html( weatherDesc );
}
});
#weatherbox {
width: 200px;
height: 20px;
background: #b4ecff;
border-radius: 8px;
display: table;
margin: 20px auto;
text-align: center;
font-size: 14px;
line-height: 20px;
overflow:hidden;
padding: 0 0 10px 0;
}
strong,
span {
width: 100%;
display: inline-block;
padding: 10px 0;
margin: 0;
}
p {
padding: 0;
margin: 0
}
strong {
background: #00769d;
color: #fff;
text-transform: uppercase;
letter-spacing: 1px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="weatherbox">
<strong id="city"></strong>
<span id="temp"></span>
<p id="desc"></p>
</div>

Related

How to build dynamic dropdowns in configuration setup?

I'm new to Google Data Studio and looking into building a community connector for our Saas service.
For the configuration section, I need to use the Stepped Configuration process. Basically, I nested set of drop-down lists.
However, I need the data to populate those lists to come from my API. I have the REST service endpoints defined, but I cannot find any documenation/examples of how I'd configure this in the getConfig section of the community connector.
Does anyone have a working example I could use as reference?
In reviewing the documentation, there is a section on stepped configurations, which is what I am looking for. You can find that example here: https://developers.google.com/datastudio/connector/stepped-configuration#dynamic_dropdowns
In this example, they show the following for defining the dropdown values.
Notice for the states, they have hard-coded the values for "Illinois" and "California".
My question is, how can I dynamically call API to retrieve values to populate this list? I have 3 nested dropdowns, each with a separate API call, using the answer from previous dropdown to drive the next.
For example first API might be http://myapi.com/countries which returns list of countries.
When they select country, next API call might be http://myapi.com/states?country=US
etc.
config.newSelectSingle()
.setId("state")
.setName("State")
// Set isDynamic to true so any changes to State will clear the city
// selections.
.setIsDynamic(true)
.addOption(config.newOptionBuilder().setLabel("Illinois").setValue("IL"))
.addOption(config.newOptionBuilder().setLabel("California").setValue("CA"));
if (!isFirstRequest) {
var city = config.newSelectSingle()
.setId("city")
.setName("City");
var cityOptions = optionsForState(configParams.state);
cityOptions.forEach(function(labelAndValue) {
var cityLabel = labelAndValue[0];
var cityValue = labelAndValue[1];
city.addOption(config.newOptionBuilder().setLabel(cityLabel).setValue(cityValue));
});
}
return config.build();
}
Worked through the issues I was having. For others who might have hit similiar issues, here's my working getConfig() method.
function getConfig(request) {
var config = cc.getConfig();
var configParams = request.configParams;
var isFirstRequest = configParams === undefined;
if (configParams ===undefined || configParams.tab ===undefined) {
config.setIsSteppedConfig(true);
}
var url ='https://<yourAPIURL>';
var userProperties = PropertiesService.getUserProperties();
var key = userProperties.getProperty('dscc.key');
var mykey ="Bearer " + key
var options = {
"method" : "GET",
"headers" : {
"AUTHORIZATION" : mykey,
"cache-control": "no-cache"
}
};
var response = UrlFetchApp.fetch(url,options);
var parsedResponse = JSON.parse(response);
var zoneControl = config.newSelectSingle()
.setId("zone")
.setName("Zone")
.setIsDynamic(true);
parsedResponse.map(function(itm) {
zoneControl.addOption(config.newOptionBuilder().setLabel(itm.name).setValue(itm.id))
});
if(configParams !==undefined && configParams.zone !==undefined){
var blockurl ='https://<yourAPIURL>?zoneid='+ configParams.zone;
var blockResponse = UrlFetchApp.fetch(blockurl,options);
var parsedBlockResponse = JSON.parse(blockResponse);
var blockControl = config.newSelectSingle()
.setId("block")
.setName("Block")
.setIsDynamic(true);
parsedBlockResponse.map(function(itm) {
blockControl.addOption(config.newOptionBuilder().setLabel(itm.name).setValue(itm.blockKey))
});
}
if(configParams !==undefined && configParams.block !==undefined){
var taburl =''https://<yourAPIURL>?blockKey='+ configParams.block;
var tabResponse = UrlFetchApp.fetch(taburl,options);
var parsedTabResponse = JSON.parse(tabResponse);
var tabControl = config.newSelectSingle()
.setId("tab")
.setName("Tab")
parsedTabResponse.map(function(itm) {
tabControl.addOption(config.newOptionBuilder().setLabel(itm.name).setValue(itm.internalname))
});
}
return config.build();
}
without testing the code:
function getConfig(request) {
var configParams = request.configParams;
var isFirstRequest = configParams === undefined;
var lst=["A","B","C"]; // your values obtained from REST
var tmp=config.newSelectSingle(); //add element to side
var element=tmp.setId("state").setName("State").setIsDynamic(true); // set name and id
for(var i in lst) // set all the values:
{
element = element.addOption(config.newOptionBuilder().setLabel(lst[i]).setValue(lst[i]))
}
if(isFirstRequest || configParams.state==undefined) // no state selected yet
{
config.setIsSteppedConfig(true); // stop here
}
else
{
// next dropdown element,
// Rest API with element set to: configParams.state
var lst2= ["x","y","z"]
var tmp2=config.newSelectSingle(); //add element to side
var element2=tmp2.setId("element2").setName("Element 2 depends on "+configParams.state).setIsDynamic(true); // set name and id
for(var i in lst2) // set all the values:
{
element2 = element2.addOption(config.newOptionBuilder().setLabel(lst2[i]).setValue(lst2[i]))
}
// code for 3rd
}
}
If the user changes the first dropdown value alle other drop downs have to be reset. This may be a bit tricky.

Pass a random JSON pair into an aframe component

Edit 3: The code is now working across numerous objects (thanks to Noam) and he has also helped in getting the random function working alongside it. I'll update the code in the question once its implemented.
Edit 2: I've taken #Noam Almosnino's answer and am now trying to apply it to an Array with numerous objects (unsuccessfully). Here's the Remix link. Please help!
Edit: I've taken some feedback and found this page which talks about using a JSON.parse function. I've edited the code to reflect the new changes but I still can't figure out exactly whats missing.
Original: I thought this previous answer would help in my attempt to parse a json file and return a random string and its related pair (e.g Title-Platform), but I couldn't get it to work. My goal is to render the output as a text item in my scene. I've really enjoyed working with A-frame but am having a hard time finding documentation that can help me in this regard. I tried using the following modified script to get text from the Json file...
AFRAME.registerComponent('super', { // Not working
schema: {
Games: {type: 'array'},
jsonData: {
parse: JSON.parse,
stringify: JSON.stringify}
},
init: function () {
var el = this.el;
el.setAttribute('super', 'jsonData', {src:"https://cdn.glitch.com/b031cbf1-dd2b-4a85-84d5-09fd0cb747ab%2Ftrivia.json?1514896425219"});
var hugeArray = ["Title", "Platform",...];
const el.setAttribute('super', {Games: hugeArray});
el.setAttribute('position', {x:-2, y:2, z:-3});
}
});
The triggers are also set up in my html to render the text. My code is being worked on through glitch.com, any help will be much appreciated!
To load the json, I think you need to use an XMLHttpRequest (as Diego pointed out in the comments), when that's loaded, you can set the text through setAttribute.
Here's a basic example on glitch:
https://glitch.com/edit/#!/a-frame-json-to-text
On init it does the request, then when done, it set's the loaded json text onto the entity.
AFRAME.registerComponent('json-text-loader', {
schema: {},
init: function () {
var textEntity = document.querySelector('#text');
var url = 'json/text.json';
var request = new XMLHttpRequest();
request.open( 'GET', url, true );
request.addEventListener( 'load', function ( event ) {
var jsonText = JSON.parse( event.target.response )
textEntity.setAttribute("value", jsonText.text)
} );
request.send( null );
}
});
Updated version: https://glitch.com/edit/#!/peppermint-direction
AFRAME.registerComponent('json-text-loader', {
schema: {},
init: function () {
var textEntity = document.querySelector('#text');
var url = 'json/text.json';
var request = new XMLHttpRequest();
request.open( 'GET', url, true );
request.addEventListener( 'load', function ( event ) {
var games = JSON.parse( event.target.response ).games;
// Get a random game from the list
var randomGame = games[Math.floor(Math.random()*games.length)];
// Get the next game if it's available
var nextGame = null
if (games.indexOf(randomGame) < games.length - 1) {
nextGame = games[games.indexOf(randomGame) + 1]
}
// Build the string for the games
var gameInfo = randomGame.Title + '\n' + randomGame.Developer + '\n\n'
if (nextGame != null) {
gameInfo += nextGame.Title + '\n' + nextGame.Developer + '\n'
}
textEntity.setAttribute("value", gameInfo);
var sceneEl = document.querySelector('a-scene');
sceneEl.querySelector('a-box').setAttribute('material', {src:"https://cdn.glitch.com/4e63fbc2-a1b0-4e38-b37a-9870b5594af8%2FResident%20Evil.jpg?1514826910998"});
});
request.send( null );
}
});

How to change Bing Map code to Google Map code

Good day,
Does anyone have an idea of how to change a bing map to google map api code. I have found a very useful code on line that is coded using bing maps and would like to change it to work with google maps. if found the code here: http://blogs.msdn.com/b/crm/archive/2011/01/19/custom-charting-capabilities-in-microsoft-dynamics-crm-2011.aspx
Code below:
<html>
<head>
<title>Accounts on Bing Maps</title>
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.3"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="ClientGlobalContext.js.aspx"></script>
<script type="text/javascript">
var map;
// Function to construct key-value pairs from a query string.
function getParametersFromQuery(query) {
var parametersDictionary = new Array();
var parameters = query.split('&');
for (var i = 0; i < parameters.length; i++) {
var keyAndValue = parameters[i].split('=');
parametersDictionary[unescape(keyAndValue[0])] = unescape(keyAndValue[1]);
}
return parametersDictionary;
}
// Function that makes a GET request to the CRM REST end-point, and invokes a callback with the results.
function retrieveFromCrmRestApi(url, callback) {
$.ajax({
type: "GET",
url: GetGlobalContext().getServerUrl() + "/XRMServices/2011/OrganizationData.svc" + url,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
callback(data.d);
}
});
}
// Function that retrieves the corresponding CRM chart, and invokes the callback when successful.
function loadChartFromCrm(callback) {
var parameters = getParametersFromQuery(window.location.search.substring(1));
parameters = getParametersFromQuery(parameters["data"]);
var id = parameters["visid"].substr(1, 36);
var type = parameters["vistype"];
var url = (type == "1111" ? "/SavedQueryVisualizationSet" : "/UserQueryVisualizationSet")
+ "(guid'" + id + "')?$select=DataDescription,PresentationDescription";
retrieveFromCrmRestApi(url, callback);
}
var locations = new Array();
function plotAccountLocations(accounts) {
if (accounts.length > 0) {
var account = accounts.pop();
var address = account.Address1_City + ', ' + account.Address1_Country;
map.Find(null, address, null, null, 0, 1, false, false, false, false,
function (shapeLayer, results, places, moreResults, error) {
if (null != places && places.length > 0) {
var place = places[0];
var newShape = new VEShape(VEShapeType.Pushpin, place.LatLong);
newShape.SetTitle(account.Name);
newShape.SetDescription(address);
locations.push(newShape);
}
// When we have found (or not found) the current account,
// recursively call the same function to find the next one.
plotAccountLocations(accounts);
});
}
else {
var shapeLayer = new VEShapeLayer();
map.AddShapeLayer(shapeLayer);
shapeLayer.AddShape(locations);
}
}
function loadAccountsFromCrm(dataDescription) {
var url = "/AccountSet?$select=Address1_Country,Address1_City,Name";
if (null != dataDescription) {
// Filter accounts based on country specified in data description.
url += "&$filter=Address1_Country eq '" + dataDescription + "'";
}
retrieveFromCrmRestApi(url,
function (data) {
var results = data["results"];
var accounts = new Array();
for (resultKey in results) {
accounts.push(results[resultKey]);
}
// Once accounts are retrieved from CRM Server, plot their locations on map.
plotAccountLocations(accounts);
}
);
}
function getMap(presentationDescription) {
// Set center and zoom defaults.
var center = null;
var zoom = 4;
if (null != presentationDescription) {
// Calculate map-center and zoom from the presentation description.
var arguments = presentationDescription.split(',');
if (arguments.length > 1) {
center = new VELatLong(arguments[0], arguments[1]);
}
if (arguments.length > 2) {
zoom = arguments[2];
}
}
map = new VEMap("map");
map.LoadMap(center, zoom, VEMapStyle.Road, true, VEMapMode.Mode2D, false, 0);
window.onresize = function (event) { map.Resize(document.body.clientWidth, document.body.clientHeight); };
window.onresize(null);
}
function loadMap() {
// First, get the chart object from CRM Server.
loadChartFromCrm(
function (chart) {
// Once we have retrieved the chart, format the map based on the chart's presentation description.
getMap(chart.PresentationDescription);
// Get Accounts from CRM Server based on the chart's data description, and plot them on the map.
loadAccountsFromCrm(chart.DataDescription);
}
);
}
</script>
</head>
<body onload="loadMap()">
<div id="map"></div>
</body>
</html>
There is no easy out of the box solution for what you are looking for.
Google API has many differences. For example, the Google API leaves keeping track of map children to the programmer (you). There is no means of looping through the map controls like there is with the Bing API. This means that your solution for saving the map content and re-displaying it will be a little different.
Although, since both API's are done via javascript, all you need to do is convert your functionality according to their documentation;
Geocoding Sample
Simple Map Initialization
Adding Shapes
Adding Markers (pushpin)

How to Parse RSS Data with JSON

As a noob, I'm trying to parse a weather.com RSS feed for display on my site. The code below successfully retrieves the data and displays it as an alert. My question is how to take this further and parse the resulting feed instead of just displaying it? The goal is to take parts of the response and embed it into the HTML on the page. For example, if I wanted to output a table that has a row with the current temperature, what would be the syntax?
<script>
function parseRSS(url, callback) {
$.ajax({
url: document.location.protocol + '//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=10&callback=?&q=' + encodeURIComponent(url),
dataType: 'json',
success: function(data) {
callback(data.responseData.feed);
}
});
}
parseRSS('http://rss.weather.com/weather/rss/local/USAK0012?cm_ven=LWO&cm_cat=rss&par=LWO_rss',
function(json)
{
alert("Result: " + JSON.stringify(json));
});
</script>
If it helps anyone, here is how I ended up doing it. I went with the feed from accuweather.com, instead of weather.com, just because I happened to get it working first.
1) Obtained the value of the feed "title" field, which contained the current weather values that I needed.
var weatherFeed = json;
var currentConditions = weatherFeed.entries[0].title;
2) Extracted the specific elements, for example currentTemperature:
var firstColonIndex = currentConditions.indexOf(":");
var secondColonIndex = currentConditions.indexOf(":", firstColonIndex + 1);
var currentTemperature = currentConditions.substring(secondColonIndex + 1);
3) Built the HTML using jQuery and embedded the extracted weather values, then put the whole thing within a Div element on my page:
<div class="tile-content" id="MyCityWeather">
<script type="text/javascript">
var weatherElement = "#MyCityWeather";
var temperatureElement = $("<h2/>",
{
style: "margin-left: 25px!important; font-size: 46px!important;"
});
temperatureElement.append(currentTemperature);
temperatureElement.appendTo(weatherElement);
</script>
</div>

google places library without map

I am trying to use the google places library for a nearby search request:
https://developers.google.com/maps/documentation/javascript/places#place_search_requests
i just want to pull the json response and put it in a html list, i do now want to show results on a map or something else. I do not want to use map at all. But in documentation it states that there has to be a map
service = new google.maps.places.PlacesService(**map**);
in order to pass it as an argument in the PlacesService function. What i do now is adding a map with height:0 but it still consumes much amount of memory (i develop a sencha touch 2 app and memory is important). Is there any workaround of using nearby search requests without a map? I do not want to use the Google Places API as it does not support JSONP requests.
As documented the PlacesService accepts as argument either a map or an node where to render the attributions for the results.
So you only have to use the node (a node being an html element) instead of the map.
Please note: hiding the attributions violates the places-policies(also hiding the map when used as argument, because the map will show the attributions)
This also may be interesting to you: Google places API does this violate the TOC?
Example: in a nutshell
If you're using jQuery:
var service = new google.maps.places.PlacesService($('#tag-id').get(0));
If plain Javascript:
var service = new google.maps.places.PlacesService(document.createElement('div'));
Then carry on as usual with the rest of the example code:
service.nearbySearch(request, callback);
Example: using details returned
Live demo of this example on jsFiddle.
Note: This example uses jQuery.
<ul class="reviews__content" id="reviews__content">
</ul>
<div id="service-helper"></div>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=GOOGLE_API_KEY_HERE&libraries=places&callback=getRelevantGoogleReviews">
</script>
<script type="text/javascript">
window.getRelevantGoogleReviews = function(){
var service = new google.maps.places.PlacesService($('#service-helper').get(0)); // note that it removes the content inside div with tag '#service-helper'
service.getDetails({
placeId: 'ChIJAwEf5VFQqEcRollj8j_kqnE' // get a placeId using https://developers.google.com/places/web-service/place-id
}, function(place, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
var resultcontent = '';
for (i=0; i<place.reviews.length; ++i) {
//window.alert('Name:' + place.name + '. ID: ' + place.place_id + '. address: ' + place.formatted_address);
resultcontent += '<li class="reviews__item">'
resultcontent += '<div class="reviews__review-er">' + place.reviews[i].author_name + '</div>';
var reviewDate = new Date(place.reviews[i].time * 1000);
var reviewDateMM = reviewDate.getMonth() + 1;
var reviewDateFormatted = reviewDate.getDate() + '/' + reviewDateMM + '/' + reviewDate.getFullYear();
resultcontent += '<div class="reviews__review-date">' + reviewDateFormatted + '</div>';
resultcontent += '<div class="reviews__review-rating reviews__review-rating--' + place.reviews[i].rating +'"></div>';
if (!!place.reviews[i].text){
resultcontent += '<div class="reviews__review-comment">' + place.reviews[i].text + '</div>';
}
resultcontent += '</li>'
}
$('#reviews__content').append(resultcontent);
}
});
}
</script>
If you want to get location data from a place_id you can do it using the Geocoder class:Here the documentation. With this class you can pass a place_id to the method geocode() and get coordinates and other location data.
Was making a custom address autocomplete for a sign up form.
import {useState, useRef, useEffect } from 'React'
function AutoCompleteInput(){
const [predictions, setPredictions] = useState([]);
const [input, setInput] = useState('');
const [selectedPlaceDetail, addSelectedPlaceDetail] = useState({})
const predictionsRef = useRef();
useEffect(
()=>{
try {
autocompleteService.current.getPlacePredictions({ input }, predictions => {
setPredictions(predictions);
});
} catch (err) {
// do something
}
}
}, [input])
const handleAutoCompletePlaceSelected = placeId=>{
if (window.google) {
const PlacesService = new window.google.maps.places.PlacesService(predictionsRef.current);
try {
PlacesService.getDetails(
{
placeId,
fields: ['address_components'],
},
place => addSelectedPlaceDetail(place)
);
} catch (e) {
console.error(e);
}
}
}
return (
<>
<input onChange={(e)=>setInput(e.currentTarget.value)}
<div ref={predictionsRef}
{ predictions.map(prediction => <div onClick={ ()=>handleAutoCompletePlaceSelected(suggestion.place_id)}> prediction.description </div> )
}
</div>
<>
)
}
So basically, you setup the autocomplete call, and get back the predictions results in your local state.
from there, map and show the results with a click handler that will do the follow up request to the places services with access to the getDetails method for the full address object or whatever fields you want.
you then save that response to your local state and off you go.
Just seen Man asking in a comment above How to initialise the places service without initialising a map? so I thought I would add it here.
placesService = new google.maps.places.PlacesService($('#predicted-places').get(0));
You will need to create an html element with that id first though.
I have come across the same problem.
Why use Maps javascript Api when Places Api is already enabled.Is it an additional price to pay for this simple task?
Maps Javascript API is not used in this code.All the google.maps.Map API methods are taken out. It works fine on jsfiddle.
Just checkout whether it works on local PC.Most of the time it gives the 403 error when i tried running it on local PC storage and using limited requests provided by google API console.
acquire an API key from the google developer console and insert it in the YOUR_API_KEY slot at the script tag of the code
Don't try to run the code here.obviously.The API key needs to be replaced.
// 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=YOUR_API_KEY&libraries=places">
function initMap() {
var input = document.getElementById('pac-input');
var options = {
types: ['establishment']
};
var autocomplete = new google.maps.places.Autocomplete(input, options);
autocomplete.setFields(['place_id', 'geometry', 'name', 'formatted_address', 'formatted_phone_number', 'opening_hours', 'website', 'photos']);
autocomplete.addListener('place_changed', placechange);
function placechange() {
var place = autocomplete.getPlace();
var photos = place.photos;
document.getElementById('place_name').textContent = place.name;
document.getElementById('place_id').textContent = place.place_id;
document.getElementById('place_address').textContent = place.formatted_address;
document.getElementById('phone_no').textContent = place.formatted_phone_number;
document.getElementById('open_time').textContent = place.opening_hours.weekday_text[0];
document.getElementById('open_now').textContent = place.opening_hours.open_now;
document.getElementById('photo').src = photos[0].getUrl();
document.getElementById('photo').style = "width:50%;";
document.getElementById('website').textContent = place.website;
}
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.controls {
background-color: #fff;
border-radius: 2px;
border: 1px solid transparent;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
box-sizing: border-box;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
height: 29px;
margin-left: 5px;
margin-top: 10px;
margin-bottom: 10px;
outline: none;
padding: 0 11px 0 13px;
text-overflow: ellipsis;
width: 400px;
}
.controls:focus {
border-color: #4d90fe;
}
.title {
font-weight: bold;
}
#infowindow-content {
display: none;
}
#map #infowindow-content {
display: inline;
}
<div>
<input id="pac-input" class="controls" type="text" placeholder="Enter a business">
</div>
<div id="info-table">
Name: <span id="place_name"></span><br> Place id: <span id="place_id"></span><br> Address :<span id="place_address"></span><br> Phone : <span id="phone_no"></span><br> Openhours: <span id="open_time"></span><br> Open Now : <span id="open_now"></span><br> website : <span id="website"></span><br> photo :<br> <img id="photo" src="" style="display:none;" />
</div>
<div id="map"></div>
<div id="infowindow-content">
<span id="place-name" class="title"></span><br>
<strong>Place ID:</strong> <span id="place-id"></span><br>
<span id="place-address"></span>
</div>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap">
</script>