twitter bootstrap typeahead(未定义的方法'toLowerCase')

时间:2022-03-12 15:58:16

I am trying to use twitter bootstrap to get the manufacturers from my DB.

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

Because twitter bootstrap typeahead does not support ajax calls I am using this fork:

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

https://gist.github.com/1866577

https://gist.github.com/1866577

In that page there is this comment that mentions how to do exactly what I want to do. The problem is when I run my code I keep on getting:

在该页面中,有一条评论提到了如何做我想做的事情。问题是当我运行我的代码时,我继续得到:

Uncaught TypeError: Cannot call method 'toLowerCase' of undefined

未捕获的TypeError:无法调用未定义的方法'toLowerCase'

I googled around and came tried changing my jquery file to both using the minified and non minified as well as the one hosted on google code and I kept getting the same error.

我google了一下,试图将我的jquery文件更改为使用缩小和非缩小以及托管在谷歌代码上的文件,我一直得到同样的错误。

My code currently is as follows:

我的代码目前如下:

$('#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) {

    }
});

on the url field I added the

在url字段我添加了

window.location.origin

window.location.origin

to avoid any problems as already discussed on another question

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

Also before I was using $.each() and then decided to use $.map() as recomended Tomislav Markovski in a similar question

在我使用$ .each()之前,然后决定使用$ .map()作为推荐的Tomislav Markovski在一个类似的问题

Anyone has any idea why I keep getting this problem?!

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

Thank you

谢谢

9 个解决方案

#1


9  

Typeahead expect a list of string as source

Typeahead期望一个字符串列表作为源

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

In your case you want to use it with a list of objects. This way you'll have to make some changes to make it works

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

This should works :

这应该有效:

$('#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;
    }
});

#2


8  

In my case, I was getting this exact error, and it turned out that the version of Bootstrap I was using (2.0.4) did not support passing in a function to the source setting.

在我的情况下,我得到了这个确切的错误,结果发现我使用的Bootstrap版本(2.0.4)不支持将函数传递给源设置。

Upgrading to Bootstrap 2.1.1 fixed the problem.

升级到Bootstrap 2.1.1修复了问题。

#3


6  

UPDATED / REVISED LOOK AT THE ISSUE: The error you mentioned "Cannot call method 'toLowerCase' of undefined" occurred to me when I used the original Typeahead extension in bootstrap that does not support AJAX. (as you have found) Are you sure that the original typeahead extension isn't loading, instead of your revised one?

更新/修改后的问题:当我在不支持AJAX的bootstrap中使用原始的Typeahead扩展时,我提到了“无法调用方法'toLowerCase'未定义的错误”。 (正如您所发现的)您确定原始的预先版本扩展名未加载,而不是您修改后的版本吗?

I have been sucessfully using this Gist of typeahead that is a slight variation on the one you mention. Once I switched to that Gist and confirmed that the input data was good (testing that the input was a string array in an JS object, the issue went away.

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

Hope this helps

希望这可以帮助


Original answer:

原始答案:

The reason the error occurs is because the value passed into the typeahead matcher function is undefined. That is just a side effect to the real issue which occurs somewhere between your input and that matcher function. I suspect the 'manufacturers' array has a problem. Test it first to verify you have a valid array.

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

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

Here is what I am using to bind the input to typeahead. I confirmed that it works with your modified typeahead fork.

这是我用来将输入绑定到typeahead的内容。我确认它适用于你修改过的前叉。

My HTML:

我的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>

My binding JavaScript code:

我的绑定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);
        });
    }
});

#4


2  

In my case I had null values in my source array causing this error.

在我的情况下,我的源数组中有空值导致此错误。

Contrived example:

举例:

source : ["item 1", "item 2", null, "item 4"]

#5


1  

Your manufacturer objects don't have a "name" property, you should change

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

property: 'name',

to

property: 'manufacturer',

#6


1  

Have you tried using mapping variables like example below, you need to use this when you got more then one property in your object;

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

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

#7


0  

I stumbled upon this issue a while ago. I advice you to recheck configuration where you are including typeahead libraries (via main.js, app.js or config.js).

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

Otherwise, you can overwrite the latest Bootstrap version to your application library.

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

#8


0  

Try this code:

试试这段代码:

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]);
}

});

});

#9


0  

I solved this problem only updating the file bootstrap3-typeahead.min.js to the file in https://github.com/bassjobsen/Bootstrap-3-Typeahead/blob/master/bootstrap3-typeahead.min.js

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

I think most people can solve this way.

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

#1


9  

Typeahead expect a list of string as source

Typeahead期望一个字符串列表作为源

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

In your case you want to use it with a list of objects. This way you'll have to make some changes to make it works

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

This should works :

这应该有效:

$('#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;
    }
});

#2


8  

In my case, I was getting this exact error, and it turned out that the version of Bootstrap I was using (2.0.4) did not support passing in a function to the source setting.

在我的情况下,我得到了这个确切的错误,结果发现我使用的Bootstrap版本(2.0.4)不支持将函数传递给源设置。

Upgrading to Bootstrap 2.1.1 fixed the problem.

升级到Bootstrap 2.1.1修复了问题。

#3


6  

UPDATED / REVISED LOOK AT THE ISSUE: The error you mentioned "Cannot call method 'toLowerCase' of undefined" occurred to me when I used the original Typeahead extension in bootstrap that does not support AJAX. (as you have found) Are you sure that the original typeahead extension isn't loading, instead of your revised one?

更新/修改后的问题:当我在不支持AJAX的bootstrap中使用原始的Typeahead扩展时,我提到了“无法调用方法'toLowerCase'未定义的错误”。 (正如您所发现的)您确定原始的预先版本扩展名未加载,而不是您修改后的版本吗?

I have been sucessfully using this Gist of typeahead that is a slight variation on the one you mention. Once I switched to that Gist and confirmed that the input data was good (testing that the input was a string array in an JS object, the issue went away.

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

Hope this helps

希望这可以帮助


Original answer:

原始答案:

The reason the error occurs is because the value passed into the typeahead matcher function is undefined. That is just a side effect to the real issue which occurs somewhere between your input and that matcher function. I suspect the 'manufacturers' array has a problem. Test it first to verify you have a valid array.

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

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

Here is what I am using to bind the input to typeahead. I confirmed that it works with your modified typeahead fork.

这是我用来将输入绑定到typeahead的内容。我确认它适用于你修改过的前叉。

My HTML:

我的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>

My binding JavaScript code:

我的绑定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);
        });
    }
});

#4


2  

In my case I had null values in my source array causing this error.

在我的情况下,我的源数组中有空值导致此错误。

Contrived example:

举例:

source : ["item 1", "item 2", null, "item 4"]

#5


1  

Your manufacturer objects don't have a "name" property, you should change

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

property: 'name',

to

property: 'manufacturer',

#6


1  

Have you tried using mapping variables like example below, you need to use this when you got more then one property in your object;

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

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

#7


0  

I stumbled upon this issue a while ago. I advice you to recheck configuration where you are including typeahead libraries (via main.js, app.js or config.js).

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

Otherwise, you can overwrite the latest Bootstrap version to your application library.

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

#8


0  

Try this code:

试试这段代码:

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]);
}

});

});

#9


0  

I solved this problem only updating the file bootstrap3-typeahead.min.js to the file in https://github.com/bassjobsen/Bootstrap-3-Typeahead/blob/master/bootstrap3-typeahead.min.js

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

I think most people can solve this way.

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