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/hgLiftOver/hgLiftOver.c src/hg/hgLiftOver/hgLiftOver.c index 4cf26e6d4d4..9d909e4bfc1 100644 --- src/hg/hgLiftOver/hgLiftOver.c +++ src/hg/hgLiftOver/hgLiftOver.c @@ -9,30 +9,31 @@ #include "portable.h" #include "linefile.h" #include "dnautil.h" #include "fa.h" #include "cheapcgi.h" #include "htmshell.h" #include "hdb.h" #include "hui.h" #include "cart.h" #include "web.h" #include "hash.h" #include "liftOver.h" #include "liftOverChain.h" #include "errCatch.h" #include "hgConfig.h" +#include "jsHelper.h" /* CGI Variables */ #define HGLFT_USERDATA_VAR "hglft_userData" /* typed/pasted in data */ #define HGLFT_DATAFILE_VAR "hglft_dataFile" /* file of data to convert */ #define HGLFT_FROMORG_VAR "hglft_fromOrg" /* FROM organism */ #define HGLFT_FROMDB_VAR "hglft_fromDb" /* FROM assembly */ #define HGLFT_TOORG_VAR "hglft_toOrg" /* TO organism */ #define HGLFT_TODB_VAR "hglft_toDb" /* TO assembly */ #define HGLFT_ERRORHELP_VAR "hglft_errorHelp" /* Print explanatory text */ #define HGLFT_REFRESHONLY_VAR "hglft_doRefreshOnly" /* Just refresh drop-down lists */ #define HGLFT_LAST_CHAIN "hglft_lastChain" #define HGLFT_EXTRA_NAME_INFO "hglft_extranameinfo" /* Include input position in output item names */ /* liftOver options: */ @@ -59,90 +60,93 @@ ".value = 1;" "document.mainForm.submit();"; char *chainStringVal(struct liftOverChain *chain) /* keep the last chain in memory in this format */ { char chainS[64]; safef(chainS, sizeof(chainS), "%s.%s", chain->fromDb, chain->toDb); return cloneString(chainS); } void webMain(struct liftOverChain *chain, boolean multiple, boolean keepSettings, int minSizeQ, int minChainT, float minBlocks, float minMatch, boolean fudgeThick, boolean extraNameInfo) /* set up page for entering data */ { -struct dbDb *dbList; char *fromOrg = hOrganism(chain->fromDb), *toOrg = hOrganism(chain->toDb); char *chainString = chainStringVal(chain); cgiParagraph( "This tool converts genome coordinates and annotation files " "from the original to the new assembly using an alignment.  " "The input regions can be entered into the text box or uploaded as a file.  " "For files over 500Mb, use the command-line tool described in our " "LiftOver documentation." "  If a pair of assemblies cannot be selected from the pull-down menus," " a sequential lift may still be possible (e.g., mm9 to mm10 to mm39).  " "If your desired conversion is still not available, please " "contact us." ""); /* create HMTL form */ puts("
\n"); cartSaveSession(cart); /* create HTML table for layout purposes */ puts("\n\n"); - -/* top two rows -- genome and assembly menus */ -cgiSimpleTableRowStart(); -cgiTableField("Original genome: "); -cgiTableField("Original assembly: "); -cgiTableField("New genome: "); -cgiTableField("New assembly: "); -cgiTableRowEnd(); - -cgiSimpleTableRowStart(); - -/* genome */ -cgiSimpleTableFieldStart(); -dbList = hGetLiftOverFromDatabases(); -printSomeGenomeListHtmlNamed(HGLFT_FROMORG_VAR, chain->fromDb, dbList, "change", onChange); -cgiTableFieldEnd(); - -/* from assembly */ -cgiSimpleTableFieldStart(); -printAllAssemblyListHtmlParm(chain->fromDb, dbList, HGLFT_FROMDB_VAR, - TRUE, "change", onChange); -cgiTableFieldEnd(); - -/* to assembly */ - -cgiSimpleTableFieldStart(); -// Genark is generating some less than fully populated dbDb structures -// so we don't expect them to free without causing problems. -//dbDbFreeList(&dbList); -dbList = hGetLiftOverToDatabases(chain->fromDb); +printf("\n"); +jsIncludeAutoCompleteLibs(); +char *searchBarId = "fromGenomeSearch"; +printf("\n", HGLFT_FROMDB_VAR, chain->fromDb); +printf("\n", HGLFT_FROMORG_VAR, fromOrg); +printf("\n"); +printf("\n"); +printf("\n"); + +// print select/options for toDb, it is more intuitive than a search bar +struct dbDb *dbList = hGetLiftOverToDatabases(chain->fromDb); +printf("\n"); +printf("\n"); -cgiTableRowEnd(); cgiTableEnd(); printf("
"); cgiSimpleTableStart(); cgiSimpleTableRowStart(); cgiTableField("Minimum ratio of bases that must remap:"); cgiSimpleTableFieldStart(); cgiMakeDoubleVar(HGLFT_MINMATCH, (keepSettings) ? minMatch : chain->minMatch,6); puts(" "); printInfoIcon("The minimum ratio of basepairs of the input region covered by an alignment. Regions scoring lower than this will not be lifted at all."); cgiTableFieldEnd(); cgiTableRowEnd(); cgiSimpleTableRowStart(); @@ -426,31 +430,31 @@ fromDb = cartCgiUsualString(cart, HGLFT_FROMDB_VAR, "0"); toOrg = cartCgiUsualString(cart, HGLFT_TOORG_VAR, "0"); toDb = cartCgiUsualString(cart, HGLFT_TODB_VAR, "0"); cartOrg = hOrganism(cartDb); if (sameWord(fromOrg,"0")) fromOrg = NULL; if (sameWord(fromDb,"0")) fromDb = NULL; if (sameWord(toOrg,"0")) toOrg = NULL; if (sameWord(toDb,"0")) toDb = NULL; if (sameWord(cartDb,"0")) cartDb = NULL; -if ((fromDb != NULL) && !sameOk(fromOrg, hOrganism(fromDb))) +if ((fromDb != NULL) && !sameOk(strLower(fromOrg), strLower(hOrganism(fromDb)))) fromDb = NULL; if ((toDb != NULL) && !sameOk(toOrg, hOrganism(toDb))) toDb = NULL; for (this = chainList; this != NULL; this = this->next) { if (sameOk(this->fromDb ,fromDb) && sameOk(this->toDb, toDb)) { choice = this; break; } double score = scoreLiftOverChain(this, fromOrg, fromDb, toOrg, toDb, cartOrg, cartDb, dbRank, dbDbHash); if (score > bestScore) { choice = this;
\n"); +printGenomeSearchBar(searchBarId, "Search any species, genome or assembly name", NULL, TRUE, "Change original genome:", NULL); +jsInlineF( + "setupGenomeSearchBar({\n" + " inputId: '%s',\n" + " labelElementId: 'fromGenomeLabel',\n" + " apiUrl: 'hubApi/findGenome?browser=mustExist&liftable=true&q=',\n" + " onSelect: function(item) {\n" + " document.mainForm."HGLFT_REFRESHONLY_VAR".value=1;\n" + " document.mainForm."HGLFT_FROMDB_VAR".value=item.genome;\n" + " document.mainForm."HGLFT_FROMORG_VAR".value=item.commonName.split('(')[0].trim();\n" + " document.mainForm.submit();\n" + " }\n" + "});\n" + , searchBarId +); +printf("\n"); +printf("
\n"); +printf("Currently selected genome:\n"); +printf("%s (%s)\n", fromOrg, chain->fromDb); +printf("
\n"); +printf("\n"); +printf("
\n"); printLiftOverGenomeList(HGLFT_TOORG_VAR, chain->toDb, dbList, "change", onChange); -cgiTableFieldEnd(); - -cgiSimpleTableFieldStart(); +printf("
\n"); +printf("
\n"); +printf("\n"); printAllAssemblyListHtmlParm(chain->toDb, dbList, HGLFT_TODB_VAR, TRUE, NULL, NULL); -cgiTableFieldEnd(); +printf("