Solution for restricting input values to the source returned by autocomplete

Solution for restricting input values to the source returned by autocomplete

I spent most of my day trying to implement input "validation" on a field employing the jquery ui autocomplete feature.  I'm not experienced enough with javascript to truly understand how terrible I am at it, so please be kind.

Problem: The out of the box autocomplete examples allow users to enter anything they want into the autocompleted field.

Ideal Behavior: If, upon field exit, the value left in the field does not match what any of the items returned by the source property, clear the field and any associated inputs.  

Solution: Assign logic to change event that runs the field's current value against the cached source items

  1. /*
  2. * Setup autocomplete on field value input
  3. * caches values for validation
  4. */
  5. var $cache = {};
  6. $('input#code_dsp').autocomplete({
  7. source: function(request, response) {
  8. $.ajax({
  9. url: $('input#code_dsp').attr('data-href'),
  10. data: {
  11. field: $('select#field').val(),
  12. search: request.term
  13. },
  14. type: "POST",
  15. dataType: "json",
  16. success: function(data) {
  17. // cache data for use in change event
  18.                                         $cache = data;
  19.                                         // returned data has value in "val" property
  20.                                         // and label in "label" and "value" property
  21. response(data);
  22. }
  23. })
  24. },
  25. minLength: 2,
  26. select: function(event, ui) {
  27.                         // preferred to have actual value in hidden
  28.                         // field and leave label in main field
  29. $('input#code').val(ui.item.val);
  30. },
  31. change: function(event, ui) {
  32.                         // assume we don't have a match
  33. var $match = false;
  34.                         // for each row of objects in json object
  35. for (var $row in $cache)
  36. {
  37.                                 // is current value match to label in row?
  38. if (this.value == $cache[$row].label)
  39. {
  40.                                         // found a match, input is validated!
  41. $match = true;
  42. console.log('Found match: '+$cache[$row].label);
  43. }
  44. }
  45. if ($match == false)
  46. {
  47.                                 // uh-ohs.  No match, so clear both input#code_dsp
  48.                                 // and the corresponding hidden input#code field
  49. console.log('No match.  Clearing input values');
  50. this.value = '';
  51. $('input#code').val('');
  52. }
  53. },
  54. focus: function(event, ui) {
  55.                         // found this in another forum post 
  56.                         // keeps the mouse-over event from dropping
  57.                         // the "hovered" item into the autocompleted
  58.                         // field.
  59. return false;
  60. }
  61. });
It seems to work well in my app.  Hope this helps someone.  By the way, I'm using jquery 1.4.2 and jquery-ui 1.8.