98d6d1e479b2f6d1d61596d8fbcea15ac0012383 hiram Tue Feb 3 12:40:07 2026 -0800 bold highlight on the autocomplete menu search results refs #36232 diff --git src/hg/js/utils.js src/hg/js/utils.js index 4481f6713ec..26aa223a5ec 100644 --- src/hg/js/utils.js +++ src/hg/js/utils.js @@ -4788,33 +4788,63 @@ // Add a heading each time we see a new category (but not for recents) if (!allRecent && item.category && item.category !== currentCategory) { ul.append("
  • " + item.category + "
  • " ); currentCategory = item.category; } that._renderItem( ul, item ); }); }, _renderItem: function(ul, item) { // In order to use HTML markup in the autocomplete, one has to overwrite // autocomplete's _renderItem method using .html instead of .text. // http://forum.jquery.com/topic/using-html-in-autocomplete // Hits to assembly hub top level (not individial db names) have no item label, // so use the value instead + var searchTerm = this.term; + // remove special characters - the \W means remove anything + // that is not: [A-Za-z0-9_] which are 'word' == \w characters + // then eliminate runs of white space characters and trim any + // white space at the beginning or end of the string + var cleanTerm = searchTerm.replace(/\W/g, ' ') + .replace(/\s+/g, ' ') + .trim(); + var label = item.label !== null ? item.label : item.value; + + // Highlight matching search terms with bold tags + if (cleanTerm && cleanTerm.length > 0) { + // Split search term into individual words (by whitespace) + var words = cleanTerm.split(/\s+/).filter(function(word) { + return word.length > 0; // Filter out empty strings + }); + + // Apply bolding for each word separately + words.forEach(function(word) { + // Escape special regex characters in each word + var escapedWord = word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + + // Create case-insensitive regex to find all occurrences + var regex = new RegExp('(' + escapedWord + ')', 'gi'); + + // Replace matches with bolded version (preserves original case) + label = label.replace(regex, '$1'); + }); + } + console.log("label:", label); return $("
  • ") .data("ui-autocomplete-item", item) - .append($("").html((item.label !== null ? item.label : item.value))) + .append($("").html(label)) .appendTo(ul); } } ); autocompleteCat.init($("[id='"+inputId+"']"), { baseUrl: baseUrl !== null ? baseUrl : defaultSearchUrl, watermark: watermark, onSelect: selectFunction, onServerReply: onServerReply !== null ? onServerReply : processFindGenome, onError: onError, showRecentGenomes: true, enterSelectsIdentical: false }); }