gena2
gena2

Reputation: 159

Intercept and modify requests to Google Maps Autocomplete API

I have web page with input that uses Google Maps API to autocomplete search requests. When user starts typing, he immediately gets suggestions.

What I want is intercept what user types and add some text to it, e.g. add words "New York" to his request. Is it possible? I've found no way to do this in Javascript

Upvotes: 4

Views: 1372

Answers (1)

Dr.Molle
Dr.Molle

Reputation: 117314

There is a service which returns the Autocomplete-predictions: https://developers.google.com/maps/documentation/javascript/places-autocomplete#place_autocomplete_service

You may implement your own Autocomplete e.g. by using jQueryUI.autocomplete and request this service.

Example:

(function ($) {
    $.fn.googlePlacesAutocomplete = function (map) {

        //test if required libraries have been loaded
        if ($.type(this.autocomplete) !== 'function') {
            try {
                console.log('jQueryUI.autocomplete not available, did you load jQueryUI?');
            } catch (e) {}
            return this;
        }

        if ($.type(google) !== 'object' || $.type(google.maps) !== 'object' || $.type(google.maps.places) !== 'object' || $.type(google.maps.places.Autocomplete) !== 'function') {
            try {
                console.log('google.maps.places.Autocomplete not available, did you load the places-library?');
            } catch (e) {}
            return this;
        }

        var ac = new google.maps.places.AutocompleteService(),

            pd = new google.maps.places.PlacesService($('<div/>').css('minHeight','20px').prependTo('body')[0]);
        this.filter("input:text").each(function () {
            var that = $(this),
                oldApi = google.maps.version < '3.17';
            //callback that will be executed when place-details are available
            detailsCallback = function (place, status, cached, item, t) {
                console.log(arguments)
                if (status != google.maps.places.PlacesServiceStatus.OK) {
                    if (t) t.style.textDecoration = 'line-through';
                    return;
                }
                console.log(place.html_attributions)
                $('div').eq(0).html(place.html_attributions.join('<br/>'))
                if (t) t.style.textDecoration = 'none';
                var data = that.data('ac');
                if (!cached) {
                    data.cache[item.id] = place;
                }
                if (data.map && data.marker) {
                    data.marker.setOptions({
                        icon: place.icon || null,
                        map: data.map,
                        position: place.geometry.location
                    });
                    map.setCenter(place.geometry.location);
                }
            };

            that.data('ac',
            $.extend({}, {
                map: map,
                marker: (map) ? new google.maps.Marker : null,
                cache: {},
                options: {}
            },
            that.data('ac')))
                .autocomplete({
                source: function (request, response) {
                    var o = $.extend({}, that.data('ac').options, {
                        
                        //here the input will be manipulated
                        input: [request.term,'New York'].join(',')
                    });
                    if (that.data('ac').bounds && that.data('ac').map) {
                        o.bounds = that.data('ac').map.getBounds();
                    }

                    ac.getPlacePredictions(o,

                    function (predictions, status) {
                        var r = [];
                        if (predictions) {
                            for (var i = 0; i < predictions.length; ++i) {
                                r.push({
                                    cache: true,
                                    callback: function (a, f) {
                                        pd.getDetails.call(pd, a, f)
                                    },
                                    label: predictions[i].description,
                                    value: predictions[i].description,
                                    id: (oldApi) ? predictions[i].reference : predictions[i].place_id
                                });
                            }
                        }
                        response(r);
                    })
                },

                //select
                select: function (e, ui) {

                    var data = that.data('ac'),
                        o = (oldApi) ? {
                            reference: ui.item.id
                        } : {
                            placeId: ui.item.id
                        },
                        t = e.toElement;
                    if (data.map && data.marker) {
                        data.marker.setMap(null);
                    }

                    if (ui.item.cache && data.cache[ui.item.id]) {
                        detailsCallback(data.cache[ui.item.id],
                        google.maps.places.PlacesServiceStatus.OK,
                        true,
                        ui.item,
                        t);
                        return;
                    }

                    ui.item.callback.call(pd,
                    o,

                    function (a, b) {
                        detailsCallback.call(pd, a, b, false, ui.item, t);
                    });
                },
                minLength: 3
            })
            //css for google-logo(required when used without a map)
            .autocomplete('widget').addClass('googleLogo')

            //use the autocomplete as map-control 
            if (map && that.data('ac').ctrl) {
                map.controls[google.maps.ControlPosition[that.data('ac').ctrl]].push(that[0]);
            }

        });
        return this;
    };
}(jQuery));


function initialize() {
    var mapOptions = {
        zoom: 14,
        center: new google.maps.LatLng(52.5498783, 13.425209099999961),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById('map_canvas'),
    mapOptions);
    $('input').googlePlacesAutocomplete(map);


}

google.maps.event.addDomListener(window, 'load', initialize);
html, body, #map_canvas {
    height:100%;
    margin:0;
    padding:0
}
#map_canvas{
    height:90%;
}
.googleLogo {
    padding-bottom:30px !important;
    font-size:1em;
    opacity:.9;
    background:#fff url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-white2.png)bottom left no-repeat !important;
}
.ui-autocomplete .ui-menu-item{
  font-size:12px;
}
  <script src="https://maps.googleapis.com/maps/api/js?v=3&libraries=places"></script>
   <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<input placeholder="type a placename" data-ac='{"ctrl":"TOP_CENTER","bounds":true}'>
<div id="map_canvas"></div>

Upvotes: 2

Related Questions