Prevent jquery-ui autocomplete from accepting words that are not in the list

Asked

Viewed 72 times

1

I want to make sure that my input autocomplete does not accept any word that is not on a list. I’m using the code below, taken from jQuery-ui’s own website 1.12.1.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>jQuery UI Autocomplete - Multiple values</title>
  <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://code.jquery.com/jquery-1.12.4.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  <script>
  $( function() {
    var availableTags = [
      "ActionScript",
      "AppleScript",
      "Asp",
      "BASIC",
      "C",
      "C++",
      "Clojure",
      "COBOL",
      "ColdFusion",
      "Erlang",
      "Fortran",
      "Groovy",
      "Haskell",
      "Java",
      "JavaScript",
      "Lisp",
      "Perl",
      "PHP",
      "Python",
      "Ruby",
      "Scala",
      "Scheme"
    ];
    function split( val ) {
      return val.split( /,\s*/ );
    }
    function extractLast( term ) {
      return split( term ).pop();
    }
 
    $( "#tags" )
      // don't navigate away from the field on tab when selecting an item
      .on( "keydown", function( event ) {
        if ( event.keyCode === $.ui.keyCode.TAB &&
            $( this ).autocomplete( "instance" ).menu.active ) {
          event.preventDefault();
        }
      })
      .autocomplete({
        minLength: 0,
        source: function( request, response ) {
          // delegate back to autocomplete, but extract the last term
          response( $.ui.autocomplete.filter(
            availableTags, extractLast( request.term ) ) );
        },
        focus: function() {
          // prevent value inserted on focus
          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;
        }
      });
  } );
  </script>
</head>
<body>
 
<div class="ui-widget">
  <label for="tags">Tag programming languages: </label>
  <input id="tags" size="50">
</div>
 
 
</body>
</html>

1 answer

0


You can add new events by checking if the typed word exists in the list, which is an array. If the word is not in the list, it is excluded from the field.

I added two events blur and mouseleave to trigger the function (see comments in the code):

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>jQuery UI Autocomplete - Multiple values</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
   <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
   <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

  <script>
  
  function remDup(){

      // remove duplicadas
      var tags = $("#tags").val().split(",");
      var dup = [];
      $.each(tags, function(i, e) {
         if($.inArray(e.trim(), dup) == -1) dup.push(e.trim());
      });
      $("#tags").val(dup.join(", "));
  }
  
  $( function() {
    var availableTags = [
      "ActionScript",
      "AppleScript",
      "Asp",
      "BASIC",
      "C",
      "C++",
      "Clojure",
      "COBOL",
      "ColdFusion",
      "Erlang",
      "Fortran",
      "Groovy",
      "Haskell",
      "Java",
      "JavaScript",
      "Lisp",
      "Perl",
      "PHP",
      "Python",
      "Ruby",
      "Scala",
      "Scheme"
    ];
    function split( val ) {
      return val.split( /,\s*/ );
    }
    function extractLast( term ) {
      return split( term ).pop();
    }
 
    $( "#tags" )
      // don't navigate away from the field on tab when selecting an item
      .on( "keydown", function( event ) {
        if ( event.keyCode === $.ui.keyCode.TAB &&
            $( this ).autocomplete( "instance" ).menu.active ) {
          event.preventDefault();
        }
      })

      // AQUI ONDE COLOQUEI A FUNÇÃO
      .on( "blur mouseleave", function(){ // capturo os eventos
         var tags = $( this ).val().split(","); // converto o valor do campo em array
         var invs = [];
         for(let item of tags){ // percorro a array da lista procurando os valores do campo
             if(availableTags.indexOf(item.trim()) != -1){ // não achou na lista
               invs.push(item);
             }
         }
         invs.push("");
         this.value = invs.join(",")+" ";

      })
      
          
      .autocomplete({
        minLength: 0,
        source: function( request, response ) {
          // delegate back to autocomplete, but extract the last term
          response( $.ui.autocomplete.filter(
            availableTags, extractLast( request.term ) ) );
        },
        focus: function() {
          // prevent value inserted on focus
          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( ", " );
          remDup();
          return false;
        }
      })
      
      remDup();
  });
  
  </script>
</head>
<body>
 
<div class="ui-widget">
  <label for="tags">Tag programming languages: </label>
  <input id="tags" value="Java, Java, C, " size="50">
  <br>
   <input type="button" value="Verificar" onclick="verificar()">
</div>
 
 
</body>
</html>

  • Okay, @dvd. I understand perfectly. Thank you very much!

  • just one more question. Now talking about duplicate values. Like, I want that when in the field there is one of the items in the list, it cannot be added again. And also if the field already starts with default values, how would you avoid duplication? Grateful!

  • @Antoniobrazfinizola I updated all the code I had placed before and added a function to remove duplicates.

  • Blz, @dvd. I’ll test it right now. Thanks again.

  • Another question, @dvd. How do I prevent the user from typing anything that is not in the table? Type, the user be required to enter some of the values in the list?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.