10

im using jqueryui autocomplete plugin with following code

$(this).autocomplete({
                source: function(request, response) {
                    $.ajax({ url: 'clinic/auto',
                    data: { 'term': this.term,'name': this.element.attr('complete')},
                    dataType: "json",
                    type: "POST",
                    success: function(data){
                        response(data);
                    }
                });
            },
            minLength: 2
        });

This display a list of all results in a dropdown.

my question is how do i get it to autocomplete work for u and highlight the added part for easier use?

do i have to code it ? or there is an already existing option for that? if i hv to do it manual how can it be done ? example pic: enter image description here

Solutions so far:

I have found this link and thisto be very usefull (monkey-patching jquery-autocomplete) to edit styling ,yet still not what i want..

Zalaboza
  • 8,899
  • 16
  • 77
  • 142

4 Answers4

19

Unfortunately, there is not an existing option for it. Fortunately, there's a pretty straightforward way to do it using the events supplied with JQuery Autocomplete. Check out this JSFiddle: http://jsfiddle.net/RyTuV/133/

As you'll notice, the relavant code you want to add uses the JQuery Autocomplete Open event:

Triggered when the suggestion menu is opened or updated.

Using this event, you can add the text of the first item in the list to what is already typed into the input filed, and then highlight from after the input text to the end of the added text:

$(this).autocomplete({
    source: function(request, response) {
                $.ajax({ url: 'clinic/auto',
                data: { 'term': this.term,'name': this.element.attr('complete')},
                dataType: "json",
                type: "POST",
                success: function(data){
                    response(data);
                }
            });
    },
    minLength: 2,
    open: function( event, ui ) {
        var firstElement = $(this).data("autocomplete").menu.element[0].children[0]
           , inpt = $('#autocomplete')
           , original = inpt.val()
           , firstElementText = $(firstElement).text();

        /*
           here we want to make sure that we're not matching something that doesn't start
           with what was typed in 
        */
        if(firstElementText.toLowerCase().indexOf(original.toLowerCase()) === 0){
            inpt.val(firstElementText);//change the input to the first match

            inpt[0].selectionStart = original.length; //highlight from end of input
            inpt[0].selectionEnd = firstElementText.length;//highlight to the end
        }
    }
});

Using this as a template, you could loop though the items in the menu to find the first match that starts with the input text, and use that to fill in and highlight, instead of only using the first item.

Rick Hanlon II
  • 20,549
  • 7
  • 47
  • 53
  • 4
    Update notice: In the current version of jquery ui, autocomplete's data is now saved as `uiAutocomplete`, so use `$(this).data("uiAutocomplete")` instead of `$(this).data("autocomplete")` – Basti Oct 18 '13 at 10:06
  • Update: `inpt = $("#autocomplete")` should be changed to `inpt = $(this)`. The `#autocomplete` id is an artifact from the JSFiddle example – Soturi Oct 13 '15 at 13:44
2

You'll need to code it yourself or see if there is a different autocomplete plugin that does this.

To code it yourself you will need to reference the response event to get the first matching result text and place it in the input box. To manipulate the selected text see this post: Selecting Part of String inside an Input Box with jQuery

Community
  • 1
  • 1
ryan
  • 6,541
  • 5
  • 43
  • 68
0

Found the answer above, but it has the dropdown from jqueryUI so i started to script my own. And decided to post it here. Working jsfiddle: https://jsfiddle.net/wb3kpxaj/

Code:

/* Need jquery to be extended with code snippet for selectrange i found somewhere, but forgot where...: */
$.fn.selectRange = function(start, end) {
  var e = document.getElementById($(this).attr('id')); // I don't know why... but $(this) don't want to work today :-/
  if (!e) return;
  else if (e.setSelectionRange) { e.focus(); e.setSelectionRange(start, end); } /* WebKit */ 
  else if (e.createTextRange) { var range = e.createTextRange(); range.collapse(true); range.moveEnd('character', end); range.moveStart('character', start); range.select(); } /* IE */
  else if (e.selectionStart) { e.selectionStart = start; e.selectionEnd = end; }
  return $(e); };

autofill=['Banana', 'Banonas', 'Appel', 'Appelpie', 'Other', 'OtherMoreSpecific', 'OtherMoreDifferent'];

$('#autofill').on('keyup', function(e) {
   unvalidInputKeys=[8,9,13,16,17,18,19,20,27,33,34,35,36,37,38,39,40,45,46,91,92,93,112,113,114,115,116,117,118,119,120,121,122,123,144,145];
  if($(this).val().length>0&&!unvalidInputKeys.includes(e.keyCode)) {
    for(i=0;i<autofill.length;i++) {
      if(autofill[i].startsWith($(this).val())) {
        userTypedLength=$(this).val().length;
        $(this).val(autofill[i]);
        $(this).selectRange(userTypedLength, autofill[i].length);
        return;
        }
      }
    }
  });
0

Works great! On mobile devices: not so much though. The first item from the menu gets selected automatically after it shows up for the first time.

To avoid this, I came up with this solution for mobile devices:

    close: function( event, ui ) {
        let firstElement =  $(this).data("uiAutocomplete").menu.element[0].children[0]
           , inpt = $(this)
           , original = inpt.val()
           , firstElementText = $(firstElement).text();

        /*
           here we want to make sure that we're not matching something that doesn't start
           with what was typed in 
        */
        if(firstElementText.toLowerCase().indexOf(original.toLowerCase()) === 0){
            inpt.val(firstElementText);//change the input to the first match

            inpt[0].selectionStart = original.length; //highlight from end of input
            inpt[0].selectionEnd = firstElementText.length; //highlight to the end
            $("#zoominmap").click(); // trigger click on mobile
        }
    },

close instead open - and a click event on a button (#zoominmap) after the highlighting.

I have the whole code wrapped in this media query btw:

if (window.matchMedia('only screen
 and (min-device-width:120px)
 and (max-device-width:767px)').matches) {
/*
mobile
*/
} else {
/*
desktop
*/
}
trashjazz
  • 62
  • 6