twitter bootstrap typeahead (method 'toLowerCa

2020-03-01 05:25发布

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

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

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

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.

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

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

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

Thank you

9条回答
混吃等死
2楼-- · 2020-03-01 05:28

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);
    }
查看更多
The star\"
3楼-- · 2020-03-01 05:39

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?

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.

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.

// 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.

My 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:

// 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);
        });
    }
});
查看更多
Juvenile、少年°
4楼-- · 2020-03-01 05:41

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楼-- · 2020-03-01 05:42

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

property: 'name',

to

property: 'manufacturer',
查看更多
时光不老,我们不散
6楼-- · 2020-03-01 05:43

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

I think most people can solve this way.

查看更多
对你真心纯属浪费
7楼-- · 2020-03-01 05:44

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

});

查看更多
登录 后发表回答