3

I have a standard field in a form for location, using Google Places API.

<div><input class="input_standard fakeWaitlistCity" placeholder="Location" id="autocomplete"></input></div>

As a user types, it shows suggestions below. Is there a setting to also fill in the field with the first returned value?

This is what it currently looks like:

enter image description here

The goal here is that a user can't just type "New York". If they stop typing, the whole field will already be filled with "New York, NY, USA".

This is the ideal experience as a user types:

enter image description here

Thank you!

UPDATE - I've found this discussion about what it's called.

Here is an image from the link above, of what I'm talking about:

enter image description here

gwalshington
  • 1,418
  • 2
  • 30
  • 60

3 Answers3

5

// Bind dollar signs to query selector (IE8+)
var $ = document.querySelector.bind(document);

function preventStandardForm(evt) {
    // prevent standard form from submitting
    evt.preventDefault();
}

function autoCallback(predictions, status) {
    // *Callback from async google places call
    if (status != google.maps.places.PlacesServiceStatus.OK) {
        // show that this address is an error
        pacInput.className = 'error';
        return;
    }

    // Show a successfull return
    pacInput.className = 'success';
    pacInput.value = predictions[0].description;
}


function queryAutocomplete(input) {
    // *Uses Google's autocomplete service to select an address
    var service = new google.maps.places.AutocompleteService();
    service.getPlacePredictions({
        input: input,
        componentRestrictions: {
            country: 'us'
        }
    }, autoCallback);
}

function handleTabbingOnInput(evt) {
    // *Handles Tab event on delivery-location input
    if (evt.target.id == "pac-input") {
        // Remove active class
        evt.target.className = '';

        // Check if a tab was pressed
        if (evt.which == 9 || evt.keyCode == 9) {
            queryAutocomplete(evt.target.value);
        }
    }
}

// ***** Initializations ***** //
// initialize pac search field //
var pacInput = $('#pac-input');
pacInput.focus();

// Initialize Autocomplete
var options = {
    componentRestrictions: {
        country: 'us'
    }
};
var autocomplete = new google.maps.places.Autocomplete(pacInput, options);
// ***** End Initializations ***** //

// ***** Event Listeners ***** //
google.maps.event.addListener(autocomplete, 'place_changed', function () {
    var result = autocomplete.getPlace();
    if (typeof result.address_components == 'undefined') {
        queryAutocomplete(result.name);
    } else {
        console.log(result.address_components);
    }
});

// Tabbing Event Listener
if (document.addEventListener) {
    document.addEventListener('keydown', handleTabbingOnInput, false);
} else if (document.attachEvent) { // IE8 and below
    document.attachEvent("onsubmit", handleTabbingOnInput);
}

// search form listener
var standardForm = $('#search-shop-form');
if (standardForm.addEventListener) {
    standardForm.addEventListener("submit", preventStandardForm, false);
} else if (standardForm.attachEvent) { // IE8 and below
    standardForm.attachEvent("onsubmit", preventStandardForm);
}
// ***** End Event Listeners ***** //
<link rel="stylesheet" href="${createLinkTo(dir:'asset/vendor/bootstrap/dist/css',file:'bootstrap.css')}">
  <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places&key=AIzaSyBI9iSbSEo3h0LdqlqRFwnayYApQfmNXuE"></script>
  
   <form id="search-shop-form" class="search-form" name="searchShopForm" action="/impl_custom/index/search/" method="post">
    <label for="pac-input">Delivery Location</label>
    <input id="pac-input" type="text" placeholder="Los Angeles, Manhattan, Houston" autocomplete="off" />
    <button class="search-btn btn-success" type="submit">Search</button>
</form>

Update:

Note: According to your requirement there is any option available for google places. So you have change timeout seconds as per your requirement. I'm assuming with 300 ms i will get the suggestions in drop down.

$("#find").click(function(){
                  $("#geocomplete").trigger("geocode");
                });
          
              $(function(){
                $("#geocomplete").geocomplete()        
                
              });
            $('.autoc').bind('keyup', function(e) {   
            if(e.keyCode==13){
         $('#find').click()
            }else{
         setTimeout(function(){ 
           var inputVal = $("#geocomplete").val();
           var inpt = $("#geocomplete");
           if( inputVal != "" ){
           
            var firstRowVal = firstRowValue();
            if( firstRowVal != "" ){
             if(firstRowVal.toLowerCase().indexOf(inputVal.toLowerCase()) === 0){
              inpt.val(firstRowVal);//change the input to the first match
              inpt[0].selectionStart = inputVal.length; //highlight from end of input
              inpt[0].selectionEnd = firstRowVal.length;//highlight to the end
             }
            }
           }
          }, 300);// please change this 300 as per your internet connection speed.
         }
         });
         
         function firstRowValue() {
              var selected = '';
              // Check if any result is selected.
              if ($(".pac-item-selected")[0]) {
                selected = '-selected';
              }
         
              // Get the first suggestion's text.
              var $span1 = $(".pac-container:visible .pac-item" + selected + ":first span:nth-child(2)").text();
              var $span2 = $(".pac-container:visible .pac-item" + selected + ":first span:nth-child(3)").text();
         
              // Adds the additional information, if available.
              var firstResult = $span1;
              if ($span2) {
                firstResult += " - " + $span2;
              }
         
              return firstResult;
            }
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&key=AIzaSyBI9iSbSEo3h0LdqlqRFwnayYApQfmNXuE"></script>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
      <script src="https://ubilabs.github.io/geocomplete/jquery.geocomplete.js"></script>
      <form>
         <input id="geocomplete" type="text" placeholder="Type in an address" size="50" class="autoc"/>
         <input id="find" type="button" value="find" size="10"/>
      </form>

