Autocomplete: how to get automatically value on focus if no values selected
Asked Answered
G

1

1

From the comment in this question, I've seen how to set an autocomplete field to empty if no element from the list has been selected.

What I am trying to implement is that when a user does not select any element from the autocomplete list and switches to the next field, one of the following should happen:

  • If there was at least on element displayed in the autocomplete list, take automatically the first element of that list. In the screenshot below, Mannheim should be automatically selected if the user goes to another field without selecting any element.

    Mannheim should be selected if the user does not click on any item and goes to the next field of the form

  • If no element was displayed, make the field empty again.

    Empty field if the user switched to another field

If tried the suggestions from here and here, but without success.

This is my code:

var cities = //function that provides a list of cities depending on the input string (edited to clarify)

$('.autocomplete-city').autocomplete({
    source: function (request, response) {
       response($.map(cities( request.term ), function (value, key) {
            return {
                label: value.label,
                value: value.value
            }
        }));
    },

    // manage what happens if user does not click any option from autocomplete
    change: function(event, ui){
        if (ui.item == null){
            if ( list_from_autocomplete == null ){ // I tried here several possibilities but none seem to work
                $(this).val('');
                $(this).focus();
            } else {
                $(this).val( first_item_in_list ); // Despite the existing questions, I could not make it work...
            }
        }
    },
    minLength: 2,
    autoFocus: true,
});

How could this be done?

Gardening answered 16/6, 2017 at 14:36 Comment(0)
W
2

You could search all the cities that contains the user input and if you get only one result, put it in the autocomplete.

1) So, in the change event you could check if user selected an item:

change: function(event, ui){
    if(ui.item){
      //user select an item
    }
    else{
      //here let's try to set the autocomplete
    }

2) Search the cities that contains the user's input:

var result = cities.filter(function( obj ) {
    return obj.label.indexOf(searched);
  });

3) Finally, if you get just one result, set the autocomplete with that value:

if(result.length==1){
    $(this).val(result[0].label);
}

Please see following snippet:

var cities = [
  {"label":"Alessandria","id":"AL"},
  {"label":"Milano","id":"MI"},
  {"label":"Pisa","id":"PI"},
  {"label":"Pistoia","id":"PT"}
];

$(".autocomplete-city").autocomplete({
  source: cities,
  select: function(event, ui){
    if(ui.item){
      console.log('select', ui.item.label);
      return ui.item.label;
    }
    else{
      console.log('select with null value');
    }
  },
  change: function(event, ui){
    var searched = this.value;
    console.log("Searched: " + searched);
    if(ui.item){
      console.log('change', ui.item.id);
    }
    else{
      console.log('change with null value');
      var result = cities.filter(function( obj ) {
        return obj.label.toLowerCase().indexOf(searched.toLowerCase()) !== -1;
      });
      if(result.length>0){
        $(this).val(result[0].label);
      }
      else{
        //clear the autocomplete
        $(this).val("");
      }
    }
  }
});
<link href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet" type="text/css" />
    <script src="https://code.jquery.com/jquery-1.11.3.js"></script>
    <script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>

<input class="autocomplete-city"/>

In the above example there are following cities: Alessandria, Milano, Pisa, Pistoia.

  • If you digit in textbox "Mil" or "Ale" and just press the tab, the autocomplete will be filled with the single result starting with "Mil" or "Ale".
  • Instead, when you digit "Pis" the autocomplete will be cleared.

I hope it was clear, bye.

Updated: In order to get the first result when user leaves the autocomplete without selecting any city, you could check result.length>0 and set the first value from result in to the autocomplete:

var result = cities.filter(function( obj ) {
        return obj.label.toLowerCase().indexOf(searched.toLowerCase()) !== -1;
      });
      if(result.length>0){
        $(this).val(result[0].label);
      }
      else{
        //clear the autocomplete
        $(this).val("");
      }
Walston answered 16/6, 2017 at 15:5 Comment(5)
Thanks for the reply. Maybe I did not explain it good enough, but I would need that if the user types "Pis" and then moves to another field, the first value of this list is taken. If the user types "Rom", then it should be empty, as Rome is not on the list.Gardening
Oh, so you could get always the first result, I'll update the snippetWalston
The approach is clever and with a simple list as a source it works. Unfortunately, my source is not a simple array but a function that has as argument var cities, which is another function. Then, I get an error in the following line: var result = cities.filter(function( obj )Gardening
OK. Investigating a bit more I managed to make it work with your approach! Grazie mille! The trick was that cities was stored as a function, not as the list that the function was returning. See here how to store the return value of the function instead of the function instead.Gardening
I'm glad it helped you. ByeWalston

© 2022 - 2024 — McMap. All rights reserved.