9

Possible Duplicate:
jQuery autocomplete UI- I'd like it to start the search onfocus without the user having to type anything

jQuery UI Autocomplete

I want the options to appear as soon as my input is focused. Is there a setting for that? I tried setting minLength to 0, but it doesn't work... it still waits for a keypress.

Community
  • 1
  • 1
mpen
  • 272,448
  • 266
  • 850
  • 1,236

4 Answers4

25
$("#yourField").bind('focus', function(){ $(this).autocomplete("search"); } );

Here a jsfiddle: http://jsfiddle.net/fpHf4/2/ Updated one (for IE): http://jsfiddle.net/q9ERL/4/

As enlighted by @HoldOffHunger you must also set minLength to 0

Pierre
  • 1,322
  • 11
  • 17
  • Your fiddle links to something completely different. – mVChr Feb 07 '11 at 00:35
  • Sorry, I didnt save the fork... Thats fixed now. – Pierre Feb 07 '11 at 00:38
  • 2
    Works, but after selecting an item with the mouse it pops open a second time (I guess it's giving focus back to the element again). – mpen Feb 07 '11 at 00:41
  • Mmh? I tested it on Firefox and Chromium and it didnt pop a second time. Which browser do you use? – Pierre Feb 07 '11 at 00:54
  • Firefox 3.6.13. **Edit:** Works fine in your jsfiddle, but not on my site. Weird.. I'm going to come back to this a bit later. http://jsfiddle.net/q9ERL/ – mpen Feb 07 '11 at 04:21
  • Actually I get the same problem in IE 8.0.7600 on Windows 7 using this http://jsfiddle.net/q9ERL/ – mpen Feb 07 '11 at 17:57
  • Exact, I experience the same problem with IE. To handle this case i updated the fiddle to ckeck against the input length: http://jsfiddle.net/q9ERL/4/ – Pierre Feb 07 '11 at 18:17
  • (Note that now, the field must be empty in order to pop the guesses on focus.) – Pierre Feb 07 '11 at 18:19
  • @Pierre: Was trying to figure out if I liked it that way or not (has to be empty) but if it *isn't* empty, then it would probably only show one result anyway (the one you previously selected). So yeah, I think this is better even if it kind of side-steps the issue (the focus() event gets called when an item is selected). – mpen Feb 08 '11 at 23:45
  • 1
    This (the stackoverflow answer) didn't work for me until I added the "minLength: 0" from the jsfiddle, then it worked perfectly. – HoldOffHunger Jul 21 '16 at 15:31
2

I think u are breaking "autocomplete" utility just making a stylized select, thats the reason to wait for a keypress to have something to complete.

I know its not the anser u looking for, just remember this u trying to do just work with few options, if there are many u will get hard autocomple div load on firsts letters.

Or maybe u can have a 10 result records on ur sql query if is from this so get fast without loading all sort of results

--- I test focus bind on ie8, it fails, by the way its no a fail it does exactly what u want open div box on focus, the difference is that IE fires onFocus event whith jquery focus event, not like the others so su must evaluate on focus event if field its empty launch search , if is not just do nothing.. i hope this helps.

$("#yourField").bind('focus', function(){
  if($(this).val()!=""){ 
     $(this).autocomplete("search");
  } 
});
Camilo Lizarazo
  • 382
  • 2
  • 10
  • It's not just a stylized select because the user is still allowed to type in the box, and enter things that don't appear in the list. More like a combobox. I'm already limiting the results, so that's not an issue. – mpen Feb 07 '11 at 00:50
  • OK Mark u were right, but i edited my answer fixing the problem that IE present, just take a look.. – Camilo Lizarazo Feb 07 '11 at 04:55
  • 3
    Should be `==` not `!=` but you've got the right idea. That'll work :) Thanks. – mpen Feb 07 '11 at 18:15
0

Here's a solution that doesn't pop open the list a second time after selecting an item (as mentioned by Mark) and also works when the input box already has text:

jQuery autocomplete UI- I'd like it to start the search onfocus without the user having to type anything

Community
  • 1
  • 1
