Oliver
Oliver

Reputation: 320

jquery ui autocomplete multiple "response" methods

Let's see if I can explain it well...I have a function that sets common options for my autocompletes (minLength, delay, close, response...). But one of my autocompletes needs to do some extra work on response method. How can I execute "original common response function" and the extra work? Is it possible without extending the widget?

function attachAutocomplete_Common(arControlIds) {
    $.each(arControlIds, function (i, control) {
        $("#" + control).autocomplete({
            minLength: 3,
            delay: 800,
            autoFocus: true,
            focus: function (event, ui) {
                $(this).val(ui.item.label);
                return false;
            },
            response: function (event, ui) {
                if (ui.content != null && ui.content.length === 1) {
                    $(this).data("ui-autocomplete").term = null;
                    $(this).data("ui-autocomplete")._trigger("select", "autocompleteselect", { item: ui.content[0] });
                    $(this).autocomplete("close");
                }
            }
        });
    });
}

$(document).ready(function () {
    attachAutocomplete_Common(["cmbCountry", "cmbCity", "cmZipCode"]);

    $("#cmZipCode").autocomplete({
        response: function (event, ui) {
            [execute common response function];
            doSomeExtraWork();
        }
    });
}); 

Upvotes: 0

Views: 481

Answers (2)

Risadinha
Risadinha

Reputation: 16666

Put the common code into its own function, outside of the widget. Then call it from both locations - from response inside attachAutocomplete_Common and from the one for #cmZipCode:

var commonResponse = function (event, ui) {
    if (ui.content != null && ui.content.length === 1) {
        $(this).data("ui-autocomplete").term = null;
        $(this).data("ui-autocomplete")._trigger("select", "autocompleteselect", { item: ui.content[0] });
        $(this).autocomplete("close");
    }
};

function attachAutocomplete_Common(arControlIds) {
    $.each(arControlIds, function (i, control) {
        $("#" + control).autocomplete({
                // ommitted, see above
            },
            response: commonResponse.bind(this)
        });
    });
}

$(document).ready(function () {
    attachAutocomplete_Common(["cmbCountry", "cmbCity", "cmZipCode"]);

    $("#cmZipCode").autocomplete({
        response: function (event, ui) {
            commonResponse.bind(this)(event, ui);
            doSomeExtraWork();
        }
    });
});

EDIT: The scoping issue: either like in the other answer, or by binding. I've updated the code. I haven't tried whether binding the function in the each loop like shown is enough.

Upvotes: 1

Oliver
Oliver

Reputation: 320

Based on Risadinha answer I made it work. There was an error when trying to access "this" inside "commonResponse" function. Here is the working code.

var commonResponse = function (event, ui, $ctl) {
    if (ui.content != null && ui.content.length === 1) {
        var $self = $ctl || $(this);

        $self.data("ui-autocomplete").term = null;
        $self.data("ui-autocomplete")._trigger("select", "autocompleteselect", { item: ui.content[0] });
        $self.autocomplete("close");
    }
};

function attachAutocomplete_Common(arControlIds) {
    $.each(arControlIds, function (i, control) {
        $("#" + control).autocomplete({
                // ommitted, see above
            },
            response: commonResponse
        });
    });
}

$(document).ready(function () {
    attachAutocomplete_Common(["cmbCountry", "cmbCity", "cmbZipCode"]);

    $("#cmbZipCode").autocomplete({
        response: function (event, ui) {
            commonResponse(event, ui, $(this));
            doSomeExtraWork();
        }
    });
}); 

Upvotes: 0

Related Questions