16eee40c920d259c10ee345472708d0cc0cc3393
chmalee
  Tue Mar 3 11:25:23 2026 -0800
Adds an hg.conf defined 'popular' species list to the new search bar as a 'default' list of results upon focus of the search bar. Combines with 'recents' list. Add a chevron next to the search bar so users know the autocomplete has some default options, refs #36232

diff --git src/hg/lib/web.c src/hg/lib/web.c
index d80ba6ba4b9..acdf382ab03 100644
--- src/hg/lib/web.c
+++ src/hg/lib/web.c
@@ -942,42 +942,70 @@
  *
  * The caller CGI needs to include  jquery-ui.js and utils.js to turn this into a
  * useable search bar with autocomplete */
 {
 printf("<div class='flexContainer'>\n"); // for styling purposes
 if (isNotEmpty(labelText))
     {
     printf("<label for='%s' class='%s'>%s</label>", id, isNotEmpty(labelClassStr) ? labelClassStr : "genomeSearchLabelDefault", labelText);
     }
 printf("<div class='searchBarAndButton'>\n");
 printf("<input id='%s' type='text' ", id);
 if (isNotEmpty(placeholder))
     printf("placeholder='%s' ", placeholder);
 printf("class='%s' ", isNotEmpty(classStr) ? classStr : "genomeSearchBarDefault");
 printf("></input>\n");
+printf("<button id='%sToggle' type='button' class='genomeSearchToggle' tabindex='-1'"
+    " aria-label='Show popular assemblies'"
+    " title='Show recent and popular assemblies'>&#9660;</button>\n", id);
 if (withSearchButton)
     printf("<input id='%sButton' value='search' type='button'></input>", id);
 char *searchHelpText = "All genome searches are case-insensitive.  Single-word searches default to prefix "
 "matching if an exact match is not found. "
 "<ul id='searchTipList' class='noBullets'>"
 "<li> Force inclusion: Use a + sign before <b>+word</b> to ensure it appears in result.</li>"
 "<li> Exclude words: Use a - sign before <b>-word</b> to exclude it from the search result.</li>"
 "<li> Wildcard search: Add an * (asterisk) at end of <b>word*</b> to search for all terms starting with that prefix.</li>"
 "<li> Phrase search: Enclose 'words in quotes' to search for the exact phrase.</li>"
 "</ul>";
 printInfoIcon(searchHelpText);
 printf("</div>\n"); // the search button is grouped with the input
+// Embed popular assemblies JSON for the autocomplete dropdown
+{
+char *popularStr = cfgOptionDefault("browser.popularGenomes",
+    "hg38,hg19,mm39,mm10,rn7,danRer11,dm6,ce11,sacCer3");
+struct slName *dbNames = slNameListFromComma(popularStr);
+struct dyString *json = dyStringNew(512);
+dyStringAppendC(json, '[');
+boolean first = TRUE;
+struct slName *dbIter;
+for (dbIter = dbNames; dbIter != NULL; dbIter = dbIter->next)
+    {
+    struct dbDb *info = hDbDb(dbIter->name);
+    if (info == NULL || !info->active)
+        continue;
+    if (!first)
+        dyStringAppendC(json, ',');
+    first = FALSE;
+    dyStringPrintf(json, "{\"db\":\"%s\",\"label\":\"%s - %s (%s)\",\"commonName\":\"%s\"}",
+        info->name, info->organism, info->description, info->name, info->organism);
+    }
+dyStringAppendC(json, ']');
+printf("<script type='application/json' id='%sPopularData'>%s</script>\n", id, dyStringContents(json));
+dyStringFree(&json);
+slFreeList(&dbNames);
+}
 printf("</div>\n");
 }
 
 static char *getDbForGenome(char *genome, struct cart *cart)
 /*
   Function to find the default database for the given Genome.
 It looks in the cart first and then, if that database's Genome matches the
 passed-in Genome, returns it. If the Genome does not match, it returns the default
 database that does match that Genome.
 
 param Genome - The Genome for which to find a database
 param cart - The cart to use to first search for a suitable database name
 return - The database matching this Genome type
 */
 {