【问题标题】:Extend Bootstrap Typeahead plugin扩展 Bootstrap Typeahead 插件
【发布时间】:2013-04-30 22:35:08
【问题描述】:

我正在使用 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”作为第一个字母,它也会呈现&lt;span&gt;。我想将我的字符串作为 HTML 推送,但我仍然不知道该怎么做。

还有一件事是,当用户单击自动完成中的项目时,我希望仅选择 Name 而不是 NamePosition

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

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

【问题讨论】:

  • 如果您不介意使用自定义 fork,可以尝试包含此功能的 my version

标签: jquery twitter-bootstrap autosuggest


【解决方案1】:

为遇到这里的人回答问题的标题。这就是您扩展 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));

【讨论】:

    【解决方案2】:

    您可以使用 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 以防止错误。

    【讨论】:

    • 但是如何将 this.Name 与 this.Position 分开?
    • 我编辑了我的示例以使用对象数组而不是字符串
    • 您的解决方案非常完美!但是只有一个问题:在&lt;li&gt; data-value=" ... " 返回[object Object]... 解决了这个问题就完美了!
    • 我正在尝试使用 'select' 和 updater 的不同解决方案,但还没有……你知道如何解决吗?
    【解决方案3】:

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

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

    【讨论】:

    • 我不需要删除 span... 我需要添加 span... 并且 Cezary Wojtkowski 发布的解决方案效果很好,但是不会在li 中上传data-value,所以当我从列表中选择某些内容时,它只会呈现[object object]
    猜你喜欢
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    相关资源
    最近更新 更多