22

我正在尝试使用 twitter bootstrap 从我的数据库中获取制造商。

因为 twitter bootstrap typeahead 不支持 ajax 调用,所以我使用这个 fork:

https://gist.github.com/1866577

在那个页面中有这个评论提到了如何做我想做的事。问题是当我运行我的代码时,我不断得到:

未捕获的类型错误:无法调用未定义的方法“toLowerCase”

我四处搜索并尝试将我的 jquery 文件更改为使用缩小和非缩小以及托管在谷歌代码上的文件,但我一直收到同样的错误。

我的代码目前如下:

$('#manufacturer').typeahead({
    source: function(typeahead, query){
        $.ajax({
            url: window.location.origin+"/bows/get_manufacturers.json",
            type: "POST",
            data: "",
            dataType: "JSON",
            async: false,
            success: function(results){
                var manufacturers = new Array;
                $.map(results.data.manufacturers, function(data, item){
                    var group;
                    group = {
                        manufacturer_id: data.Manufacturer.id,
                        manufacturer: data.Manufacturer.manufacturer
                    };
                    manufacturers.push(group);
                });
                typeahead.process(manufacturers);
            }
        });
    },
    property: 'name',
    items:11,
    onselect: function (obj) {

    }
});

在 url 字段上,我添加了

window.location.origin

避免已经在另一个问题上讨论过的任何问题

同样在我使用之前$.each(),然后决定在类似的问题$.map()中使用推荐的 Tomislav Markovski

任何人都知道为什么我一直遇到这个问题?!

谢谢

4

9 回答 9

10

Typeahead 期望字符串列表作为源

$('#manufacturer').typeahead({
    source : ["item 1", "item 2", "item 3", "item 4"]
})

在您的情况下,您想将它与对象列表一起使用。这样,您必须进行一些更改才能使其正常工作

这应该有效:

$('#manufacturer').typeahead({
    source: function(typeahead, query){
        $.ajax({
            url: window.location.origin+"/bows/get_manufacturers.json",
            type: "POST",
            data: "",
            dataType: "JSON",
            async: false,
            success: function(results){
                var manufacturers = new Array;
                $.map(results.data.manufacturers, function(data){
                    var group;
                    group = {
                        manufacturer_id: data.Manufacturer.id,
                        manufacturer: data.Manufacturer.manufacturer,

                        toString: function () {
                            return JSON.stringify(this);
                        },
                        toLowerCase: function () {
                            return this.manufacturer.toLowerCase();
                        },
                        indexOf: function (string) {
                            return String.prototype.indexOf.apply(this.manufacturer, arguments);
                        },
                        replace: function (string) {
                            return String.prototype.replace.apply(this.manufacturer, arguments);
                        }
                    };
                    manufacturers.push(group);
                });
                typeahead.process(manufacturers);
            }
        });
    },
    property: 'manufacturer',
    items:11,
    onselect: function (obj) {
        var obj = JSON.parse(obj);

        // You still can use the manufacturer_id here 
        console.log(obj.manufacturer_id);

        return obj.manufacturer;
    }
});
于 2012-11-01T00:22:55.967 回答
8

就我而言,我遇到了这个确切的错误,结果证明我使用的 Bootstrap 版本(2.0.4)不支持将函数传递给source设置。

升级到 Bootstrap 2.1.1 解决了这个问题。

于 2012-09-17T03:35:35.520 回答
6

更新/修订后的问题: 当我在不支持 AJAX 的引导程序中使用原始 Typeahead 扩展时,我出现了您提到的错误“无法调用未定义的方法 'toLowerCase'”。(如您所见)您确定没有加载原始的预先输入扩展名,而不是您修改后的扩展名吗?

