Ben Racicot
Ben Racicot

Reputation: 5934

autocomplete list items printing HTML out

I have a simple jQuery UI autocomplete that works fine. However when I add HTML tags to the label output string they actually print out. I've replaced them with superscript html entities ² and many other tags which also print...

$('#mainSearch').autocomplete({
    appendTo: ".inputWrapper",
    minLength: 3,
    source: function (request, response) {
        var customer = new Array();
        $.ajax({
            async: false,
            cache: false,
            type: "POST",
            url: "http://localhost/EmployeeDirectory/GetEmployees",
            data: { "filterText": request.term },
            error: function (data) { console.log('Error!'); },
            success: function (data) {
                for (var i = 0; i < data.length ; i++) {
                    customer[i] = {

                        label: data[i].FullName + "<a href='#'>" + data[i].Region + '/' + data[i].District + "</a>" + data[i].Center,

                        Id: data[i].UserID,
                        encryptID: data[i].UserIDEncryted
                    };
                }
            }
        });
        response(customer);
    },
});

Displays:

enter image description here

Has anyone ever seen this happen? Not sure if its the Autocomplete, the way the string is built or response()...

UPDATE:

Here is the final code that I ended up using.

$('#mainSearch').autocomplete({
    appendTo: ".inputWrapper",
    minLength: 3,
    source: function (request, response) {
        $.ajax({
            async: false,
            cache: false,
            type: "POST",
            url: "localhost/",
            data: { "filterText": request.term },
            error: function (data) { console.log('Error!'); },
            success: function (data) {
                response(data);
            }
        });
    },
    focus: function (event, ui) {
        event.preventDefault();
        $(this).val(ui.item.FirstName + ' ' + ui.item.LastName);
    },
    select: function (event, ui) {
        console.log('object: ' + JSON.stringify(ui, null, 4));
        document.location.href = "/eCard/?uid=" + ui.item.UserIDEncrypted;
    }
}).autocomplete("instance")._renderItem = function (ul, item) {
    return $("<li>")
      .append(item.FullName + '<br /><sup>' + item.Region + '/' + item.District + ' ' + item.Center + '</sup>')
      .appendTo(ul);
};

Upvotes: 0

Views: 987

Answers (1)

blgt
blgt

Reputation: 8205

This occurs because the autocomplete widget populates its items using .text() which escapes all your html inside label. You can override _renderItem and use .html() to populate the items instead:

$.widget("my.customAutocomplete", $.ui.autocomplete, {
    _renderItem: function( ul, item ) {
        return $( "<li>" ).html( item.label ).appendTo( ul );
    }
}
$('#mainSearch').customAutocomplete({ // etc.

Keep in mind this can be xss-prone (which is the reason the default version uses .text()). Unless you're 100% confident in your server validation, you might want to manually escape the Ajax results:

label: $("<p>").text(data[i].FullName).text() +
       "<a href='#'>" +
       $("<p>").text(data[i].Region).text() + /* etc. */

Upvotes: 1

Related Questions