Dunc
  • 18,404
  • 6
  • 86
  • 103
  • That solution is a bit of a hack. It relies on a 300ms delay. – mpen Sep 17 '11 at 18:10
  • Agreed it's not idea, but it works - I'm open to better suggestions? – Dunc Sep 17 '11 at 18:21
  • You can see my solution. Although it does a heck of a lot more than just pop open the search. It opens it on click, or on tab, but only under certain conditions such as not being programatically triggered. I think the key to preventing the double-open is this bit `$(this).data('isOpen', true)` in the open and close events, which stores the variable on the element itself rather than using a global, which also lets you have multiple of these on the page. – mpen Sep 18 '11 at 17:04
  • Thanks for posting - I can't easily integrate your code into my solution but as you say it seems more elegant, so hopefully someone will find it useful. – Dunc Sep 18 '11 at 19:29
0

Here's my full solution (it does a few other things too):

$.fn.ajaxselect = function(options) {
    var settings = {
        delay: 300,
        sourceData: function(term) {
            return {term:term};
        },
        sourceUrl: null,
        select: function(item) {},
        html: true,
        minLength: 0,
        autoSelect: true,
        autoFocus: true,
        showOnClick: null
    };

    if(options) $.extend(settings, options);
    if(settings.showOnClick === null) settings.showOnClick = settings.minLength === 0;

    $(this).autocomplete({
        source: function(request, response) {
            var data = settings.sourceData.call(this.element[0], request.term);
            if(data === false) {
                response([]);
                return;
            }
            $.ajax({
                url: settings.sourceUrl,
                dataType: 'json',
                data: data,
                success: function(data, textStatus, $xhr) {
                    response(data);
                },
                error: function($xhr, textStatus) {
                    response([]);
                }
            });
        },
        focus: function(e, ui) {
            return false; // don't fill input with highlighted value
        },
        search: function(e, ui) {
            if(settings.minLength < 0 && e.hasOwnProperty('originalEvent')) return false;  // don't search on keypress if minLength < 0 (use with showOnClick)
            $(this).data('lastSearch', this.value);
            return true;
        },
        select: function(e, ui) {
            if(!settings.autoSelect && e.keyCode === 9) return false; // don't select highlighted item on tab unless autoSelect is enabled
            if($(this).val() === $(this).data('lastSearch')) {
                if(settings.select.call(this, ui.item) !== false) {
                    $(this).val(ui.item.value);
                }
                $(this).data('selectedValue',$(this).val()).trigger('change');
            } 
            return false;
        },
        open: function(e, ui) {
            $(this).data('isOpen', true);
        },
        close: function(e, ui) {
            $(this).data('isOpen', false);
        },
        minLength: settings.minLength,
        autoFocus: settings.autoFocus,
        delay: settings.delay,
        html: settings.html
    }).bind('change.ajaxselect', function() {
        $(this).toggleClass('ajax-selected', $(this).val() === $(this).data('selectedValue'));
    });

    if(settings.autoSelect) {
        $(this).bind('autocompletechange.ajaxselect', function(event, ui) {
            if($(this).val() !== $(this).data('selectedValue') && this.value.length > 0) {
                var self = this;
                var data = $.extend({autoSelect:1},settings.sourceData.call(this, this.value));
                $(this).addClass('.ui-autocomplete-loading');
                $.ajax({
                    url: settings.sourceUrl,
                    dataType: 'json',
                    data: data,
                    success: function(data, textStatus, $xhr) {
                        if(data.length >= 1) {
                            var item = $.ui.autocomplete.prototype._normalize(data)[0];
                            if(settings.select.call(self, item) !== false) {
                                $(self).val(item.value);
                            }
                            $(self).data('selectedValue',$(self).val()).trigger('change');
                        }
                    },
                    complete: function($xhr, textStatus) {
                        $(self).removeClass('.ui-autocomplete-loading');
                    }
                });
            }
        });
    }

    if(settings.showOnClick) {
        $(this).bind('click.ajaxselect', function(e) {
            if(!$(this).data('clickHandled') && !$(this).data('isOpen')) {
                $(this).data('clickHandled',true);
                $(this).autocomplete('search','');
            } else {
                $(this).data('clickHandled',false);
            }
        }).bind('focus.ajaxselect', function(e) {
            if(!$(this).data('clickHandled') && e.hasOwnProperty('originalEvent') && $(this).val() === this.defaultValue && !$(this).data('isOpen')) {
                $(this).data('clickHandled',true);
                $(this).autocomplete('search','');
            } else {
                $(this).data('clickHandled',false);
            }
        })
    }

    return $(this);
};
mpen
  • 272,448
  • 266
  • 850
  • 1,236