I'm having a lot of trouble making jQuery's autocomplete widget work for me. I am using a list of key/value pairs from a server.
I have the following requirements:
If the user selects a value from the widget, I want to pass the ID to the server.
If the user doesn't select a value and enters raw text, or modifies a value that has already been selected, I want the ID field to be cleared and just the raw text to be sent to the server.
Assume that someAjaxFunction
returns an array of objects that the autocomplete widget expects: {label:label, value:key}
.
Initially I set the autocomplete widget up like so:
$(input).autocomplete({
source: sourceFunction,
minLength: 1
});
Changing the selection even by hovering over one of the items changes the text in the text box referenced by $(input) to the underlying key, rather than the label. This is highly undesirable from a user interaction point of view - indeed, the very reason why I am investigating this is because the users of the site I am building were consistently baffled by the text they entered seemingly turning into random numbers!
I added a hidden field under the text box and implemented the select() and focus() events in order to cloak the ID like so:
$(input).autocomplete({
source: sourceFunction,
minLength: 1
focus: function(event, ui) {
$(idField).val(ui.item.value);
$(this).val(ui.item.label);
return false;
},
select: function(event, ui) {
$(idField).val(ui.item.value);
$(this).val(ui.item.label);
return false;
},
minLength: 1
});
This works well when the user is sticking to the script provided by the autocomplete drop-down. The ID is cloaked and correctly submitted to the server. Unfortunately, if the user wants to enter some freeform text into the box and search based on that value, the ID field is not reset and the previously selected ID gets submitted to the server. This is also rather confusing.
The jQuery UI Autocomplete documentation lists a change
event and states that the item
property of the ui
argument will be set to the selected item. I figured I could reset the hidden id field on a key press and re-populate the ID if the autocomplete is changed. Unfortunately, in addition to the keypress event capturing a whole bunch of keypresses that shouldn't reset the ID, the return false
statement in the above select
event which is necessary to manage the text in the text box prevents the change
event from having ui.item properly assigned.
So now I'm stuck - I don't really know what else I can try to make the widget support functionality that it seems like it should support by default. Either this process is way more complicated than it should be, or I'm missing something really obvious. I've picked through all the available events and all the examples and come up empty handed. In fact, even the "Custom data and display" example on the jQuery UI page suffers from this problem.
I can add some hacks at the server side to cover for this, but I would really prefer to be able to do this at the client level.
I would also prefer to stick to the jQuery UI autocomplete widget rather than switch to another one.