Autocomplete disallow free text entry?
Asked Answered
M

7

46

Is it possible to disallow free text entry in the JQuery UI autocomplete widget?

eg I only want the user to be allowed to select from the list of items that are presented in the autocomplete list, and dont want them to be able to write some random text.

I didn't see anything in the demos/docs describing how to do this.

http://jqueryui.com/demos/autocomplete/

I'm using autocomplete like this

$('#selector').autocomplete({
    source: url,
    minlength: 2,
    select: function (event, ui) {
        // etc
    }
Mcewen answered 25/5, 2010 at 22:49 Comment(0)
I
3

One way would be to use additional validation on form submit (if you are using a form) to highlight an error if the text isn't one of the valid option.

Another way would be to attach to the auto complete's change event which will get fired even if an options isn't selected. You can then do validation to ensure the user input is in your list or display an error if it is not.

Immunology answered 25/5, 2010 at 23:13 Comment(2)
I went with the .change() event, it was easier and quicker than trying to change the combobox solution to fit.Mcewen
@Tephrite pointed out below another answer and that worked like a charm change: function(event,ui) { if (ui.item==null) { $("#your_input_box").val(''); $("#your_input_box").focus(); } }Shifty
T
92

According to the API documentation, the change event's ui property is null if the entry was not chosen from the list, so you can disallow free text as simply as this:

$('#selector').autocomplete({
    source: url,
    minlength: 2,
    change: function(event, ui) {
        if (ui.item == null) {
          event.currentTarget.value = ''; 
          event.currentTarget.focus();
        }
    }
});
Tephrite answered 29/3, 2013 at 13:58 Comment(9)
Worked for me, nice one :)Svetlana
Worked for me also ;)Plane
change: (e, ui) -> ($ '#input_box').val('').focus() if not ui.item for the Coffeescripters.Irregularity
event.currentTarget.value = ''; event.currentTarget.focus(); any cases where this wouldn't work?Sweetsop
Best answer this is the proper way of handling it.Prepossessing
works perfect. on change autocomplete if not item selected set val to nothing. its okContinental
Should be accepted answer! I would suggest $(this).val(""); $(this).focus();Femur
This in essence "clears" the errant entered texts and sets focus "back to the box" if somebody types in a non-option then hits tab. But it does nothing if they type in a non-option and hit "enter" :| The combobox example does something like this (but shows a tooltip if invalid): jqueryui.com/autocomplete/#comboboxCastle
This solution will not work when the page loaded with default value.Patroclus
G
10

If you want the user to just get the item from the list then use autocomplete combobox.

http://jqueryui.com/demos/autocomplete/#combobox

HTH

Gunk answered 25/5, 2010 at 22:59 Comment(5)
You can still type into that, that's exactly what he said he didn't want.Letourneau
No I don't think he wants that. I think he wants to get it from the item from the list i.e. if the user starts to type "Ja" then if it lists "Java" and "Javascript" then he wants the user to select from one of them and not type "Jab" and submit.Gunk
No I said autocomplete, which implies typing is allowed. But the typing must be restricted to only items in the autocomplete list. The combobox example does exactly that.Mcewen
Combobox functionally is perfect, but the UI is bad - it looks very different from standard the < select >, so I can't use it. I will look at the example in more detail to see if the drop down button can be left out.Mcewen
I'm the one that misunderstood what he wanted then. Made an irrelevant edit to this answer so I could take back my downvote.Letourneau
I
3

One way would be to use additional validation on form submit (if you are using a form) to highlight an error if the text isn't one of the valid option.

Another way would be to attach to the auto complete's change event which will get fired even if an options isn't selected. You can then do validation to ensure the user input is in your list or display an error if it is not.

Immunology answered 25/5, 2010 at 23:13 Comment(2)
I went with the .change() event, it was easier and quicker than trying to change the combobox solution to fit.Mcewen
@Tephrite pointed out below another answer and that worked like a charm change: function(event,ui) { if (ui.item==null) { $("#your_input_box").val(''); $("#your_input_box").focus(); } }Shifty
T
0

I used the combobox module which gives you a "down arrow" button. Then to the input tag, just add the following to the input tag right around line 41 (depending on your version of the combobox http://jqueryui.com/demos/autocomplete/#combobox )

input.attr("readonly", "readonly");

Then add code so that if the user clicks the input box, it'll show the drop list.

For my purposes, I added a readonly flag that I can pass in to the module so if I need it readonly, I can turn it on/off as well.

Tenorite answered 3/5, 2012 at 17:55 Comment(0)
V
0

Old question, but here:

    var defaultVal = '';
    $('#selector').autocomplete({
        source: url,
        minlength: 2,
        focus: function(event, ui) {
            if (ui != null) {
                defaultVal = ui.item.label;
            }
        },
        close: function(event, ui) {
            $('#searchBox').val(defaultVal);
        }
    });
Vergne answered 28/8, 2012 at 21:27 Comment(0)
S
0

If you would like to restrict the user to picking a recommendation from the autocomplete list, try defining the close function like this. The close function is called when the results drop down closes, if the user selected from the list, then event.currentTarget is defined, if not, then the results drop down closed without the user selecting an option. If they do not select an option, then I reset the input to blank.

/**
 * The jQuery UI plugin autocomplete
 */
$.widget( "ui.autocomplete", $.ui.autocomplete, {
   options: {
      close: function( event, ui ) {
         if (typeof event.currentTarget == 'undefined') {
            $(this).val("");
         }
      }
   }
 });
Schoonover answered 24/10, 2019 at 13:25 Comment(2)
While this code snippet may be the solution, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.Rose
In this particular example, i extend the autocomplete ui widget to behave this way so I don't have to fix every place it occurs in my application. If you only have a few, then just define the close function and don't bother extending the widgetSchoonover
R
-1

The combobox option works well if you are using a set list, however if you have a dynamic generated list via a json get, then you can only capture the data on change.

Full example with additional parameters below.

        $("#town").autocomplete(
        {       
            select: function( event, ui ) {
                $( "#town" ).val( ui.item.value );
                return false;
            },        
            focus: function( event, ui ) {
                    $( "#town" ).val( ui.item.label );
                    return false;
                },           
            change: function(event, ui) {
                if (!ui.item) {
                    $("#town").val("");
                }
            },
            source: function(request, response) {
                $.ajax({
                    url: 'urltoscript.php',
                    dataType: "json",
                    data: {
                        term : request.term,
                        country : $("#abox").val()    // extra parameters
                    },                        
                    success: function(data) {
                        response($.map(data,function (item)
                        {                                
                            return {
                                id: item.id,
                                value: item.name
                            };
                        }));
                    }
                });
            },
            minLength: 3
            , highlightItem: true                                
        });
Reflux answered 15/1, 2017 at 16:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.