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/hgSearch/hgSearch.c src/hg/hgSearch/hgSearch.c index b14ffde25de..f3d0cb81ec2 100644 --- src/hg/hgSearch/hgSearch.c +++ src/hg/hgSearch/hgSearch.c @@ -490,40 +490,70 @@ } jsonElementSaveCategoriesToCart(db,jel); } void doCartJson() /* Register functions that return JSON to client */ { struct cartJson *cj = cartJsonNew(cart); cartJsonRegisterHandler(cj, "getSearchResults", getSearchResults); cartJsonRegisterHandler(cj, "getUiState", getUiState); cartJsonRegisterHandler(cj, "saveCategoriesToCart", doSaveCategoriesToCart); cartJsonRegisterHandler(cj, "getChromName", getChromName); cartJsonExecute(cj); } +static void printPopularDataJson() +/* Emit a <script type='application/json' id='genomeSearchPopularData'> block + * with the same format as printGenomeSearchBar() in web.c, so that + * setupGenomeSearchBar() in utils.js can show Popular items on empty input. */ +{ +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='genomeSearchPopularData'>%s</script>\n", dyStringContents(json)); +dyStringFree(&json); +slFreeList(&dbNames); +} + void doMainPage() /* Print the basic HTML page and include any necessary Javascript. AJAX calls * will fill out the page later */ { char *database = NULL; char *genome = NULL; getDbAndGenome(cart, &database, &genome, oldVars); webStartGbNoBanner(cart, database, "Search Disambiguation"); printMainPageIncludes(); jsInlineF("var hgsid='%s';\n", cartSessionId(cart)); +printPopularDataJson(); struct jsonElement *cartJson = newJsonObject(hashNew(0)); jsonObjectAdd(cartJson, "db", newJsonString(database)); jsonObjectAdd(cartJson, "genomes", getGenomes()); struct dyString *cartJsonDy = dyStringNew(0); jsonDyStringPrint(cartJsonDy, cartJson, "cartJson", -1); jsInlineF("%s;\n", dyStringCannibalize(&cartJsonDy)); // Call our init function to fill out the page jsInline("hgSearch.init();\n"); webEndGb(); } void doSearchOnly() /* Send back search results along with whatever we need to make the UI */ { cartJsonPushErrHandlers(); @@ -603,30 +633,31 @@ puts("</HEAD>\n</HTML>"); } else { dyStringPrintf(cj->jw->dy, ", \"db\": '%s'", db); dyStringPrintf(cj->jw->dy, ", \"categs\": "); jsonDyStringPrint(cj->jw->dy, categsJsonElement, NULL,-1); dyStringPrintf(cj->jw->dy, ", \"trackGroups\": "); jsonDyStringPrint(cj->jw->dy, makeTrackGroupsJson(db), NULL, -1); dyStringPrintf(cj->jw->dy, ", \"genomes\": "); jsonDyStringPrint(cj->jw->dy, getGenomes(), NULL, -1); // Now we need to actually spit out the page + json webStartGbNoBanner(cart, db, "Search Disambiguation"); printMainPageIncludes(); + printPopularDataJson(); cartJsonPrintWarnings(cj->jw); jsInlineF("var hgsid='%s';\n", cartSessionId(cart)); jsInline("var cartJson = {"); jsInline(cj->jw->dy->string); jsInline("};\n"); jsInline("hgSearch.init();\n"); webEndGb(); } cartJsonPopErrHandlers(); } /* End do commands */ void doMiddle(struct cart *theCart) /* Set up globals and make web page */ {