Bing Maps Auto Complete Search

A while back I had put some code together to generate an auto complete box using the VEMap.Find method. Recently I was asked if I had any examples of how to do this and ended up finding my original code which was originally written when version 5 of the map control was the current version, and at some point updated to use version 6.1. In any case it was code. With that I decided to clean it up a bit and make it simple.

The first step to creating the auto complete input box is to first create your base elements; Bing Map, textbox, search button…. After that you can wrap with div’s and position accordingly (Note: if it is going to display over the map make sure to have a high z-index). Once that is done add a onkeyup event to the textbox. When this even fires you will want to grab the text in the textbox and make sure it’s not empty. If it is not empty you can then use the VEMap.Find function to search for the input. The find callback can be used to grab the returned results. With the results you can then create html that contain all the suggestions. As a feature I split each location into pieces and bold the first word to make it look nice. In the html an onclick event is added to each result. When a user clicks on a suggestion it will then fire the SelectSuggestion function which populates your textbox with the suggestion

A side note, I used a array to concatenate my html in the FindSuggestion function. This was done for performance, however using “+” is fine too.

Here is the code:

Autocomplete.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html>
   <head>
      <title></title>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <script src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2"></script&gt;
        <script>
        var map = null;
          
        function GetMap()
        {
            map = new VEMap(‘myMap’);
            map.LoadMap();
        }   

        function FindSuggestions(searchBox)
          {
            var location = searchBox.value;
            if(location && location != ”)
            {
                map.Find(null, location, null, null, null, null, false, null, false, false, findCallback);
             }
            else
            {
                document.getElementById(‘suggestionBox’).style.display = ‘none’;
            }
          }
        
        function findCallback(layer, resultsArray, places, hasMore, veErrorMessage)
        {    
            var suggestionHTML = [];
            
            if(places)
            {
                for(var i=0;i < places.length; i++)
                {
                    var parts = places[i].Name.split(",");
                    
                    suggestionHTML.push("<div style=’width:100%;cursor:pointer;’ onclick=\"SelectSuggestion(‘");
                    suggestionHTML.push(places[i].Name, "’)\">");
                    
                    //bold first word to make it look nice
                    suggestionHTML.push("<b>", parts[0], "</b>,");
                    
                    for(var j=1; j < parts.length; j++)
                    {
                        if(j != parts.length-1)
                        {
                            suggestionHTML.push(parts[j], ",");
                        }
                        else
                        {
                            suggestionHTML.push(parts[j]);
                        }
                    }
                    
                    suggestionHTML.push("</div>");
                }
            }
            
            document.getElementById(‘suggestionBox’).style.display = ”;
            document.getElementById(‘suggestionBox’).innerHTML = suggestionHTML.join(”);
        }

        //functionality for when user clicks on a suggestion
        function SelectSuggestion(suggestion)
        {
            document.getElementById(‘suggestionBox’).innerHTML = "";
            document.getElementById(‘suggestionBox’).style.display = ‘none’;
            document.getElementById(‘searchBox’).value = suggestion;
        }
        
        //Functionality for find button
        function Find()
        {
            var location = document.getElementById(‘searchBox’).value;
            document.getElementById(‘suggestionBox’).style.display = ‘none’;
            
            if(location && location != ”)
            {
                map.Find(null, location);
            }
        }
        
        </script>
        <style>
        #suggestionBox
        {
            position:absolute;
            width:250px;
            background-color:#fff;
            border:solid 1px #000;
        }
        </style>
    </head>
    <body onload="GetMap()">
        <div>
            <div style=’width:260px;float:left;’>
                <input id="searchBox" style="width:250px;" onkeyup="FindSuggestions(this)" />
                <div style=’position:relative;z-index:100000′><div id=’suggestionBox’ style=’display:none;’></div></div>
            </div>

            <input type="button" value="Find" onclick="Find();"/>
        </div>            
        <div id=’myMap’ style="position:relative; width:600px; height:400px;"></div>
    </body>
</html>

Advertisements

