Search code examples
jqueryjquery-ui-autocomplete

jQuery autocomplete filtering issue


This is my code. I am trying to search only if user enter "[" symbol. But user can enter normal words also like hello.

Example : Hello - no need to autocomplete. [Hello] - need to autocomplete.

Here is the jsfiddle sample

function split(val) {
  return val.split(/,\s*/);
}

function extractLast(term) {
  return split(term).pop();
}

var availableTags = [
  "[Hello]",
  "[Hello World]",
  "[Google",
  "[New Life]",
  "[World]",
  "[Old]"
];
$("#tags").autocomplete({
  source: function(request, response) {
    // delegate back to autocomplete, but extract the last term
    response($.ui.autocomplete.filter(
      availableTags, extractLast(request.term)));
  },
  select: function(event, ui) {
    var terms = split(this.value);
    // remove the current input
    terms.pop();
    // add the selected item
    terms.push(ui.item.value);
    // add placeholder to get the comma-and-space at the end
    terms.push("");
    this.value = terms.join("  ");
    return false;
  }
});
<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js" jq=""></script>
<script type="text/javascript" src="//code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">

<div class="ui-widget">
  <label for="tags">Search: </label>
  <input type="text" id="tags" onkeypress="edValueKeyPress()" />
</div>


Solution

  • You can update your source callback to use response like below. Get lastTerm and check if it starts with [ then only return filtered results else return empty which will not display any results in autocomplete.

    As per comment it was not working for 2nd selection from autocomplete, you need to add focus callback which would be similar to select with little change that it will not have one line terms.push("");.

    source: function(request, response) {
      let lastTerm = extractLast(request.term);
      if (lastTerm.trim().startsWith('[')) {
        // delegate back to autocomplete, but extract the last term
        response($.ui.autocomplete.filter(availableTags, lastTerm));
      } else {
        response([]);
      }
    },
    focus: function(event, ui) {
      var terms = split(this.value);
      // remove the current input
      terms.pop();
      // add the selected item
      terms.push(ui.item.value); 
      // terms.push(""); <-- comment this line from select   
      this.value = terms.join(", ");
      return false;
    }
    

    Try it below.

    function split(val) {
      return val.split(/,\s*/);
    }
    
    function extractLast(term) {
      return split(term).pop();
    }
    
    var availableTags = [
      "[Hello]",
      "[Hello World]",
      "[Google",
      "[New Life]",
      "[World]",
      "[Old]"
    ];
    
    $("#tags").autocomplete({
      source: function(request, response) {
        let lastTerm = extractLast(request.term);
        if (lastTerm.trim().startsWith('[')) {
          // delegate back to autocomplete, but extract the last term
          response($.ui.autocomplete.filter(availableTags, lastTerm));
        } else {
          response([]);
        }
      },
      focus: function(event, ui) {
         var terms = split(this.value);
        // remove the current input
        terms.pop();
        // add the selected item
        terms.push(ui.item.value);
        // terms.push(""); <-- comment this line from select
        this.value = terms.join(", ");
        return false;
      },
      select: function(event, ui) {
        var terms = split(this.value);
        // remove the current input
        terms.pop();
        // add the selected item
        terms.push(ui.item.value);
        // add placeholder to get the comma-and-space at the end
        terms.push("");
        this.value = terms.join(", ");
        return false;
      }
    });
    
    function edValueKeyPress() {}
    <script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js" jq=""></script>
    <script type="text/javascript" src="//code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
    <link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
    <div class="ui-widget">
      <label for="tags">Search: </label>
      <input type="text" id="tags" onkeypress="edValueKeyPress()" />
    </div>