扩展Bootstrap Typeahead插件

时间:2012-10-03 08:46:16

标签: jquery twitter-bootstrap autosuggest

我正在使用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推送,但我仍然不知道该怎么做。

还有一件事是,当用户点击自动填充中的项目时,我只想选择Name而不是NamePosition

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

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

3 个答案:

答案 0 :(得分: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使用的扩展函数。

即。 (吼叫需要下划线)

(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));

答案 1 :(得分:1)

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

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

Typeahead的源函数只需要一个字符串数组。要更改这些字符串的输出,请查看添加荧光笔功能。突出显示的函数将接受一个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尝试对源内的字符串进行排序时,还必须重写分拣机以防止出错。

答案 2 :(得分:0)

我相信你应该创建自己的“匹配器”方法。您可以使用original method作为您的基础。原始方法使用“〜”运算符(我不知道),您可以阅读here

searchInput.typeahead({
  ...
  matcher: function(item){
    // maybe some ugly solution to remove <span> markup
  },
  ...
});