4 thoughts on “Bing Maps Auto Complete Search

  1. Hey Ricky,
    Thank you very much for your code, it helped me a lot for building my own version of auto suggestion box using bing map ajax control v7. I’ve implemented it using the bing map’s REST API and of course your help. I would like to share this here. Hope some one would be in need.

    Bing Map: Ajax Control 7 – Auto Complete Address

    body{
    margin:0;
    padding:0;
    }
    .map {
    margin: 0 auto;
    top: 30px;
    position: relative;
    width: 95%;
    height: 400px;
    }
    .action_bar{
    width:95%;
    margin: 0 auto;
    position:relative !important;
    top:40px;
    }
    #suggestionBox{
    width:250px;
    background-color:#fff;
    border:solid 1px #000;
    }

    // Variable holding the map object
    var mapObject = null;
    var credentials = “ArnmfgTNLxh-E7k52Q_ZGg_xCUOXKlrsYDMfFH4x6fOPyzGdxMcQgrWY1FBPCUmX”;

    function GetMap(){
    mapObject = new Microsoft.Maps.Map(document.getElementById(“myMap”), {
    credentials: credentials,
    center: new Microsoft.Maps.Location(32.7637, -96.6509),
    mapTypeId: Microsoft.Maps.MapTypeId.road,
    zoom: 12
    });
    }

    // Create the HTML script element to call the Bing Map’s rest service
    function callRestService(url){
    var script = document.createElement(“script”);
    script.setAttribute(“type”, “text/javascript”);
    script.setAttribute(“src”, url);
    document.body.appendChild(script);
    }

    function findSuggestions(searchString){
    var geoSearchString = searchString.value;
    var url = null;
    if(geoSearchString && geoSearchString.length > 2){
    url = “http://dev.virtualearth.net/REST/v1/Locations/”+geoSearchString+”?output=json&jsonp=geocodeCallback&key=”+credentials;
    callRestService(url); // Call Bing Map’s rest service
    }
    else{
    document.getElementById(‘suggestionBox’).style.display = ‘none’;
    }
    }

    // Callback function
    function geocodeCallback(result){
    var suggestionHTML = [];
    if(result && result.resourceSets){
    for(var i=0;i < result.resourceSets[0].resources.length; i++){
    var location_name = result.resourceSets[0].resources[i].address.formattedAddress;
    // Push the location name to array
    suggestionHTML.push('’+ location_name+”);
    document.getElementById(‘suggestionBox’).style.display = “”;
    document.getElementById(‘suggestionBox’).innerHTML = suggestionHTML.join(“”);
    }
    }
    }

    // Function to select the auto suggested strings
    function selectSuggestion(location_name){
    document.getElementById(‘suggestionBox’).innerHTML = “”;
    document.getElementById(‘suggestionBox’).style.display = ‘none’;
    document.getElementById(‘searchBox’).value = location_name;
    }

    function findOnMap(result){
    if(
    result &&
    result.resourceSets &&
    result.resourceSets.length > 0 &&
    result.resourceSets[0].resources &&
    result.resourceSets[0].resources.length > 0
    ){
    // Set the map view using the returned bounding box
    var bbox = result.resourceSets[0].resources[0].bbox;
    var viewBoundaries = Microsoft.Maps.LocationRect.fromLocations
    (
    new Microsoft.Maps.Location(bbox[0], bbox[1]),
    new Microsoft.Maps.Location(bbox[2], bbox[3])
    );
    mapObject.setView({ bounds: viewBoundaries});
    // Add a pushpin at the found location
    var location = new Microsoft.Maps.Location
    (
    result.resourceSets[0].resources[0].point.coordinates[0],
    result.resourceSets[0].resources[0].point.coordinates[1]
    );
    var pushpin = new Microsoft.Maps.Pushpin(location);
    mapObject.entities.push(pushpin);
    }
    else{
    var locationString = document.getElementById(‘searchBox’).value;
    document.getElementById(‘suggestionBox’).style.display = ‘none’;
    if(locationString.length > 2){
    url = “http://dev.virtualearth.net/REST/v1/Locations/”+locationString+”?output=json&jsonp=findOnMap&key=”+credentials;
    callRestService(url); // Call Bing Map’s rest service
    }
    }
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s