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/hgPcr/hgPcr.c src/hg/hgPcr/hgPcr.c
index 12eb1e89755..adb9fc94804 100644
--- src/hg/hgPcr/hgPcr.c
+++ src/hg/hgPcr/hgPcr.c
@@ -21,30 +21,31 @@
 #include "hdb.h"
 #include "hui.h"
 #include "cart.h"
 #include "dbDb.h"
 #include "blatServers.h"
 #include "targetDb.h"
 #include "pcrResult.h"
 #include "trashDir.h"
 #include "web.h"
 #include "botDelay.h"
 #include "oligoTm.h"
 #include "trackHub.h"
 #include "hubConnect.h"
 #include "obscure.h"
 #include "chromAlias.h"
+#include "jsHelper.h"
 
 
 struct cart *cart;	/* The user's ui state. */
 struct hash *oldVars = NULL;
 
 /* for earlyBotCheck() function at the beginning of main() */
 #define delayFraction   1.0     /* standard penalty for most CGIs */
 static boolean issueBotWarning = FALSE;
 
 void usage()
 /* Explain usage and exit. */
 {
 errAbort(
   "hgPcr - In-silico PCR CGI for UCSC\n"
   "usage:\n"
@@ -395,46 +396,57 @@
 	       "defaulting to %s %s</EM></P><HR>\n",
 	       hGenome(db), hFreezeDate(db), organism, hFreezeDate(orgServer->db));
     *pDb = db = orgServer->db;
     }
 }
 
 void doGetPrimers(char *db, char *organism, struct pcrServer *serverList,
 	char *fPrimer, char *rPrimer, int maxSize, int minPerfect, int minGood,
 	boolean flipReverse, boolean appendToResults)
 /* Put up form to get primers. */
 {
 redoDbAndOrgIfNoServer(serverList, &db, &organism);
 struct sqlConnection *conn = hConnectCentral();
 boolean gotTargetDb = sqlTableExists(conn, "targetDb");
 hDisconnectCentral(&conn);
-
+jsIncludeAutoCompleteLibs();
 
 printf("<FORM ACTION=\"../cgi-bin/hgPcr\" METHOD=\"GET\" NAME=\"mainForm\">\n");
 cartSaveSession(cart);
 
 printf("<TABLE BORDER=0 WIDTH=\"96%%\" COLS=7><TR>\n");
 
-printf("%s", "<TD><CENTER>\n");
-printf("Genome:<BR>");
-showGenomes(organism, serverList);
-printf("%s", "</CENTER></TD>\n");
+printf("<TD class='searchCell'><center>\n");
+char *searchBarId = "genomeSearch";
+printGenomeSearchBar(searchBarId, "Search any species, genome or assembly name", NULL, TRUE, "Genome:", NULL);
+jsInlineF(
+    "setupGenomeSearchBar({\n"
+    "    inputId: '%s',\n"
+    "    onSelect: function(item) {\n"
+    "        " ORGFORM_KEEP_PARAMS "\n"
+    "        document.orgForm.org.value = '0';\n"
+    "        document.orgForm.db.value = item.genome;\n"
+    "        " ORGFORM_RESET_TARGET "\n"
+    "        " ORGFORM_SUBMIT "\n"
+    "    }\n"
+    "});\n"
+    , searchBarId
+);
 
-printf("%s", "<TD><CENTER>\n");
-printf("Assembly:<BR>");
-showAssemblies(organism, db, serverList, gotTargetDb);
-printf("%s", "</CENTER></TD>\n");
+printf("</center></td><TD><CENTER>\n");
+printf("Assembly:<BR><span id='genomeLabel'>%s</span>", getCurrentGenomeLabel(db));
+printf("</CENTER></TD>\n");
 
 if (gotTargetDb)
     {
     struct targetPcrServer *targetServerList = getTargetServerList(db, NULL);
     if (targetServerList != NULL)
 	{
 	char *target = cartUsualString(cart, "wp_target", "genome");
 	printf("%s", "<TD><CENTER>\n");
 	printf("Target:<BR>");
 	showTargets(target, targetServerList);
 	printf("%s", "</CENTER></TD>\n");
 	}
     else
 	cgiMakeHiddenVar("wp_target", "genome");
     }