SNIPPET · FREE

WordPressGravity Forms

City and place autocomplete for Gravity Forms

Add city or place suggestions to a Gravity Forms field using Google Places or Mapbox.

Two variants

Choose Google Places or Mapbox. Do not activate both on the same field. Both require your own public API key/token plus the Gravity Forms form and field IDs.

Google Places · PHP
/**
 * Gravity Forms city autocomplete with Google Places.
 * Replace YOUR_GOOGLE_MAPS_API_KEY and configure form/field IDs.
 */
add_action( 'wp_enqueue_scripts', function () {

    $config = array(
        'api_key' => 'YOUR_GOOGLE_MAPS_API_KEY',
        'forms'   => array(
            1 => array( 22 ),
        ),
        'country' => '', // Example: 'it'
    );

    if ( $config['api_key'] === 'YOUR_GOOGLE_MAPS_API_KEY' ) {
        return;
    }

    wp_enqueue_script(
        'mrc-gf-google-places',
        'https://maps.googleapis.com/maps/api/js?key=' . rawurlencode( $config['api_key'] ) . '&libraries=places',
        array( 'jquery' ),
        null,
        true
    );

    wp_localize_script( 'mrc-gf-google-places', 'MRC_GF_GOOGLE_PLACES', $config );

    wp_add_inline_script( 'mrc-gf-google-places', <<<'JS'
(function($){
    function init() {
        if (!window.google || !google.maps || !google.maps.places || !window.MRC_GF_GOOGLE_PLACES) return;

        Object.keys(MRC_GF_GOOGLE_PLACES.forms).forEach(function(formId){
            MRC_GF_GOOGLE_PLACES.forms[formId].forEach(function(fieldId){
                var input = document.getElementById('input_' + formId + '_' + fieldId);
                if (!input || input.dataset.mrcPlacesReady) return;

                var options = { types: ['(cities)'] };
                if (MRC_GF_GOOGLE_PLACES.country) {
                    options.componentRestrictions = { country: MRC_GF_GOOGLE_PLACES.country };
                }

                new google.maps.places.Autocomplete(input, options);
                input.dataset.mrcPlacesReady = '1';
            });
        });
    }

    $(init);
    $(document).on('gform_post_render', init);
})(jQuery);
JS
    );
} );
Mapbox · PHP
/**
 * Gravity Forms city/place autocomplete with Mapbox.
 * Replace YOUR_MAPBOX_PUBLIC_TOKEN and configure form/field IDs.
 */
add_action( 'wp_enqueue_scripts', function () {

    $config = array(
        'access_token' => 'YOUR_MAPBOX_PUBLIC_TOKEN',
        'forms'        => array(
            1 => array( 22 ),
        ),
        'country'      => '',
        'types'        => 'place',
        'limit'        => 7,
    );

    if ( $config['access_token'] === 'YOUR_MAPBOX_PUBLIC_TOKEN' ) {
        return;
    }

    wp_register_script( 'mrc-gf-mapbox-autocomplete', '', array( 'jquery' ), '1.0.0', true );
    wp_enqueue_script( 'mrc-gf-mapbox-autocomplete' );
    wp_localize_script( 'mrc-gf-mapbox-autocomplete', 'MRC_GF_MAPBOX', $config );

    wp_add_inline_script( 'mrc-gf-mapbox-autocomplete', <<<'JS'
(function($){
    function init() {
        if (!window.MRC_GF_MAPBOX) return;

        Object.keys(MRC_GF_MAPBOX.forms).forEach(function(formId){
            MRC_GF_MAPBOX.forms[formId].forEach(function(fieldId){
                var input = document.getElementById('input_' + formId + '_' + fieldId);
                if (!input || input.dataset.mrcMapboxReady) return;

                input.dataset.mrcMapboxReady = '1';
                input.setAttribute('autocomplete','off');

                var timer = null;
                var request = null;
                var list = document.createElement('div');
                list.setAttribute('role','listbox');
                list.style.cssText = 'position:absolute;z-index:999999;background:#fff;border:1px solid #ddd;max-height:280px;overflow:auto;display:none;';
                document.body.appendChild(list);

                function position() {
                    var r = input.getBoundingClientRect();
                    list.style.left = (window.scrollX + r.left) + 'px';
                    list.style.top = (window.scrollY + r.bottom + 2) + 'px';
                    list.style.width = r.width + 'px';
                }

                function close() {
                    list.style.display = 'none';
                    list.innerHTML = '';
                }

                function render(features) {
                    list.innerHTML = '';
                    (features || []).forEach(function(feature){
                        var item = document.createElement('button');
                        item.type = 'button';
                        item.setAttribute('role','option');
                        item.textContent = feature.place_name || feature.text || '';
                        item.style.cssText = 'display:block;width:100%;text-align:left;padding:10px 12px;border:0;border-bottom:1px solid #eee;background:#fff;cursor:pointer;';
                        item.addEventListener('click', function(){
                            input.value = feature.place_name || feature.text || '';
                            input.dispatchEvent(new Event('input',{bubbles:true}));
                            input.dispatchEvent(new Event('change',{bubbles:true}));
                            close();
                        });
                        list.appendChild(item);
                    });
                    if (list.children.length) {
                        position();
                        list.style.display = 'block';
                    } else {
                        close();
                    }
                }

                input.addEventListener('input', function(){
                    clearTimeout(timer);
                    if (request) request.abort();

                    var q = input.value.trim();
                    if (q.length < 3) { close(); return; }

                    timer = setTimeout(function(){
                        request = new AbortController();

                        var url = 'https://api.mapbox.com/geocoding/v5/mapbox.places/' +
                            encodeURIComponent(q) + '.json?access_token=' +
                            encodeURIComponent(MRC_GF_MAPBOX.access_token) +
                            '&autocomplete=true&limit=' +
                            encodeURIComponent(MRC_GF_MAPBOX.limit || 7) +
                            '&types=' + encodeURIComponent(MRC_GF_MAPBOX.types || 'place');

                        if (MRC_GF_MAPBOX.country) {
                            url += '&country=' + encodeURIComponent(MRC_GF_MAPBOX.country);
                        }

                        fetch(url,{signal:request.signal})
                            .then(function(r){ return r.ok ? r.json() : Promise.reject(); })
                            .then(function(data){ render(data.features); })
                            .catch(function(e){ if (e && e.name !== 'AbortError') close(); });
                    }, 250);
                });

                window.addEventListener('resize', function(){ if (list.style.display !== 'none') position(); });
                window.addEventListener('scroll', function(){ if (list.style.display !== 'none') position(); }, true);
                document.addEventListener('mousedown', function(e){ if (e.target !== input && !list.contains(e.target)) close(); });
            });
        });
    }

    $(init);
    $(document).on('gform_post_render', init);
})(jQuery);
JS
    );
} );

Requires Gravity Forms, a provider account and your own restricted public API key/token. Check provider terms and availability. These examples are not an address validation service.

How to use it

  1. Install Code Snippets Free in WordPress.
  2. Create a new PHP snippet.
  3. Copy and paste the code.
  4. Activate it in the required scope.

This is a simple option, not a requirement: experienced users can put the code in their own plugin or the appropriate location. Configure form IDs and any required providers before enabling Gravity Forms examples.