views:

375

answers:

1

I'm using the jQuery UI AutoComplete control (just updated to jQuery UI 1.8.1). Whenever the user leaves the text box, I want to set the contents of the text box to a known-good value and set a hidden ID field for the value that was selected. Additionally, I want the page to post back when the contents of the text box are changed.

Currently, I am implementing this by having the autocomplete select event set the hidden id and then a change event on the text box which sets the textbox value and, if necessary, causes a post back.

If the user just uses the keyboard, this works perfectly. You can type, use the up and down arrows to select a value and then tab to exit. The select event fires, the id is set and then the change event fires and the page posts back.

If the user starts typing and then uses the mouse to pick from the autocomplete options though, the change event fires (as focus shifts to the autocomplete menu?) and the page posts back before the select event has a chance to set the ID.

Is there a way to get the change event to not fire until after the select event, even when a mouse is used?

$(function() {
    var txtAutoComp_cache = {};
    var txtAutoComp_current = { label: $('#txtAutoComp').val(), id: $('#hiddenAutoComp_ID').val() };
    $('#txtAutoComp').change(function() {
        if (this.value == '') { txtAutoComp_current = null; }
        if (txtAutoComp_current) {
            this.value = txtAutoComp_current.label ? txtAutoComp_current.label : txtAutoComp_current;
            $('#hiddenAutoComp_ID').val(txtAutoComp_current.id ? txtAutoComp_current.id : txtAutoComp_current);
        } else {
            this.value = '';
            $('#hiddenAutoComp_ID').val('');
        }
        // Postback goes here
    });
    $('#txtAutoComp').autocomplete({
        source: function(request, response) {
            var jsonReq = '{ "prefixText": "' + request.term.replace('\\', '\\\\').replace('"', '\\"') + '", "count": 0 }';
            if (txtAutoComp_cache.req == jsonReq && txtAutoComp_cache.content) {
                response(txtAutoComp_cache.content);
                return;
            }
            $.ajax({
                url: 'ajaxLookup.asmx/CatLookup',
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                data: jsonReq,
                type: 'POST',
                success: function(data) {
                    txtAutoComp_cache.req = jsonReq;
                    txtAutoComp_cache.content = data.d;
                    response(data.d);
                    if (data.d && data.d[0]) { txtAutoComp_current = data.d[0]; }
                }
            });
        },
        select: function(event, ui) {
            if (ui.item) { txtAutoComp_current = ui.item; }
            $('#hiddenAutoComp_ID').val(ui.item ? ui.item.id : '');
        }
    });
});
A: 

I don't know about preventing the change event from firing, but you could easily throw some conditionals in your change event that makes sure the hidden field has been set and that the TextBox currently has a value.

Nathan Taylor
The textbox and hidden ID values are persisted from previous post backs so I can't see an easy way of determining that I've caught the current change rather than some past change that has already been handled. I guess the problem is that exiting the text box without selecting an item is valid and needs to be handled separately from exiting the text box while selecting an item and I can't work out how to determine which is happening if select fires after change.
Zarigani