开发者

jQuery UI AutoComplete: Only allow selected valued from suggested list

开发者 https://www.devze.com 2023-02-09 20:43 出处:网络
I am implementing jQuery UI Autocomplete and am wondering if there is any way to only allow a selection from the suggested results that are returned as opposed to allowing any value to be input into t

I am implementing jQuery UI Autocomplete and am wondering if there is any way to only allow a selection from the suggested results that are returned as opposed to allowing any value to be input into the text box.

I am using this for a tagging system much like the one used on this site, so I only want to allow users to select tags from a pre-populated list returned to the开发者_如何学JAVA autocomplete plugin.


You could also use this:

change: function(event,ui){
  $(this).val((ui.item ? ui.item.id : ""));
}

The only drawback I've seen to this is that even if the user enters the full value of an acceptable item, when they move focus from the textfield it will delete the value and they'll have to do it again. The only way they'd be able to enter a value is by selecting it from the list.

Don't know if that matters to you or not.


I got the same problem with selected not being defined. Got a work-around for it and added the toLowerCase function, just to be safe.

$('#' + specificInput).autocomplete({ 
  create: function () {
    $(this).data('ui-autocomplete')._renderItem = function (ul, item) {
      $(ul).addClass('for_' + specificInput); //usefull for multiple autocomplete fields
      return $('<li data-id = "' + item.id + '">' + item.value + '</li>').appendTo(ul); 
    };
  }, 
  change:
    function( event, ui ){
      var selfInput = $(this); //stores the input field
      if ( !ui.item ) { 
        var writtenItem = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val().toLowerCase()) + "$", "i"), valid = false;

        $('ul.for_' + specificInput).children("li").each(function() {
          if($(this).text().toLowerCase().match(writtenItem)) {
            this.selected = valid = true;
            selfInput.val($(this).text()); // shows the item's name from the autocomplete
            selfInput.next('span').text('(Existing)');
            selfInput.data('id', $(this).data('id'));
            return false;
          }
        });

        if (!valid) { 
          selfInput.next('span').text('(New)');
          selfInput.data('id', -1); 
        }
    }
}


http://jsfiddle.net/pxfunc/j3AN7/

var validOptions = ["Bold", "Normal", "Default", "100", "200"]
previousValue = "";

$('#ac').autocomplete({
    autoFocus: true,
    source: validOptions
}).keyup(function() {
    var isValid = false;
    for (i in validOptions) {
        if (validOptions[i].toLowerCase().match(this.value.toLowerCase())) {
            isValid = true;
        }
    }
    if (!isValid) {
        this.value = previousValue
    } else {
        previousValue = this.value;
    }
});


This is how I did it with a list of settlements:

 $("#settlement").autocomplete({
  source:settlements,
  change: function( event, ui ) {
  val = $(this).val();
  exists = $.inArray(val,settlements);
  if (exists<0) {
    $(this).val("");
    return false;
  }
 }
});


i just modify to code in my case & it's working

selectFirst: true,
change: function (event, ui) {
        if (ui.item == null){ 
         //here is null if entered value is not match in suggestion list
            $(this).val((ui.item ? ui.item.id : ""));
        }
    }

you can try


Ajax submission and handling

This will be of use to some of you out there:

$('#INPUT_ID').autocomplete({
    source: function (request, response) {
        $.ajax({
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            url: autocompleteURL,
            data: "{'data':'" + $('INPUT_ID').val() + "'}",
            dataType: 'json',
            success: function (data) {
                response(data.d);
            },
            error: function (data) {
                console.log('No match.')
            }
        });
    },
    change: function (event, ui) {
        var opt = $(this).val();

        $.ajax({
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            url: autocompleteURL,
            data: "{'empName':'" + name + "'}",
            dataType: 'json',
            success: function (data) {
                if (data.d.length == 0) {
                    $('#INPUT_ID').val('');
                    alert('Option must be selected from the list.');
                } else if (data.d[0] != opt) {
                    $('#INPUT_ID').val('');
                    alert('Option must be selected from the list.');
                }
            },
            error: function (data) {
                $(this).val('');
                console.log('Error retrieving options.');
            }
        });
    }
});


I'm on drupal 7.38 and to only allow input from select-box in autocomplete you only need to delete the user-input at the point, where js does not need it any more - which is the case, as soon as the search-results arrive in the suggestion-popup right there you can savely set:

 **this.input.value = ''**

see below in the extract from autocomplete.js ... So I copied the whole Drupal.jsAC.prototype.found object into my custom module and added it to the desired form with

 $form['#attached']['js'][] = array(
  'type' => 'file',
  'data' => 'sites/all/modules/<modulname>_autocomplete.js',
 );

And here's the extract from drupal's original misc/autocomplete.js modified by that single line...

Drupal.jsAC.prototype.found = function (matches) {
  // If no value in the textfield, do not show the popup.
  if (!this.input.value.length) {
    return false;
  }
  // === just added one single line below ===
  this.input.value = '';

  // Prepare matches.

=cut. . . . . .


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.

//
// Extend Autocomplete
//
$.widget( "ui.autocomplete", $.ui.autocomplete, {      
   options: {
      close: function( event, ui ) {
         if (typeof event.currentTarget == 'undefined') {
            $(this).val("");
         }
      }
   }
 });


You can actually use the response event in combination to the change event to store the suggested items like so:

response: function (event, ui) {
    var list = ui.content.map(o => o.value.toLowerCase());
},
change: function (event, ui) {
    if (!ui.item && list.indexOf($(this).val().toLowerCase()) === -1 ) { $(this).val(''); 
}
0

精彩评论

暂无评论...
验证码 换一张
取 消