1

我正在使用 Bootstrap Typeahead 和 Ajax 构建一个特定的“自动完成”。

我的代码类似于:

searchInput.typeahead({
    source: function (request, response) {
        $.ajax({
            url: '/Home/AllNamesAutoComplete',
            type: 'post',
            dataType: 'json',
            data: { searchText: searchInput.val() },
            success: function (data) {
                var arr = [];
                $.each(data.AutoCompleteItemViewModel, function () {
                    arr.push(this.Name + " - <span>" + this.Position + "</span>");
                });
                return response(arr);
            }
        })
    },
    items: 6
});

在推送中,我传递了两个不同的值:this.Namethis.Position.

一切正常,但如果我输入“ S”作为第一个字母,它<span>也会呈现。我想将我的字符串作为 HTML 推送,但我仍然不知道该怎么做。

另一件事是,当用户单击自动完成中的项目时,我希望只选择Nameand 而不是Nameand Position

我想将 HTML 放入 Typeahead 源的数组中,然后我想在单击时仅在主输入中呈现特定值,而不是两者都呈现。

我看了一下“ Extend the bootstrap-typeahead in order to take an object而不是 string ”,但我无法理解它,因为它使用的是 Backbone。

4

3 回答 3

2

为在这里绊倒的人回答问题的标题。这就是扩展Bootstrap 插件的方式。(是的,我读的比标题还多)

(function ($, app) {

    var Typeahead = $.fn.typeahead.Constructor;
    Typeahead.extend = app.extend;

    app.YourCustomTypeahead = Typeahead.extend({
        highlighter: function (items) {
            // proof that it's working
            console.log('custom highlighter');
            // to call the parent just do this
            return Typeahead.prototype.highlighter.apply(this, arguments);
        }
    });

}(window.jQuery, window.YourProjectNamespace));

用法:

var typeahead = new app.YourCustomTypeahead($('selector'), { /* options */ });

在这个例子app.extend中是一个通用的扩展函数,比如 Backbone 使用的那个。

IE。(下面需要下划线)

(function (app, $) {

    // Backbone's extend function
    app.extend = function(protoProps, staticProps) {

        var parent = this;
        var child;

        // The constructor function for the new subclass is either defined by you
        // (the "constructor" property in your `extend` definition), or defaulted
        // by us to simply call the parent's constructor.
        if (protoProps && _.has(protoProps, 'constructor')) {
          child = protoProps.constructor;
        } else {
          child = function(){ return parent.apply(this, arguments); };
        }

        // Add static properties to the constructor function, if supplied.
        _.extend(child, parent, staticProps);

        // Set the prototype chain to inherit from `parent`, without calling
        // `parent`'s constructor function.
        var Surrogate = function(){ this.constructor = child; };
        Surrogate.prototype = parent.prototype;
        child.prototype = new Surrogate;

        // Add prototype properties (instance properties) to the subclass,
        // if supplied.
        if (protoProps) _.extend(child.prototype, protoProps);

        // Set a convenience property in case the parent's prototype is needed
        // later.
        child.__super__ = parent.prototype;

        return child;
    };

}(window.YourProjectNamespace, window.jQuery));
于 2013-04-30T14:35:08.670 回答
1

您可以使用 jQuery 将字符串转换为 HTML:

html = $('<div>hello</div>')[0]

Typeahead 的源函数只需要一个字符串数组。要更改这些字符串的输出,请考虑添加荧光笔功能。highlighter 函数将接受 item 参数并应返回 HTML:

searchInput.typeahead({
  source: function(request, response){
  ...
    arr.push({Name:this.Name, Position:this.Position});
  ...
  },
  highlighter: function(item){
    return "<div>"+item.Name+" - <span>"+item.Position+"<span></div>"
  },
  matcher: function(item){
    return item.Name.indexOf(this.query) > -1;
  },
  sorter: function(items){
    return items;
  },
  items:6
});

编辑:我进行了一些更改,以便源使用对象数组而不是字符串调用响应。输出 html 的格式应该在您的荧光笔功能中进行。匹配器需要能够找到对象内部的属性以与您的查询进行比较。当 typeahead 尝试对源中的字符串进行排序时,还必须覆盖 Sorter 以防止错误。

于 2012-10-04T06:54:13.647 回答
0

我相信您应该创建自己的“匹配器”方法。您可以使用原始方法作为您的基础。原始方法使用您可以在此处阅读的“~”运算符(我不知道)。

searchInput.typeahead({
  ...
  matcher: function(item){
    // maybe some ugly solution to remove <span> markup
  },
  ...
});
于 2012-10-04T17:45:49.227 回答