Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent selecting google autocomplete to put my value to the input?

I'm using Google Autocomplete and want to put street number + route value to the input field after selecting necessary location. I'm using this code

let options = { types: ['address'] };
let autocomplete = new google.maps.places.Autocomplete(element, options);
autocomplete.addListener('place_changed', function () {
    let place = autocomplete.getPlace();
    let components = new AutoCompleteAddressComponent(place.address_components).parse();

    /* getStreet is returning address_components.street_number.short_name
       and address_components.route.long_name */
    let streetName = components.getStreet().trim();
    $(element).val(streetName);
});

And how this code is working:

  1. User it typing something in the input
  2. Google is suggesting location from where users are selecting necessary one
  3. Input is reflecting on the user action and putting data. For example 777 Brockton Avenue, Abington, MA, USA
  4. After this place_changed is firing and 777 Brockton Avenue, Abington, MA, USA replacing to 777 Brockton Avenue

I don't like that 4-th point where users can see how data is replacing from long address to the short one.

Is there any way to show street number + route right after selecting location from the dropdown? I've tried to play with an Autocomplete method options by providing different types, but nothing helps me. I also need to get all data like country, state, city, post_code in the autocomplete.getPlace() object (I'm pre-filling these fields on the site).

like image 921
alexey-novikov Avatar asked Dec 05 '25 08:12

alexey-novikov


1 Answers

I've found solution by using Google Places Autocomplete Service and completely redesign of the Autocomplete widget

Here is a source code if someone will try to implement this service:

registerGoogleAutoComplete = function(input) {
  let options = { types: ['address'] };
  const autocomplete = new google.maps.places.AutocompleteService();

  // building container for the prediction list
  const predictionList = this.predictionListMarkup(input);
  $(input).parent().append(predictionList);
  
  /* listening the input changing event and send data to the Google Service 
  to get prediction list */
  input.addEventListener('input', function () {
      // display list if something have
      if (input.value) {
          predictionList.style.display = 'block';
          /* here is a main call of the getPlacePredictions where your input 
             value is sending to the Google Service 
             (input option of the getPlacePredictions method)  */
          autocomplete.getPlacePredictions({
              input: input.value,
              types: options.types,
          }, function (predictions, status) {
              self.displayPredictionSuggestions(predictions, status, predictionList, input);
          });
       } else {
           // hide if not
           predictionList.style.display = 'none';
       }
   });
}

/**
 * @param autocompleteFormField
 * @returns {HTMLUListElement}
 */
 this.predictionListMarkup = function (autocompleteFormField) {
     const predictionsWrapperDiv = document.createElement(`ul`);
     predictionsWrapperDiv.classList.add(`pac-container`, `pac-logo`);
     predictionsWrapperDiv.style.display = 'none';
     predictionsWrapperDiv.style.width = autocompleteFormField.clientWidth + 'px';

     return predictionsWrapperDiv;
  };

  this.displayPredictionSuggestions = function (predictions, status, predictionList, autocompleteFormField) {
      if (status !== google.maps.places.PlacesServiceStatus.OK) {
          predictionList.style.display = `none`;
          return;
      }
      predictionList.innerHTML = '';

     /* this is a list of all predictions from the Google API. Each prediction
        is a default Place object of the Google. So you can parse `address_component` and pre-fill whatever you want  */
      for (let prediction of predictions) {
          self.predictionBuilder(prediction, predictionList, autocompleteFormField);
      }

      // here you can bind all necessary events like keyDownPress, keyUpPress to control your prediction list more
  }

   // this is a each prediction element UI building function
    this.predictionBuilder = function (prediction, predictionList, autocompleteFormField) {
        // we are creating li item to the ul container
        const predictionListItem = document.createElement(`li`);
        predictionListItem.classList.add(`pac-item`);

        let text = prediction.description;
        /* prediction has an matched_substrings, using which you can make matched string words bold (as Google is doing it)  */
        if (prediction.matched_substrings.length > 0) {
            let tmp = text;
            prediction.matched_substrings.forEach(function (item) {
                let substrText = tmp.substring(item.offset, item.length + item.offset);
                text = text.replace(substrText, '<span class="pac-matched">' + substrText + '</span>');
            })
        }

        let node = document.createElement('div');
        node.innerHTML = text;
        predictionListItem.appendChild(node);

        /* add 'onClick' event listener to handle user selecting action 
           where you can act the same is `place_changed` event of the Autocomplete service  */
        predictionListItem.addEventListener(`click`, function () {
            self.autocompleteServiceListener(prediction, predictionList, autocompleteFormField);
        });

        predictionList.appendChild(predictionListItem);
    };

P.s: Later I'll try to write a small component/widget for this

like image 109
alexey-novikov Avatar answered Dec 07 '25 21:12

alexey-novikov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!