Suggesting Places with jQuery, Geolocation, and the HERE Places API - HERE Developer

October 08, 2018 0 Comments

Suggesting Places with jQuery, Geolocation, and the HERE Places API - HERE Developer

 

 

Have you ever tried to enter a location for a calendar event using one of the popular calendar applications? You’ve probably noticed that as you’re entering information about the location it suggests an address for you to save you some time. Being able to get suggestions for places is a powerful feature of a location service and can benefit applications far beyond a typeahead or autocomplete type scenario.

In this tutorial we’re going to see how to create a typeahead using jQuery and the HERE Places API to suggest places based on a user defined query and their location based on the geolocation returned from HTML5 in the web browser.

The goal of this project is to produce something like demonstrated in the following animated image:

jquery-places-typeahead

You’ll notice that when the application starts, it searches for the latitude and longitude coordinates of the web browser. Most browsers will prompt for permission before releasing this information. After the coordinates are found, any queries entered will be centered around those coordinates.

Creating a New Web Application with Standard HTML Markup

Before we can start gathering location data and performing searches against the HERE Places API, we need to get the foundation to our application in place. Somewhere on your computer, create a new directory with an index.html file in it. Open the index.html file and include the following HTML markup:

<html> <head> <title>HERE Places Suggestions</title> <style> body { background-color: #F0F0F0; } .tt-input, .tt-hint, .twitter-typeahead { width: 100%; } </style> </head> <body> <div id="remote"> <p id="coords">Location: searching....</p> <input class="typeahead" type="text" placeholder="Places..."> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.11/handlebars.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.10.5/typeahead.bundle.min.js"></script> <script> // Search and location logic here... </script> </body>
</html>

There are a few things to note in the above HTML markup. First, we are creating some very simple style information. It isn’t necessary, but it will make our application look slightly more attractive. Next you’ll notice that we have a <div> tag with an id attribute. This will be referenced when we start working with jQuery. Inside our <div> tag we have text to display our location as well as an input field with a class attribute. It too will be used when we get into our jQuery.

To make this project tick, we need to import three JavaScript libraries. jQuery will be the power-horse to the project, but we also need Handlebars.js to compile HTML and Typeahead.js for our typeahead logic. Notice the versions that I’ve chosen to use. As of right now, I’m using the latest jQuery and Handlebars.js, but a specific version of Typeahead.js. Due to lingering bugs in the latest version of Typeahead.js, we need to use the 0.10.5 release.

Now we can focus on the next step of development.

Gathering Location through HTML and the Web Browser

In most circumstances, searching for a place without a general location in mind, probably isn’t going to be very beneficial. For this reason it makes sense to get the users current location so that we can search for places around that location. This can be accomplished in most web browsers using HTML5 and the geolocation APIs.

Within the index.html file, include the following JavaScript within the <script> tag:

var uiCoords = document.getElementById("coords");
if(navigator.geolocation) { navigator.geolocation.getCurrentPosition(position => { uiCoords.innerHTML = "Location: " + position.coords.latitude + "," + position.coords.longitude; });
} else { console.log("Geolocation is not supported by this browser.");
}

If you try to run your application, you should be prompted for your location. It may take a moment, but when it has found your location, the HTML in the UI will be updated to reflect it.

Because we’re planning ahead, we are going to set a default location, just in case we can’t get the location from the web browser or the user has denied access to it. Take the following revised code:

var coordinates = "40.74917,-73.98529";
var uiCoords = document.getElementById("coords");
if(navigator.geolocation) { navigator.geolocation.getCurrentPosition(position => { coordinates = position.coords.latitude + "," + position.coords.longitude; uiCoords.innerHTML = "Location: " + coordinates; });
} else { console.log("Geolocation is not supported by this browser.");
}

When we start doing queries against the HERE Places API, we’ll be using the coordinates variable which is defaulted to somewhere in New York. After we get the location from the browser, it is updated.

Now that we know a location, even if it isn’t our own, we can start planning our typeahead functionality. Within the same <script> tag in the index.html file, include the following:

$('#remote .typeahead').typeahead( { hint: true, minLength: 3, highlight: false }, { name: "place", displayKey: "vicinity", source: function (query, callback) { // HTTP request here... }, templates: { suggestion: Handlebars.compile('<div>{% raw %}{{title}}{% endraw %} - {% raw %}{{vicinity}}{% endraw %}</div>') } }
);

Remember the id and class attributes that existed on our UI components? They are now bound to this typeahead component with jQuery. The above code is how you’d use the typeahead component, with the exception that we’re not seeing the HERE Places API yet.

When using the typeahead component, we specify that we’d like to see suggestion hints as we type, but our data source will only be called if we have more than three characters present.

Take note of the displayKey and the templates property. The displayKey is what object property in the result set will be shown in the input field after a typeahead result is clicked. In this case we want to show the address, otherwise known as the vicinity. The templates is where we define how the typeahead will look. In our scenario we want a simple single line response that has the name of the place and the address separated by a hyphen. You can get significantly more complex if you wanted to.

Using the HERE Places API to Find Places and Addresses

Now that we have the typeahead in place and our location being resolved, it is time to make sense of our data with the HERE Places API. To be successful with this, you will need to have created a free developer account in the HERE Developer Portal.

In the previous code example we had a source for the typeahead, but it didn’t do anything as of now. We need to have it issue an HTTP request to the HERE Places API for data.

Take the following code for example:

source: function (query, callback) { $.getJSON("https://places.cit.api.here.com/places/v1/autosuggest?at=" + coordinates + "&q=" + query + "&appid=APPIDHERE&appcode=APPCODEHERE", function (data) { var places = data.results.filter(place => place.vicinity); places = places.map(place => { place.title = place.title.replace(/<br\/>/g, ", "); place.vicinity = place.vicinity.replace(/<br\/>/g, ", "); return place; }); return callback(places); });
}

In the above example we are using jQuery to make an HTTP request. We are using the coordinates variable that was populated with the HTML5 API and we are using our app id and app code values from the HERE Developer Portal. The query is what is bound to the actual form input.

The data that is returned from the HERE Places API isn’t necessarily the most useable for our example as is. We need to do some data manipulations to make it into a format that is more appropriate for us. For example, we only want data that has a vicinity. If data doesn’t have a vicinity it is removed using a JavaScript filter function. The data returned may also have some HTML characters so it is best to remove those characters and maybe replace them with a comma.

When the data is ready, we can use the callback method to display the results.

Conclusion

You just saw how to use the HERE Places API as a datasource to populating a jQuery typeahead field. This is a common practice for calendars and other forms that request generic location or places information. It saves your users from having to know the full address or type the full address.

As a next step to this tutorial, you could use the typeahead and populate the result as a marker on a map.


Tag cloud