47ea57080b515e5dad5f658c58feb8944a7e7d61 chmalee Thu Jan 29 15:30:26 2026 -0800 Replace clade/assembly dropdowns with a search bar on most CGIs. Add a recents list to hgGateway and to the species bar and to the 'Genomes' dropdown menu. Track recently selected species in localStorage. Add toGenome and fromGenome arguemnts to hubApi/liftOver in order to find appropriate liftover assemblies, refs #36232 diff --git src/hg/lib/web.c src/hg/lib/web.c index 0a9b9bc4562..969cd5b5c5a 100644 --- src/hg/lib/web.c +++ src/hg/lib/web.c @@ -904,30 +904,74 @@ } void printBlatAssemblyListHtml(char *db) { /* Find all the assemblies that pertain to the selected genome Prints to stdout the HTML to render a dropdown list containing a list of the possible assemblies to choose from. param curDb - The assembly (the database name) to choose as selected. If NULL, no default selection. */ struct dbDb *dbList = hGetBlatIndexedDatabases(); printSomeAssemblyListHtml(db, dbList, NULL, NULL); } +char *getCurrentGenomeLabel(char *db) +/* Construct a label from dbDb (or dbDb related for an assembly hub) for the currently + * selected genome */ +{ +// TODO: what if 'db' is a reference to an assembly hub or genark? +struct dbDb *info = hDbDb(db); +if (info) + return cloneString(info->description); +else + return cloneString(db); +} + +void printGenomeSearchBar(char *id, char *placeholder, char *classStr, boolean withSearchButton, char *labelText, char *labelClassStr) +/* Prints an input text box that can be used to search for any genome. + * param withSearchButton - controls if there is a button next to the bar + * to manually fire the search + * param classStr - if desired, a custom class name or string can be used + * otherwise the default styling of 'genomeSearchBarDefault' is applied via HGStyle.css + * param labelText - If not empty, put up a <label> for the search bar, use labelClassStr to + * style it + * param labelClassStr - if not empty and labelText not empty, apply this class to the label + * + * There is a default class in HGStyle.css that is used + * + * 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"); +if (withSearchButton) + printf("<input id='%sButton' value='search' type='button'></input>", id); +printf("</div>\n"); // the search button is grouped with the input +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 */ { char *retDb = cartUsualString(cart, dbCgiName, NULL); @@ -1696,30 +1740,33 @@ safef(buf, sizeof(buf), "<li><a id='%s' href='%s'>%s</a></li>", contextSpecificHelpId, contextSpecificHelpLink, contextSpecificHelpLabel); menuStr = replaceChars(menuStr, "<!-- CONTEXT_SPECIFIC_HELP -->", buf); } // links to hgTracks need to use the web browser width and set the hgTracks image // size in pixels correctly to match the hgGateway "GO" button jsInline("$(\"#tools1 ul li a\").each( function (a) {\n" " if (this.href && this.href.indexOf(\"hgTracks\") !== -1) {\n" " var obj = this;\n" " obj.onclick = function(e) {\n" " var pix = calculateHgTracksWidth();\n" " e.currentTarget.href += \"&pix=\" + pix;\n" " }\n" " }\n" "});\n"); +// if the user has previously searched for assemblies, add them to the "Genomes" menu heading, +// above the "other" assemblies link +jsInline("addRecentGenomesToMenuBar();\n"); return menuStr; } void checkForGeoMirrorRedirect(struct cart *cart) // Implement Geo/IP based redirection. { char *thisNodeStr = geoMirrorNode(); if (thisNodeStr) // if geo-mirroring is enabled { char *redirectCookie = findCookieData("redirect"); char *redirect = cgiOptionalString("redirect"); // if we're not already redirected if (redirect == NULL && redirectCookie == NULL) {