Autocomplete JQuery shows all the results without filtering them

Viewed 41

This jQuery autocomplete code show all options, regardless of what is typed in the input field. How are the displayed options limited to items based on what it typed?

jQuery(document).ready(function($) {
  $("#inputfield").autocomplete({
    minLength: 0,
    source: function(request, response) {
      var data = $.map(resultUsers, function(value, key) {
        return {
          label: value.name + " - " + value.city,
          value: value.name
        }
      });
      response(data);
    }
  }).focus(function() {
    $(this).autocomplete("search", "");
  });
});
  <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
  <script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<input id="inputfield">

1 Answers
  1. Remove function(request, response) { ... } response(data); "wrapper", and
  2. Add filter overwrite.

jQuery(document).ready(function($) {
  $("#inputfield").autocomplete({
    minLength: 0,
    source: $.map(resultUsers, function(value, key) {
      return {
        label: value.name + " - " + value.city,
        value: value.name
      }
    })
  }).focus(function() {
    $(this).autocomplete("search", "");
  });
});

const resultUsers = [
  {"name": "one", "city": "hey"}, {"name": "two", "city": "ya"}
];

// CREDIT: https://stackoverflow.com/a/19053987/2743458
$.ui.autocomplete.filter = function(array, term) {
  var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(term), "i");
  return $.grep(array, function(value) {
    return matcher.test(value.label || value.value || value);
  });
};
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<input id="inputfield">

Including the ui filter overwrite is only necessary to restrict limiting the results to items start with what is typed.

Credit for "starts with" filter: https://stackoverflow.com/a/19053987/2743458


Looking at @cbroe 's final comment on the question—when a callback is assigned to the source property the response() function displays the suggested options after filtering.

So the source callback also needs to filter the potential options, and reformat them into the label/value return object. jQuery map() function can do both:

jQuery(document).ready(function($) {
  $("#inputfield").autocomplete({
    minLength: 0,
    source: function (req, res) {
      let data = $.map(resultUsers, function(value, key) {
      
        // FILTER to include options that start with search term
        if ( 0 === value.name.indexOf(req.term) ) {
        
          // MAP to label/value object
          return { // <-- reformat
            label: value.name + " - " + value.city,
            value: value.name
          }
        } else { return null; }
      });
      res(data);
    }
  }).focus(function() {
    $(this).autocomplete("search", "");
  });
});

const resultUsers = [
  {"name": "one", "city": "hey"}, {"name": "two", "city": "ya"}
];
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<input id="inputfield">

No need to modify the $.ui.autocomplete.filter() function, as in the solution above.

Related