Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jquery Autocomplete - prefill the text field

I have a autocomplete field (adapted from the geo autocomplete to find geolocations), when a user selects the location from the list I grab the lat/lon and some other info used for the search. However right now it only works if the user actually selects from the autocomplete list (as opposed to start typing and clicking enter e.g. they haven't chosen from the list).

I'm seeing the behaviour I wish to replicate on http://www.airbnb.com/, basically if you start typing a location (e.g. London) the actual textfield is pre-populated with the first entry on the list - can someone explain how this can be done with jquery autocomplete? I can set the autoFocus to true which focuses on the first field, but doesn't actually fill the text field in?

Any help appreciated.

like image 824
Xrender Avatar asked Nov 05 '22 11:11

Xrender


1 Answers

Here is a solution. It might need some tweaking to work with several autocomplete on the same page but it works with one:

(function( $ ) {

    $.extend($.ui.autocomplete.prototype, {

        _createSelection: function($input, start, end) {

            // get a reference to the input element
            var field = $input.get(0);

            // set the selection (browser specific methods)
            if( field.createTextRange ){
                var selRange = field.createTextRange();
                selRange.collapse(true);
                selRange.moveStart("character", start);
                selRange.moveEnd("character", end);
                selRange.select();
            } else if( field.setSelectionRange ){
                field.setSelectionRange(start, end);
            } else {
                if( field.selectionStart ){
                    field.selectionStart = start;
                    field.selectionEnd = end;
                }
            }

            field.focus();
        },

        _autoFill: function($input, sValue) {

            // here 'this' is the plugin itself
            // if the last user key pressed was backspace, don't autofill
            if (this._lastKeyPressCode != 8) {

                // fill in the value (keep the case the user has typed)
                $input.val($input.val() + sValue.substring(this._previousValue.length));

                // select the portion of the value not typed by the user (so the next character will erase)
                this._createSelection($input, this._previousValue.length, sValue.length);
            }
        },

        _previousValue: '',
        _lastKeyPressCode: null
    });

        $( ".ui-autocomplete-input" )
        .live( "keyup", function() {

            var $this = $(this),
                autocomplete = $this.data('autocomplete'),
                key;

            autocomplete._lastKeyPressCode = key = event.which;

            // do nothing on backslash/command keys
            if( key == 46 || (key > 8 && key < 32) )
                return autocomplete.menu.deactivate();

            // check value is different
            var v = $this.val();
            if (v == autocomplete._previousValue)
                return;

            // save value
            autocomplete._previousValue = v;

        })
        .live( "autocompleteopen", function() {

            var $this = $(this),
                autocomplete = $this.data( "autocomplete" ),
                menu = autocomplete.menu;

            // check the 'selectFirst' setting
            if ( !autocomplete.options.selectFirst ) {
                return;
            }

            // activate the menu
            menu.activate( $.Event({ type: "mouseenter" }), menu.element.children().first() );

            // set the autoFill
            autocomplete._autoFill($this, menu.element.children().first().text());
        });

    }( jQuery ));

    $('.for-autocomplete').autocomplete({selectFirst: true, source: ['aa','absolution','borinage','baba']});


To initialize the autocomplete widget, you have to add the new option selectFirst: true/false.

The autofill and createSelection methods were taken from this autocomplete plugin and the binding of the live events was inspired by this post.

Enjoy


Edit

I have adapted the code so now it fully integrates with the jQuery UI Autocomplete Widget. And it works with multiple instances of the plugin on the same page.

:o)

like image 65
Didier Ghys Avatar answered Nov 15 '22 00:11

Didier Ghys