1

I'm currently using .data( "ui-autocomplete" )._renderItem = function( ul, item ) in three places in my page. Now I need to add one more and I'm done.

But this time I get the error message

TypeError: this._renderItem(...) is undefined

The strange thing is that I only get this if my IF test is false.

 .data( "ui-autocomplete" )._renderItem = function( ul, item ) {

  // If only one row is returned and ID = 0, then return 'no result' message
  if(item.id == '0') {
    return jQuery( "<li></li>" )
        .data( "item.autocomplete", item )
        .append( "<div class='no-result'>"+ item.value + "</div>" )
        .appendTo( ul );
  }

I can't figure out why it's failing here, and not in the other 3 places. Is there a conflict somewhere?

This is my code

jQuery('#my-selector').autocomplete({
  minLength: 2,
  source: function( request, response ) {
    jQuery.ajax({
        url: callback_url,
        dataType: "json",
        data: {
                term: request.term
        },
        success: function( data ) {
          response( jQuery.map( data, function( item ) {
            return {
              id: item.id,
              value: item.name,
              name_encoded: item.name_encoded
            }
        }));
      }
    });
  },
  select: function( event, ui ) {
        return false;
  }
}).data( "ui-autocomplete" )._renderItem = function( ul, item ) {
  if(item.id == '0') {
    return jQuery( "<li></li>" )
        .data( "item.autocomplete", item )
        .append( "<div class='no-result'>"+ item.value + "</div>" )
        .appendTo( ul );
  }
};

Update

This change works. But I still don't understand why I must use a else statement here, when I'm not using it in two other autocomplete functions.

.data( "ui-autocomplete" )._renderItemData = function( ul, item ) {
        if(item.id == '0') {
                return jQuery( "<li></li>" )
                        .data( "item.autocomplete", item )
                        .append( "<div class='no-result'>"+ item.value + "</div>" )
                        .appendTo( ul );
        } else {
            return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
        }

};

Return data from query with search term some

[
  {"id":"8186","name":"Some Are Thieves"},
  {"id":"6149","name":"Somet"},
  {"id":"6150","name":"Somethin'Else from SKECHERS"}
]
Steven
  • 19,224
  • 47
  • 152
  • 257
  • http://stackoverflow.com/questions/5590776/why-am-i-getting-this-js-error – Techie Apr 01 '13 at 10:23
  • http://stackoverflow.com/questions/9513251/cannot-set-property-renderitem-of-undefined-jquery-ui-autocomplete-with-html – PSR Apr 01 '13 at 10:24

1 Answers1

6

It is because of the test, if the test fails then _renderItem does not return any value which is equivalent to returning undefined.

But _renderItem is called as given below, which causes the error since jquery attempts to set the data value to the returned value.

return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );

In your case you have to, override _renderItemData instead of _renderItem

var el = $('<my-autocomplete-element>');
var _renderItemData = el.data("ui-autocomplete")._renderItemData;
el.data("ui-autocomplete")._renderItemData = function(ul, item) {

    // If only one row is returned and ID = 0, then return 'no result' message
    if (item.id == '0') {
        return jQuery("<li></li>").data("item.autocomplete", item).data(
                "ui-autocomplete-item", item).append("<div class='no-result'>"
                + item.value + "</div>").appendTo(ul);
    } else {
        _renderItemData.apply(this, arguments)
    }
}

Demo: Plunker

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • Aha! Thanks for clearing that up. That got rid of the error message. But now it returns zero results unless I add an `else {}` statement with he first line of code you wrote. But why am I getting this now, and not in the other two places where I do the exact same check? – Steven Apr 01 '13 at 10:39
  • It might be because you are missing the default behaviour, try the update – Arun P Johny Apr 01 '13 at 10:44
  • Nope, still empty list. I've tried different variations. The only thing that works, is to put the following in the else statement `return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );`. The point I'm trying to make, is why do I need an else statement here and not in my other autocomplete functions? – Steven Apr 01 '13 at 11:08
  • can you share sample respone data – Arun P Johny Apr 01 '13 at 11:18
  • Done. I have to use `this` (and it works), otherwise autocompletes stops working. My updated code does work now. – Steven Apr 01 '13 at 11:26
  • Checkout the demo at [plunker](http://plnkr.co/edit/bBJUWsZps3eZgLjYuHZp?p=preview) – Arun P Johny Apr 01 '13 at 11:32
  • yes, you are right since now we are not overrloading `_renderItem`, it will work – Arun P Johny Apr 01 '13 at 11:56