Thang Nguyen
Thang Nguyen

Reputation: 1151

Jquery Autocomplete for 2 input field (same class)

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?

Upvotes: 15

Views: 21868

Answers (3)

guest1
guest1

Reputation: 11

It's works for me!!! http://www.arctickiwi.com/blog/jquery-autocomplete-labels-escape-html-tags

(Just add code to your Javascript somewhere and your HTML tags won’t be escaped anymore in Autocomplete)

Upvotes: 1

Steffan
Steffan

Reputation: 41

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.

Upvotes: 4

mu is too short
mu is too short

Reputation: 434735

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.

Upvotes: 19

Related Questions