'Jquery Autocomplete - focus on the whole table and not only on the <li>

I got a problem that i can't resolve, even after many days of researches.

I use Autocomplete from Jquery, everything works fine except the focus. When i focus on my menu, the whole table is focus, not only 'li' by 'li'. Snippet of code:

$(document).ready(function() {
  $.ui.autocomplete.prototype._renderMenu = function(ul1, items) {
    var self = this;
    ul1.append("<table class='books'><thead><tr><th class='subtitleSearch'>BOOKS</th></thead><tbody></tbody></table>");
    $.each(items, function(index, item) {
      self._renderItemData(ul1, ul1.find("table.books tbody"), item);
    })
    ul1.append("<p class='seeMore'><a href=''>See more...</a></p>");
    ul1.append("<table class='movies'><thead><tr><th class='subtitleSearch'>MOVIES</th></thead><tbody></tbody></table>");
    $.each(items, function(index, item) {
      self._renderItemData(ul1, ul1.find("table.movies tbody"), item);
    })
    ul1.append("<p class='seeMore'><a href=''>See more...</a></p>");
    ul1.append("<table class='TVShows'><thead><tr><th class='subtitleSearch'>TV SHOWS</th></thead><tbody></tbody></table>");
    $.each(items, function(index, item) {
      self._renderItemData(ul1, ul1.find("table.TVShows tbody"), item);
    })
    ul1.append("<p class='seeMore'><a href=''>See more...</a></p>");
  };
  $.ui.autocomplete.prototype._renderItemData = function(ul, table, item) {
    return this._renderItem(table, item).data("ui-autocomplete-item", item);
  };
  $("#input_search_form").autocomplete({
      source: '/autocomplete.php',
      minLength: 3,
      focus: function(event, ui) {
        //alert("Focus Event Triggered");
      }
    })
    .autocomplete("instance")._renderItem = function(ul, item) {
      return $("<li>")
        .data("item.autocomplete", item)
        .append("<tr><td rowspan='3' class='thumbTD'><img src='" + item.cover + "' alt='Cover' class='thumb' /></td><td>" + item.label + "</td></tr><tr><td class='subtitle'>" + item.author + "</td></tr><tr><td class='subtitle'>" + item.publishedDate + "</td></tr>")
        .appendTo(ul);
    };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="viewport">
  <div id="header" class="header">
    <div class="header_top">
    </div>
  </div>
  <div id="container">
    <div class="container_search">
      <div class="search">
        <div class="search_box">
          <span class="material-icons md-36">search</span>
          <form id="search_form" class="search_form" action="autocomplete.php" method="post">
            <input id="input_search_form" placeholder="Type your search here...">
          </form>
        </div>
      </div>
    </div>
  </div>
</div>

Demo : http://www.thebitcoinstreet.com/ (don't worry about the url, this is my draft website)

Thank you in advance !



Solution 1:[1]

Consider the following example. I have added category section to the data.

$(function() {
  $.widget("custom.catcomplete", $.ui.autocomplete, {
    _create: function() {
      this._super();
      this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)");
    },
    _renderMenu: function(ul, items) {
      var that = this,
        currentCategory = "";
      $.each(items, function(index, item) {
        var li;
        if (item.category != currentCategory) {
          ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>");
          currentCategory = item.category;
        }
        li = that._renderItemData(ul, item);
        if (item.category) {
          li.attr("aria-label", item.category + " : " + item.label);
        }
      });
    }
  });

  var example = [{
    "label": "Revue des arts d\u00e9coratifs",
    "category": "Books",
    "author": "",
    "cover": "http:\/\/books.google.com\/books\/content?id=8aZaAAAAYAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
    "publishedDate": "1890"
  }, {
    "label": "Pie VI et le Directorie",
    "category": "Books",
    "author": "L\u00e9on S\u00e9ch\u00e9",
    "cover": "http:\/\/books.google.com\/books\/content?id=BXErAQAAMAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
    "publishedDate": "1894"
  }, {
    "label": "Index of Federal Specifications, Standards and Commercial Item Descriptions",
    "category": "Books",
    "author": "",
    "cover": "http:\/\/books.google.com\/books\/content?id=LbFPAAAAMAAJ&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
    "publishedDate": ""
  }, {
    "label": "Recueil g\u00e9n\u00e9ral des lois et des arr\u00eats",
    "author": "",
    "category": "Books",
    "cover": "http:\/\/books.google.com\/books\/content?id=RyFRAQAAIAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
    "publishedDate": "1933"
  }];

  $(function() {
    $("#input_search_form").catcomplete({
      source: example,
      minLength: 3
    }).catcomplete("instance")._renderItem = function(ul, item) {
      return $("<li>")
        .data("item.autocomplete", item)
        .append("<div><span class='thumbTD'><img src='" + item.cover + "' alt='Cover' class='thumb' /></span>" + item.label + "<br /><span class='subtitle'>" + item.author + "</span><br /><span class='subtitle'>" + item.publishedDate + "</span></div>")
        .appendTo(ul);
    };;
  });
});
.ui-autocomplete-category {
  font-weight: bold;
}

.ui-autocomplete .ui-menu-item .thumbTD {
  float: left;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>

<div class="viewport">
  <div id="header" class="header">
    <div class="header_top">
    </div>
  </div>
  <div id="container">
    <div class="container_search">
      <div class="search">
        <div class="search_box">
          <span class="material-icons md-36">Search</span>
          <form id="search_form" class="search_form" action="autocomplete.php" method="post">
            <input id="input_search_form" placeholder="Type your search here...">
          </form>
        </div>
      </div>
    </div>
  </div>
</div>

This creates the List without Tables.

If you really want to use Tables, try this.

$(function() {
  $.widget("custom.catcomplete", $.ui.autocomplete, {
    _create: function() {
      this._super();
      this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)");
    },
    _renderMenu: function(ul, items) {
      var that = this,
        currentCategory = "";
      $.each(items, function(index, item) {
        var li;
        if (item.category != currentCategory) {
          ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>");
          currentCategory = item.category;
        }
        li = that._renderItemData(ul, item);
        if (item.category) {
          li.attr("aria-label", item.category + " : " + item.label);
        }
      });
    }
  });

  var example = [{
    "label": "Revue des arts d\u00e9coratifs",
    "category": "Books",
    "author": "",
    "cover": "http:\/\/books.google.com\/books\/content?id=8aZaAAAAYAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
    "publishedDate": "1890"
  }, {
    "label": "Pie VI et le Directorie",
    "category": "Books",
    "author": "L\u00e9on S\u00e9ch\u00e9",
    "cover": "http:\/\/books.google.com\/books\/content?id=BXErAQAAMAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
    "publishedDate": "1894"
  }, {
    "label": "Index of Federal Specifications, Standards and Commercial Item Descriptions",
    "category": "Books",
    "author": "",
    "cover": "http:\/\/books.google.com\/books\/content?id=LbFPAAAAMAAJ&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
    "publishedDate": ""
  }, {
    "label": "Recueil g\u00e9n\u00e9ral des lois et des arr\u00eats",
    "author": "",
    "category": "Books",
    "cover": "http:\/\/books.google.com\/books\/content?id=RyFRAQAAIAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
    "publishedDate": "1933"
  }];

  $(function() {
    $("#input_search_form").catcomplete({
      source: example,
      minLength: 3
    }).catcomplete("instance")._renderItem = function(ul, item) {
      return $("<li>")
        .data("item.autocomplete", item)
        .append("<div><table><tr><td rowspan='3' class='thumbTD'><img src='" + item.cover + "' alt='Cover' class='thumb' /></td><td>" + item.label + "</td></tr><tr><td class='subtitle'>" + item.author + "</td></tr><tr><td class='subtitle'>" + item.publishedDate + "</td></tr></table></div>")
        .appendTo(ul);
    };;
  });
});
.ui-autocomplete-category {
  font-weight: bold;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>

<div class="viewport">
  <div id="header" class="header">
    <div class="header_top">
    </div>
  </div>
  <div id="container">
    <div class="container_search">
      <div class="search">
        <div class="search_box">
          <span class="material-icons md-36">Search</span>
          <form id="search_form" class="search_form" action="autocomplete.php" method="post">
            <input id="input_search_form" placeholder="Type your search here...">
          </form>
        </div>
      </div>
    </div>
  </div>
</div>

To add an "See More" type of link may take more work. This requires knowing when the category is changing or where to inject that link. Can try to inject it before the new category item is added. Can also inject it after the menu is complied.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Twisty