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/hgCustom/hgCustom.c src/hg/hgCustom/hgCustom.c index 5a3b9e78654..6503c2fc046 100644 --- src/hg/hgCustom/hgCustom.c +++ src/hg/hgCustom/hgCustom.c @@ -149,98 +149,89 @@ " If you do not have web-accessible data storage available, please see the\n" " Hosting section of the Track Hub Help documentation.\n

" " \n" " Please note a much more efficient way to load data is to use\n" " Track Hubs, which are loaded\n" " from the Track Hubs Portal found in the menu under My Data.\n" ); } void addCustomForm(struct customTrack *ct, char *err, boolean warnOnly) /* display UI for adding custom tracks by URL or pasting data */ { char *dataUrl = NULL; char buf[1024]; -boolean gotClade = FALSE; boolean isUpdateForm = FALSE; if (ct) { isUpdateForm = TRUE; dataUrl = ctDataUrl(ct); } -else - /* add form needs clade for assembly menu */ - gotClade = hGotClade(); jsIncludeFile("jquery.js", NULL); jsIncludeFile("hgCustom.js", NULL); jsIncludeFile("utils.js", NULL); jsIncludeFile("ajax.js", NULL); if (cfgOptionBooleanDefault("showTutorial", TRUE)) { jsIncludeFile("shepherd.min.js", NULL); webIncludeResourceFile("shepherd.css"); jsIncludeFile("jquery-ui.js", NULL); webIncludeResourceFile("jquery-ui.css"); jsIncludeFile("tutorialPopup.js", NULL); jsIncludeFile("customTrackTutorial.js", NULL); if (sameOk(cgiOptionalString("startCustomTutorial"), "true")) { jsInline("var startCustomTutorialOnLoad = true;"); } } /* main form */ printf("
\n", hgCustomName(), cartUsualString(cart, "formMethod", "POST")); jsOnEventById("submit", "mainForm", "$('input[name=Submit]').attr('disabled', 'disabled');"); cartSaveSession(cart); if (!isUpdateForm) { - /* Print clade, genome and assembly */ - /* NOTE: this uses an additional, hidden form (orgForm), below */ - char *onChangeDb = "document.orgForm.db.value = document.mainForm.db.options[document.mainForm.db.selectedIndex].value; document.orgForm.submit();"; - char *onChangeOrg = "document.orgForm.org.value = document.mainForm.org.options[document.mainForm.org.selectedIndex].value; document.orgForm.db.value = 0; document.orgForm.submit();"; - char *onChangeClade = "document.orgForm.clade.value = document.mainForm.clade.options[document.mainForm.clade.selectedIndex].value; document.orgForm.org.value = 0; document.orgForm.db.value = 0; document.orgForm.submit();"; - + /* Print genome search bar and selected genome label */ puts("\n"); - if (gotClade) - { - puts("
Clade\n"); - printCladeListHtml(hOrganism(database), "change", onChangeClade); - puts("   "); - puts("Genome\n"); - printGenomeListForCladeHtml(database, "change", onChangeOrg); - } - else - { - puts("
genome\n"); - printGenomeListHtml(database, "change", onChangeOrg); - } - puts("   "); - puts("Assembly\n"); - printAssemblyListHtml(database, "change", onChangeDb); - char *description = hFreezeFromDb(database); - if ((description != NULL) && ! stringIn(database, description)) - { - puts("   "); - printf("[%s]", trackHubSkipHubName(database)); - } - puts("
\n"); + printf("\n"); + printf("\n"); + // hgCustom requires this be created to go along with form submission, we + // will change it when a genome is selected in the search bar + printf("\n", database); + jsIncludeAutoCompleteLibs(); + char *searchBarId = "genomeSearch"; + printGenomeSearchBar(searchBarId, "Search any species, genome or assembly name", NULL, TRUE, "Change selected genome:", NULL); + jsInlineF( + "setupGenomeSearchBar({\n" + " inputId: '%s',\n" + " onSelect: function(item) {\n" + " document.mainForm.db.value = item.genome;\n" + " }\n" + "});\n" + , searchBarId + ); + printf("\n"); + printf("\n"); + char *dbLabel = getCurrentGenomeLabel(database); + printf("Current Genome: %s\n", dbLabel); + printf("\n"); + puts("\n"); } /* intro text */ puts("

"); if (isUpdateForm) puts("Update your custom track configuration, data, and/or documentation."); else puts("Display your own data as custom annotation tracks in the browser."); addIntro(); puts("

"); /* row for error message */ if (isNotEmpty(err)) { printf("

    " @@ -467,43 +458,30 @@ if (isUpdateForm) { /* hidden variables to identify track */ cgiMakeHiddenVar(hgCtUpdatedTable, ct->tdb->track); char buf[512]; char *shortLabel = htmlEncode(ct->tdb->shortLabel); char *longLabel = htmlEncode(ct->tdb->longLabel); safef(buf, sizeof buf, "track name='%s' description='%s'", shortLabel, longLabel); char *trackLine = htmlEncode(ctOrigTrackLine(ct)); cgiMakeHiddenVar(hgCtUpdatedTrack, trackLine ? trackLine : buf); freeMem(trackLine); freeMem(shortLabel); freeMem(longLabel); } -else - { - /* hidden form to handle clade/genome/assembly dropdown. - * This is at end of page for layout reasons (preserve vertical space) */ - puts(""); - printf("

", hgCustomName()); - cartSaveSession(cart); - if (gotClade) - printf("\n"); - printf("\n", organism); - printf("\n", database); - printf("\n"); - } puts(""); cgiDown(0.9); } void tableHeaderFieldStart(int columns) { /* print table column header with white text on black background */ printf("", columns); } void tableHeaderField(char *label, char *description) { /* print table column header with white text on black background */ puts("