jQuery / jQueryUI升级后自动完成功能无法正常工作

时间:2013-03-01 15:41:40

标签: jquery jquery-ui autocomplete

升级jQuery和jQueryUI后,自动完成部分抛出错误:

  

SCRIPT5007:预期的对象

以下是代码:

(function($) {

$.widget("ui.fwcomplete", {

    // default options
    options: {
        baseUrl: "${querycompletion.base.url}",
        searchUrl: "",
        format: "opensearch",
        collection: "",
        highlight: false,
        minLength: 2,
        hlPre: "<b>",
        hlPost: "</b>",
        withNumbers: false,
        dataType: "jsonp"
    },
    _open: false,
    _enabled: true,

    _create: function() {
        var self = this;
        this.element.autocomplete({
            source: function(request, fn) {
                $.ajax({
                    url: self.options.baseUrl + "/complete.do",
                    dataType: self.options.dataType,
                    data: {
                        format: self.options.format,
                        q: request.term,
                        c: self.options.collection
                    },
                    success: function(data) {
                        if ($.isArray(data) && "opensearch" == self.options.format) {
                            fn(self._responseOpenSearch(data, request.term));

                        } else if ($.isPlainObject(data) && "json" == self.options.format) {
                            fn(self._responseJSON(data, request.term));
                        }
                    }
                });
            },
            minLength: this.options.minLength,
            select: function(event, ui) {
            var url = self.options.searchUrl == "" ? window.location.toString().split('?')[0] : self.options.searchUrl;
                url += "?q=" + ui.item.value;
                if (getURLParameter('sp') != 'null')
                    url += "&sp=" + getURLParameter('sp');
                window.location = url;
            },
            open: function(event, ui) {
                self._open = true;
            },
            close: function(event, ui) {
                self._open = false;
            }
        });
    },

    _responseOpenSearch: function(data, term, fn) {
        return this._unique(data[1]);
    },

    _responseJSON: function(data, term) {
        if (this.options.highlight) {
            data = this._highlight(data, term);

            if (!$.isEmptyObject(data[0])) {
                return this._unique(data);
            }
            return data;
        } else {
            return this._unique(data.suggestions[0].suggestions);
        }
    },

    _highlight: function(data, term) {
        var termregex = new RegExp("(" + term + ")", "i"),
            self = this,
            res = [];
        $(data.suggestions).each(function() {
            $(this.suggestions).each(function() {
                this.label = this.label || this.value;
                this.value = this.value || this.label;
                this.label = this.label.replace(termregex, self.options.hlPre + "$1" + self.options.hlPost);

                if (self.options.withNumbers && this.hits) {
                    this.label = this.label + " (" + this.hits + ")";
                }
                res.push({
                    label: this.label,
                    value: this.value
                });
            });
        });
        return res;
    },

    _unique: function(arr) {
        var unique = [];
        outer: for (var i = 0, len = arr.length; i < len; i++) {
            for (var j = 0, len2 = unique.length; j < len2; j++) {
                if ($.isPlainObject(arr[i]) && unique[j].label == arr[i].label) {
                    continue outer;
                } else if (unique[j] == arr[i]) {
                    continue outer;
                }
            }
            unique.push(arr[i]);
        }
        return unique;
    },

    _setOption: function(key) {
        this.element.autocomplete("option", arguments[0], arguments[1]);
        $.Widget.prototype._setOption.apply(this, arguments);
    },

    isOpen: function() {
        return this._open;
    },

    open: function() {
        this.element.autocomplete("open");
    },

    close: function() {
        this.element.autocomplete("close");
    },

    enable: function() {
        this.element.autocomplete("enable");
        this._enabled = true;
    },

    isEnabled: function() {
        return this._enabled;
    },

    disable: function() {
        this.element.autocomplete("disable");
        this._enabled = false;
    },

    destroy: function() {
        this.element.autocomplete("destroy");
        $.Widget.prototype.destroy.apply(this, arguments);
    }
});
} (jQuery));


// Replace the functionality of the jQuery autocomplete widget to
// allow inserting HTML labels rather than text-only.
(function( $ ) {
$(function() {
    $.extend($.ui.autocomplete.prototype, {
        _renderItem_orig: $.ui.autocomplete.prototype._renderItem,
        _response_orig: $.ui.autocomplete.prototype._response,

        _renderItem: function( ul, item) {
            return $( "<li></li>" )
                .data( "item.autocomplete", item )
                .append( "<a>" + item.label + "</a>" )
                .appendTo( ul );
        },

        _response: function( content ) {
            if ( !this.options.disabled && content && content.length ) {
                    content = this._normalize( content );
                    this._suggest( content );
                    this._trigger( "open" );
            } else {
                    this.close();
            }
            this.element.removeClass( "ui-autocomplete-loading" );
        }
    });
});
})(jQuery)

调试时我会看到这行代码:

fn(self._responseJSON(data, request.term));

将异常抛回我身上,我可以看到“fn”未定义。 我在这做错了什么? 我希望有人可以解决这个问题,我已经失去了它。 :(

1 个答案:

答案 0 :(得分:2)

自动完成版本1.8.18,请注意没有返回值: -

_response: function( content ) {
    if ( !this.options.disabled && content && content.length ) {
        content = this._normalize( content );
        this._suggest( content );
        this._trigger( "open" );
    } else {
        this.close();
    }
    this.pending--;
    if ( !this.pending ) {
        this.element.removeClass( "ui-autocomplete-loading" );
    }
}

自动完成版本1.10.1(最新版)

_response: function() {
    var that = this,
        index = ++requestIndex;

    return function( content ) {
        if ( index === requestIndex ) {
            that.__response( content );
        }

        that.pending--;
        if ( !that.pending ) {
            that.element.removeClass( "ui-autocomplete-loading" );
        }
    };
},

__response: function( content ) {
    if ( content ) {
        content = this._normalize( content );
    }
    this._trigger( "response", null, { content: content } );
    if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
        this._suggest( content );
        this._trigger( "open" );
    } else {
        // use ._close() instead of .close() so we don't cancel future searches
        this._close();
    }
}

你重写_response但是这个函数现在需要一个返回值,看起来你现在应该重写_response和__response