Search code examples
javascriptjqueryhtmlgoogle-places-apigoogle-places-autocomplete

Using jQuery with google places autocomplete


Hello guys I'm using google places autocomplete for establishments in Russia. I'm having problems with manipulating DOM elements.

What I'm trying to achieve:
In HTML I have div with autocompleteString class which is hidden with CSS. In function fillIn I'm adding HTML to it from google response with place.adr_address. Then I'm using class locality from that response to populate input with class name cityRu. Not this part works fine.

Problem is that I will have multiple accommodationDivs that will be added dynamically and I'm trying to add $('.autocompleteString').html(place.adr_address) and $('.cityRu').val(cityRu) to each one of them. I'm trying to target classes autocompleteString and cityRu closest to my autocomplete input. I'm trying to achieve something like this:
$('.yourAccomm').closest('.accommodationDivs').find('.cityRu').val('mytext') but instead of $('.yourAccomm') I need to have something like JQ $(this) or vanilla JS equivalent, but everything I've tried so far didn't work. Can anyone please help me with this ?

This is example of place.adr_address response:
<span class="street-address">ул. Рубинштейна, 20</span>, <span class="locality">Санкт-Петербург</span>, <span class="country-name">Россия</span>, <span class="postal-code">191002</span>

JS:

function searchHotels() {
    var inputs = document.querySelectorAll('.yourAccomm');

    var options = {
        types: ['establishment'],
        componentRestrictions: {country: 'ru'}
    };

    var autocompletes = [];

    for (var i = 0; i < inputs.length; i++) {
        var autocomplete = new google.maps.places.Autocomplete(inputs[i], options);
        autocomplete.inputId = inputs[i].id;
        autocomplete.addListener('place_changed', fillIn);
        autocompletes.push(autocomplete);
    }

    function fillIn() {
        var place = this.getPlace();
        console.log(this)

        // console.log(inputs[0])

        // inputs[0].style.background = "red";

        $('.autocompleteString').html(place.adr_address);
        var cityRu = $('.locality').text();
        console.log(cityRu)
        $('.cityRu').val(cityRu);
    }
}
searchHotels();

HTML:

<div class="accommodationDivs first_accommodation">
    <div class="steps__f-grp form-group">
        <label><i class="fa fa-info-circle"></i>Name of hotel / hostel (first entry)</label>
        <div class="steps__f-grp__accomo input-group">
            <input type="text" class="input--margin-r form-control yourAccomm" aria-label="Name of accommodation" name="first_accommodation" tabindex="11" placeholder="Enter a location">

            <span class="input-group-btn">
                <button id='add_field_button_1' class="steps__f-grp__btn-more btn btn-secondary" type="button">+</button>
            </span>
        </div>
        <label for="first_accommodation" generated="true" class="error"></label>
    </div>

    <div class="autocompleteString">

    </div>

    <div class="steps__f-grp form-group">
        <label for="cityRu">City</label>
        <input id="cityRu" class="form-control cityRu" type="text" name="cityRu" tabindex="12">
    </div>
</div>

Solution

  • Okay so I managed to solve this. Logic is a bit messy and hacky but it gets the job done.
    First we get ID of input that user is typing for autocomplete. Then we add data attribute city to that with input and we give value to that data attribute with city we get from google API. Then we use that data attribute to populate nearest input with city name.

    // Google places API code
    function searchHotels() {
    
        var inputs = document.querySelectorAll('.yourAccomm');
        var cityRu;
    
        var options = {
            types: ['establishment'],
            componentRestrictions: {country: 'ru'},
        };
    
        var autocompletes = [];
    
        for (var i = 0; i < inputs.length; i++) {
            var autocomplete = new google.maps.places.Autocomplete(inputs[i], options);
            autocomplete.inputId = inputs[i].id;
            autocomplete.addListener('place_changed', fillIn);
            autocompletes.push(autocomplete);
        }
    
        function fillIn() {
            var place = this.getPlace();
            var myInput = $('#' + this.inputId);
    
            myInput.attr('data-city', place.address_components[3].long_name);
    
            myInput.on('datachange', function(){
                var localityData = myInput.data("city");
                myInput.closest('.accommodationDivs').find('.cityRu').val(localityData);
            });
    
            myInput.data('city', place.address_components[3].long_name).trigger('datachange');
    
        }
    
    }
    searchHotels();