I have two input fields like this:
<input name="accountCode" class="accountCode grid_2"/>
<input name="accountCode" class="accountCode grid_2"/>
I want to have an autocompleter on both of these fields. I have written the following JavaScript:
$(".accountCode").autocomplete(
{
minLength : 1,
source : function(request, response) {
$.ajax({
url : baseUrl + "Autocomplete/Account?accountCode=" + $(this).val(),
dataType : "json",
success : function(data) {
response($.map(data, function(item) {
return {
value : item.accountCode,
desc : item.accountName
}
}));
}
});
},
focus : function(event, ui) {
$(this).val(ui.item.accountCode);
return false;
},
select : function(event, ui) {
// $("#category").val( ui.item.name );
$(this).val(ui.item.value);
// $( "#project-description" ).html( ui.item.desc );
return false;
}
}).data("autocomplete")._renderItem = function(ul, item) {
return $("<li></li>").data("item.autocomplete", item).append(
"<a><strong>" + item.value + " </strong>" + item.desc + "</a>")
.appendTo(ul);
};
Of course, my server returns JSON data with 2 field: accountCode
and accountName
.
I want both inputs to use the custom renderer in _renderItem
so that this will be displayed in the list:
"<a><strong>" + item.value + " </strong>" + item.desc + "</a>"
For the first field, it works perfectly, but for second field it only displays the accountCode
from item.value
.
I've checked that the JSON received from the server is the same in both cases so the problem is in the Javascript.
Do you know why this problem exist?
Your problem is right here:
}).data("autocomplete")._renderItem
When the autocomplete widget binds to an element, each element gets its own distinct autocomplete
data value. Then, when you grab the .data('autocomplete')
to set the _renderItem
function, you'll only get one of the two distinct data objects; so the first text field gets your custom renderer but the second one stays with the default renderer.
You can see what's going on by playing with this HTML:
<div id="a"></div>
<div id="b"></div>
<div id="out"></div>
And this jQuery:
var $out = $('#out');
$out.append('<p>Setting both to {a:"a"}</p>');
$('#a').data('pancakes', { a: 'a' });
$('#b').data('pancakes', { a: 'a' });
$out.append('<p>#a.a = ' + $('#a').data('pancakes').a + '</p>');
$out.append('<p>#b.a = ' + $('#b').data('pancakes').a + '</p>');
$out.append('<p>Setting "div".a to "x"</p>');
$('div').data('pancakes').a = 'x';
$out.append('<p>#a.a = ' + $('#a').data('pancakes').a + '</p>');
$out.append('<p>#b.a = ' + $('#b').data('pancakes').a + '</p>');
And a live demo: http://jsfiddle.net/ambiguous/DM8Wv/2/
Check what the jsfiddle does and you should see what's going on.
You can iterate through the autocomplete fields and set the _renderItem
individually with something like this (untested code):
$(".accountCode").autocomplete({
//...
}).each(function() {
$(this).data('autocomplete')._renderItem = function(ul, item) {
//...
};
});
You could also bind the autocomplete widget to each element individually but keeping it all together and using each
to set the _renderItem
keeps everything nicely organized.
Very nice solution with respect to:
.each(function() {
$(this).data('autocomplete')._renderItem = function(ul, item) {
//...
};
});
The purpose of calling auto-complete with the same class is when you want to have the same help list to show up in several similar fields.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With