views:

527

answers:

2

The below code is very simple. I have a jQuery autocomplete bound to an html text input referenced by #search. When the user types something into it, a drop-out list shows suggestions from the server. If the user clicks on one of the suggestions, or presses Enter with it selected, a popup (facebox) appears showing the called page within the popup. If instead the user just wants to execute a normal search and not select a suggestion, he can do so by pressing Enter or clicking #searchButton. In other words:

  1. User types something in, e.g. grapefruit
  2. Selectable suggestions appear.
  3. Scenario 1: User selects a suggestion with mouse or keyboard, presses enter, or clicks it - causing that item to pop up, i.e. autocomplete's result .handler fires (and not .keypress)
  4. Scenario 2: User is not interested in the suggestions, and instead presses enter OR clicks on #searchButton to execute a full search on what he's typed into #search. Autocomplete's result handler does not fire, instead, either the Enter keypress triggers #searchButton's click event, or it is triggered directly (ie, actually clicked) thereby triggering a normal search.

This works beautifully in IE6, IE7, IE8, Chrome, Safari, but NOT in firefox.

In firefox, when Enter is pressed on a suggestion, both the result handler and the keypress events fire, giving the user the facebox popup, as well as executing the full search. I figured that somehow stopping .keypress from firing if .result fires would do the trick, however, I have not been able to figure out how to do so. I tried putting using jQuery's stopPropogation() and stopImmediatePropogation() into the .result handler in the hope that it would prevent .keypress from firing, but it didn't change a thing.

If anyone has any thoughts, or would like to help me through this, I would be most appreciative.

Thanks in advance!

    jQuery("#search").autocomplete("/index/suggest", {
        selectFirst: false,
        formatItem: function(data, i, n, value) {
            return "<font color='#3399CC'>" + value.split("::")[0] + "</font>";
        },
        formatResult: function(data,value) {
            return value.split("::")[0];
        }
    }).result(function(event, data, formatted) {
        alert('Hello, someone selected a suggestion by clicking on it or pressing enter on it, so you\'re getting this!');
        var pieces = formatted.split("::");
        var url = '/' + pieces[1] + '/detail/?id=' + pieces[2];
        jQuery.facebox({ ajax: url });
    }).keypress(keypressHandler).blur(function() {
        alert('I don\'t want this to appear if .result above is called, and it doesnt, except in firefox! Bah!');
        jQuery(this).flushCache();
    });

    function keypressHandler(e)
    {
        if(e.which == 13) {
            if(!jQuery('#searchButton').is(':disabled')) {
                jQuery(this).blur();
                jQuery('#searchButton').focus().click();
            }
        }
    }
A: 

In javascript you can simply:

return false;

on your event handler functions in order to stop the event from bubbling further.

Soviut
Thanks Soviut, tried it before, just tried it again, with no joy unfortunately.
karim79
+3  A: 

Have you tried unbinding the keypress event on just the search box and rebinding your own keypress handler?

jQuery("#search").autocomplete("/index/suggest", {
    selectFirst: false,
    formatItem: function(data, i, n, value) {
        return "<font color='#3399CC'>" + value.split("::")[0] + "</font>";
    },
    formatResult: function(data,value) {
        return value.split("::")[0];
    }
}).result(function(event, data, formatted) {
    alert('Hello, someone selected a suggestion by clicking on it or pressing enter on it, so you\'re getting this!');
    var pieces = formatted.split("::");
    var url = '/' + pieces[1] + '/detail/?id=' + pieces[2];
    jQuery.facebox({ ajax: url });
});

jQuery("#search").unbind("keypress").keypress(keypressHandler).blur(function() {
    alert('I don\'t want this to appear if .result above is called, and it doesnt, except in firefox! Bah!');
    jQuery(this).flushCache();
});

It could also be that there are other key events that are being handled instead in the autocomplete handler. I would think that you would want to remove all of them from the text input while leaving them on the autocomplete "list". If the events handled by autocomplete are different than keypress, you may want to remove them instead.

tvanfosson
+1 and tick. You set me on the right track. I fixed it by putting jQuery('#searchButton').attr('disabled',true) in the result handler, thereby preventing key events on #searchButton from firing after .result is called :D Thanks!
karim79