Reputation: 4572
jQuery is almost winning me. I already saw lots and lots in StackOverflow answers and I can't find a solution to my problem.
I'm using jQuery UI Autocomplete in my project, and I need render a default message if no results is returned. I'm using "_renderItem", as you can see bellow.
var autocompleteDir = $("#search");
autocompleteDir.autocomplete({
source: function (request, response) {
populate(request.term, response);
result = $.ui.autocomplete.filter(result, request.term)
var item = {};
item.type = 'loading';
item.label = "Loading..";
item.value = "";
result.unshift(item)
response(result.slice(0, 10));
}
});
autocompleteDir.data("ui-autocomplete")._renderItem = function (ul, item) {
if (item.type === "loading") {
return $('<li></li>')
.data("ui-autocomplete-item", item)
.append("<div style='text-align: center;'>" + item.label + "</div>")
.appendTo(ul);
}
};
Uncaught TypeError: Cannot read property 'type' of null
Uncaught TypeError: Cannot call method 'data' of undefined
I'm using jQuery 1.10.2 and jQuery UI 1.10.3. Someone have a good idea?
If I use this before "source":
response: function(event, ui){
if (ui.item.type === "loading"){
ui.content.push({label:"Loading",value:"Loading"})
}
}
I have the following error:
Cannot read property 'type' of undefined
If you help me solve this problem, can I use "response" to format and style my "loading" and my "none" result?
var populate = function(term, response) {
$.getJSON(
'<%= my_rails_path %>.json',
{search: term},
function(json) {
var result = [];
$.each(json, function(key, value) {
var item = {};
item.type = '';
item.label = value.name;
item.value = value.name;
result.push(item);
})
if (result.length == 0) {
var item = {};
item.type = "noResult";
item.label = "Create '" + term + "'";
item.value = term;
result.push(item)
}
response(result);
}
);
};
Now the problem is solved, but the label is literally showed, but I want that be rendered. See the code, you'll understand:
response: function(event, ui){
for(var i in ui.content){
if (ui.content[i].type==="loading"){
ui.content[i] = {
label:"<div style='text-align: center;'>Loading</div>",
value:""
}
}
}
}
Instead render "Loading" in the middle of the ui, all the string is showed to user (Loading).
Upvotes: 2
Views: 2132
Reputation: 21737
You don't need to use _renderItem
because jQuery provides an event that fires after the search returns and before the results are displayed, which you can modify to return a default value if the search return was empty. See the response event. You can do this instead:
autocompleteDir.autocomplete({
source: function (request, response) {
populate(request.term, response);
result = $.ui.autocomplete.filter(result, request.term)
var item = {};
item.type = 'loading';
item.label = "Loading..";
item.value = "";
result.unshift(item)
response(result.slice(0, 10));
},
response: function(event, ui){
if(ui.content.length === 0){
ui.content.push({label:"default",value:"value"}); /* modify to your liking */
}
}
});
Changing to this technique should solve both issues.
Edit:
In your third edit, if you want to change the value of a div somewhere else on the page, you need to do this in the response function yourself, not by returning the value in the function.
response: function(event, ui){
if(ui.content.length === 0){
$('#id-of-div-to-change').text("Loading");
}
}
Upvotes: 1