我已经成功地使用了这个 typeahead 的 Gist,它与你提到的稍有不同。一旦我切换到那个 Gist 并确认输入数据是好的(测试输入是 JS 对象中的字符串数组,问题就消失了。

希望这可以帮助


原答案:

发生错误的原因是传递给预输入匹配器函数的值未定义。这只是发生在您的输入和匹配器函数之间某处的实际问题的副作用。我怀疑“制造商”阵列有问题。首先测试它以验证您有一个有效的数组。

// It appears your array constructor is missing ()
// try the following in your binding code:
var manufacturers = new Array();

这是我用来将输入绑定到预先输入的内容。我确认它适用于您修改后的 typeahead fork。

我的 HTML:

<!-- Load bootstrap styles -->
<link href="bootstrap.css" rel="stylesheet" type="text/css" />
...

<input type="text" class="typeahead" name="Category" id="Category" maxlength="100" value="" />

...
<!-- and load jQuery and bootstrap with modified typeahead AJAX code -->
<script src="jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="bootstrap-modified-typeahead.js" type="text/javascript"></script>

我的绑定 JavaScript 代码:

// Matches the desired text input ID in the HTML
var $TypeaheadInput = $("#Category");  

// Modify this path to your JSON source URL
// this source should return a JSON string array like the following:
// string[] result = {"test", "test2", "test3", "test4"}
var JsonProviderUrl = "../CategorySearch";

// Bind the input to the typeahead extension
$TypeaheadInput.typeahead({
    source: function (typeahead, query) {
        return $.post(JsonProviderUrl, { query: query }, function (data) {
            return typeahead.process(data);
        });
    }
});
于 2012-06-29T00:30:14.973 回答
2

就我而言,我的源数组中有空值导致此错误。

人为的例子:

source : ["item 1", "item 2", null, "item 4"]
于 2014-03-24T04:33:18.303 回答
1

您的制造商对象没有“名称”属性,您应该更改

property: 'name',

property: 'manufacturer',
于 2012-07-18T09:18:01.447 回答
1

您是否尝试过使用下面示例中的映射变量,当您的对象中有多个属性时,您需要使用它;

source: function (query, process) {
        states = [];
        map = {};

        var data = [
            {"stateCode": "CA", "stateName": "California"},
            {"stateCode": "AZ", "stateName": "Arizona"},
            {"stateCode": "NY", "stateName": "New York"},
            {"stateCode": "NV", "stateName": "Nevada"},
            {"stateCode": "OH", "stateName": "Ohio"}
        ];

        $.each(data, function (i, state) {
            map[state.stateName] = state;
            states.push(state.stateName);
        });

        process(states);
    }
于 2013-06-24T06:40:18.053 回答
0

试试这个代码:

String.prototype.hashCode = function(){
var hash = 0;
if (this.length == 0) return hash;
for (i = 0; i < this.length; i++) {
    char = this.charCodeAt(i);
    hash = ((hash<<5)-hash)+char;
    hash = hash & hash; // Convert to 32bit integer
}
return hash;
};

var map_manufacter, result_manufacters;
$('#manufacturer').typeahead({
source: function(typeahead, query){
    $.ajax({
        url: window.location.origin+"/bows/get_manufacturers.json",
        type: "POST",
        data: "",
        dataType: "JSON",
        async: false,
        success: function(results){

            result_manufacter = [], map_manufacters = {};
            $.each(results.data.manufacturers, function(item, data){                    
                map_manufacters[data.Manufacturer.manufacturer.hashCode()] = data;
                result_manufacters.push(data.Manufacter.manufacter);
            });             
            typeahead.process(result_manufacters);                
        }
    });
},
property: 'name',
items:11,
onselect: function (obj) {
    var hc = obj.hashCode();
    console.log(map_manufacter[hc]);
}

});

于 2013-09-09T00:03:44.507 回答
0

不久前我偶然发现了这个问题。我建议您重新检查包含typeahead库的配置(通过 main.js、app.js 或 config.js)。

否则,您可以将最新的 Bootstrap 版本覆盖到您的应用程序库中。

于 2013-04-15T14:26:23.543 回答
0

我解决了这个问题,只将文件 bootstrap3-typeahead.min.js 更新到https://github.com/bassjobsen/Bootstrap-3-Typeahead/blob/master/bootstrap3-typeahead.min.js中的文件

我想大多数人都可以这样解决。

于 2015-06-19T02:17:31.510 回答