Hope this will helps you

reference here

Rahul Mahadik
  • 11,668
  • 6
  • 41
  • 54
  • Hi - thanks for the response! When I run your code snippet, it doesn't fill in the text input - it just has the dropdown of suggested locations. – gwalshington Mar 22 '18 at 21:14
  • @gwalshington I worked lot for this problem. But not got any solution. You can check with vue. https://jsfiddle.net/santiblanko/dqo6vr57/ – Rahul Mahadik Mar 23 '18 at 12:18
  • Hi - thanks this is an interesting solution. It looks like a placeholder, but it doesn't actually allow the 'autocomplete' functionality. If the user types `New York` and sees the rest of it in the text field, they would assume clicking submit would submit the whole string, but `,NY, USA` isn't actually present in the input field - it's a placeholder. Does that make sense? Thanks! – gwalshington Mar 23 '18 at 14:58
  • 1
    Please check this http://jsfiddle.net/RyTuV/346/ and sry, i am not getting what exactly you want. Thanks. – Rahul Mahadik Mar 23 '18 at 15:38
  • The fiddle is what I was looking for! Can you update your answer, using Google Locations, to show what you're doing in the fiddle, and I'll accept the answer. Thanks! – gwalshington Mar 23 '18 at 16:39
  • Can you please complete the question, and update your answer? Thanks – gwalshington Mar 25 '18 at 20:19
  • 1
    @gwalshington I have updated the answer after lots of efforts. i don't know is this full-fill your requirements or not. But officially there is API or documentation available in google or other places regarding which you expect – Rahul Mahadik Mar 27 '18 at 15:41
  • Hi! It's almost there. Did you run your snippet? The one in jsfiddle is what I'm looking for, but with Google Places, instead of an array of predefined strings. The snippet you put forces the first one into the input, and doesn't allow the user to keep typing if the first option isn't what they are trying to select. Does that make sense? I feel like your answer is very close, but not exactly. – gwalshington Mar 27 '18 at 16:38
  • @gwalshington have you checked 2nd snippet? It's with Google Places,not an array of predefined strings – Rahul Mahadik Mar 27 '18 at 16:40
  • yes, it's almost there, but the second snippet - it forces the cursor to the end of the string when it autofills into the input field, so the user can't keep typing if the first suggestion isn't the one they want? Does that make sense? The jsfiddle is exactly what I was looking for, but how can I do that with google places? Thanks!! – gwalshington Mar 28 '18 at 15:38
  • Sorry. It's not possible. I tried lot. Google not giving list of suggestions in any object. now we are reading suggestions from `html`. So from my side it's not possible to fulfill your requirement. Still you think like it might possible. please update answer. Thanks : ) – Rahul Mahadik Mar 28 '18 at 19:25
  • 1
    Hey - thanks for your help. I think it is possible, so I'll keep working on a solution, but I awarded you the bounty since you got the closest to the solution. Thank you very much for your help! – gwalshington Mar 29 '18 at 20:42
0

check this out! this is a google place autofill API, maybe with this you can work it. https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete

mat's
  • 49
  • 1
  • 10
  • Hi - Thank you so much!! This is actually what I'm using for the dropdown you can see in the above question. Do you know how to have the first returned option auto-complete the text field (like a google search), instead of just being dropdown options? Thank you :) – gwalshington Mar 20 '18 at 21:11
0

I looked for an effective solution regarding your request but wasn't able to find anything working through Google ( except Google itself!… =) ).

I tried to do things with jQuery and jQuery-UI… and in the end, I started over from the beginning.

Anyway, here is what I've read and want to share with you, I'm sure you'll find something interesting in all this.

About Google
Here is some answers to how google instant works:
How does Google Instant work?
https://searchengineland.com/how-google-instant-autocomplete-suggestions-work-62592

Also, Google isn't using only autocomplete, but a prediction algorithm too: https://support.google.com/websearch/answer/106230?hl=en
https://blog.google/products/search/google-search-autocomplete/

Visually, we could try to do something similar to google, and this link could be helpfull:
How to implement a google suggest-like input field?

What I'll do

Here is the snippet I ended with:

$(function() {
  var states = [
    'Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
    'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia',
    'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa',
    'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland',
    'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi',
    'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
    'New Jersey', 'New Mexico', 'New York', 'North Carolina',
    'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania',
    'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee',
    'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington',
    'West Virginia', 'Wisconsin', 'Wyoming'
  ];
  $("#tags").autocomplete({
    source: states,
    autoSelectFirst: true,
    autoFocus: true
  });
});
<head>
  <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
  <link rel="stylesheet" href="/resources/demos/style.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>

<body>
  <div class="ui-widget">
    <label for="tags">Tags: </label>
    <input id="tags">
  </div>
</body>

As we're not Google, we can't predict what the user wants to write.
So, in my snippet, they need to press enter or tab to confirm the autocomplete. It is not wise to auto-select the first hit after the user typed only two or three characters.

But, if we do auto-select anyway… Which one will be auto-selected ?
For example, when I am starting to type “New ”, the auto-selection will certainly be “New York” if we follow Google suggestion, “New Hampshire” if we're based on the alphabetical order, and it could be “New Mexico” if based on the user location.

Hope it helps, in any way.

Takit Isy
  • 9,688
  • 3
  • 23
  • 47
  • Hi - thanks so much for all the links! `As we're not Google, we can't predict what the user wants to write.` - we actually can predict what they want to write! It's a location that is stored in Google Places - the API I'm using to validate the location. Furthermore, I'm not looking for a way to guess what the user wants to type - Google Places API already does this, and appends a list like the snippet above. I'm looking for an autofill feature while they type. Thanks so much for your contribution! – gwalshington Mar 28 '18 at 15:46