Google Places Auto-complete in extjs4

旧巷老猫 提交于 2019-12-06 01:36:22

The proxy cannot be used to retrieve data from a URL on a different origin. See the limitations section of Ext.data.proxy.ajax for more information.

http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.proxy.Ajax

You will probably need to set up an endpoint on your server to proxy the request to Google if you want to use that API.

Why not instead of use the sencha combobox, use a simple text input as suggest the google api autocomplete documentation. (I first try with a just common textfield but it didn't work) Then declare a panel or component with html as the following example, and then assign the render:

xtype: 'component',
html: '<div> <input id="searchTextField" type="text" size="50"> </div>',
listeners: {
    render: function () {
        var input = document.getElementById('searchTextField');
        autocomplete = new google.maps.places.Autocomplete(input, { types: ['geocode'] });
        autocomplete.addListener('place_changed', this.fillInAddress);
    },

And result in this:

I was looking for a way to do the same, and I came up writing a custom proxy against the google map javascript library Then I used this custom proxy in a regular combo box

ComboBox:

Ext.create('Ext.form.field.ComboBox', {
    store: {
        fields: [
            {name: 'id'},
            {name: 'description'}
        ],
        proxy: 'google-places'
    },
    queryMode: 'remote',
    displayField: 'description',
    valueField: 'id',
    hideTrigger: true,
    forceSelection: true
});

Custom proxy: (inspired from Ext.data.proxy.Ajax)

Ext.define('com.custom.PlacesProxy', {
    extend: 'Ext.data.proxy.Server',
    alias: 'proxy.google-places',

    constructor: function() {
        this.callSuper();
        this.autocompletePlaceService = new google.maps.places.AutocompleteService();
    },

   buildUrl: function() {
        return 'dummyUrl';
   },

    doRequest: function(operation) {
        var me = this,
            request = me.buildRequest(operation),
            params;

        request.setConfig({
            scope               : me,
            callback            : me.createRequestCallback(request, operation),
            disableCaching      : false // explicitly set it to false, ServerProxy handles caching 
        });

        return me.sendRequest(request);
    },

    sendRequest: function(request) {
        var input = request.getOperation().getParams().query;

        if(input) {
            this.autocompletePlaceService.getPlacePredictions({
                input: input
            }, request.getCallback());
        } else {
            // don't query Google with null/empty input
            request.getCallback().apply(this, [new Array()]);
        }

        this.lastRequest = request;

        return request;
    },

    abort: function(request) {
        // not supported by Google API 
    },

    createRequestCallback: function(request, operation) {
        var me = this;

        return function(places) {
            // handle result from google API
            if (request === me.lastRequest) {
                me.lastRequest = null;
            }
            // turn into a "response" ExtJs understands
            var response = {
                status: 200,
                responseText: places ? Ext.encode(places) : []
            };
            me.processResponse(true, operation, request, response);
         };
    },

    destroy: function() {
        this.lastRequest = null;        
        this.callParent();
    }

});

Note: I wrote this against ExtJs6 but it should basically work alike for ExtJs4.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!