651f959d7553ee0256b1e0b37ffa83d64709511d
lrnassar
  Mon Mar 16 17:57:16 2026 -0700
Adding accessible labels to form controls across main CGI pages. Extends cheapcgi and hui libraries with aria-label support for track visibility dropdowns, and adds <label> elements to hgBlat, hgTables, hgPcr, and hgGateway form controls. Also adds Form Control Labels section to accessibility page. refs #37253

diff --git src/hg/hgBlat/hgBlat.c src/hg/hgBlat/hgBlat.c
index 33a09ad0845..45d9fbddcbc 100644
--- src/hg/hgBlat/hgBlat.c
+++ src/hg/hgBlat/hgBlat.c
@@ -2064,98 +2064,89 @@
 {
 /* ignore struct serverTable* return, but can error out if not found */
 findServer(db, FALSE);
 
 char *userSeq = NULL;
 char *type = NULL;
 
 printf( 
 "<FORM ACTION=\"../cgi-bin/hgBlat\" METHOD=\"POST\" ENCTYPE=\"multipart/form-data\" NAME=\"mainForm\">\n"
 "<H2>BLAT Search Genome</H2>\n");
 cartSaveSession(cart);
 puts("\n");
 puts("<INPUT TYPE=HIDDEN NAME=changeInfo VALUE=\"\">\n");
 puts("<TABLE class='hgBlatTable' BORDER=0 WIDTH=80>\n");
 printf("<TR>\n");
-printf("<TD ALIGN=CENTER style='overflow:hidden;white-space:nowrap;'>Genome:");
+printf("<TD ALIGN=CENTER style='overflow:hidden;white-space:nowrap;'><label for='genomeSearch'>Genome:</label>");
 printf(" <INPUT TYPE=CHECKBOX id=allGenomes NAME=allGenomes VALUE=\"\">");
-printf(" <span id=searchAllText> Search all genomes</span>");
+printf(" <label for='allGenomes'> Search all genomes</label>");
 printf("</TD>");
-// clicking on the Search ALL text clicks the checkbox.
-jsOnEventById("click", "searchAllText", 
-    "document.mainForm.allGenomes.click();"
-    "return false;"   // cancel the default
-    );
 
 printf("<TD ALIGN=CENTER>Assembly:</TD>");
-printf("<TD ALIGN=CENTER>Query type:</TD>");
-printf("<TD ALIGN=CENTER>Sort output:</TD>");
-printf("<TD ALIGN=CENTER>Output type:</TD>");
+printf("<TD ALIGN=CENTER><label for='type'>Query type:</label></TD>");
+printf("<TD ALIGN=CENTER><label for='sort'>Sort output:</label></TD>");
+printf("<TD ALIGN=CENTER><label for='output'>Output type:</label></TD>");
 printf("<TD ALIGN=CENTER>&nbsp;</TD>");
 printf("</TR>\n");
 
 printf("<TR>\n");
 printf("<TD class='searchCell' ALIGN=CENTER>\n");
 // hgBlat requires this <input> be created to go along with form submission, we
 // will change it when a genome is selected in the search bar
 printf("<input name='db' value='%s' type='hidden'></input>\n", db);
 jsIncludeAutoCompleteLibs();
 char *searchBarId = "genomeSearch";
 printGenomeSearchBar(searchBarId, "Search any species, genome or assembly name", NULL, TRUE, NULL, NULL);
 jsInlineF(
     "setupGenomeSearchBar({\n"
     "    inputId: '%s',\n"
     "    onSelect: function(item) {\n"
     "        let db = dbFromRecentItem(item);\n"
     "        document.mainForm.db.value = db;\n"
     "        document.mainForm.submit();\n"
     "    }\n"
     "});\n"
     , searchBarId
 );
 printf("</TD>\n");
 printf("<TD id='genomeLabel' class='searchCell' ALIGN=CENTER>\n");
 char *dbLabel = getCurrentGenomeLabel(db);
 printf("%s\n", dbLabel);
 printf("</TD>\n");
 printf("<TD ALIGN=CENTER>\n");
 if (orgChange)
     type = cartOptionalString(cart, "type");
-cgiMakeDropList("type", typeList, ArraySize(typeList), type);
+cgiMakeDropListClassWithIdStyleAndJavascript("type", "type", typeList, ArraySize(typeList), type, "normalText", NULL, NULL);
 printf("</TD>\n");
 printf("<TD ALIGN=CENTER>\n");
-cgiMakeDropList("sort", pslSortList, ArraySize(pslSortList), cartOptionalString(cart, "sort"));
+cgiMakeDropListClassWithIdStyleAndJavascript("sort", "sort", pslSortList, ArraySize(pslSortList), cartOptionalString(cart, "sort"), "normalText", NULL, NULL);
 printf("</TD>\n");
 printf("<TD ALIGN=CENTER>\n");
-cgiMakeDropList("output", outputList, ArraySize(outputList), cartOptionalString(cart, "output"));
+cgiMakeDropListClassWithIdStyleAndJavascript("output", "output", outputList, ArraySize(outputList), cartOptionalString(cart, "output"), "normalText", NULL, NULL);
 printf("</TD>\n");
 printf("</TR>\n<TR>\n");
 userSeq = cartUsualString(cart, "userSeq", "");
 printf("<TD COLSPAN=5 ALIGN=CENTER>\n");
-htmlPrintf("<TEXTAREA NAME=userSeq ROWS=14 COLS=140>%s</TEXTAREA>\n", userSeq);
+printf("<label for='userSeq' style='display:block; margin-bottom:2px;'>Paste in a query sequence or upload a FASTA file:</label>");
+htmlPrintf("<TEXTAREA NAME=userSeq id=userSeq ROWS=14 COLS=140>%s</TEXTAREA>\n", userSeq);
 printf("</TD>\n");
 printf("</TR>\n");
 
 printf("<TR>\n");
 printf("<TD COLSPAN=1 ALIGN=CENTER style='overflow:hidden;white-space:nowrap;font-size:0.9em'>\n");
 cgiMakeCheckBoxWithId("allResults", allResults, "allResults");
-printf("<span id=allResultsText>All Results (no minimum matches)</span>");
-// clicking on the All Results text clicks the checkbox.
-jsOnEventById("click", "allResultsText", 
-    "document.mainForm.allResults.click();"
-    "return false;"   // cancel the default
-    );
+printf("<label for='allResults'>All Results (no minimum matches)</label>");
 printf("</TD>\n");
 
 printf("<TD COLSPAN=1 ALIGN=CENTER style='overflow:hidden;white-space:nowrap;font-size:0.9em'>\n");
 printf("<label for='autoRearr'>");
 cgiMakeCheckBoxWithId("autoRearr", autoRearr, "autoRearr");
 printf("<span> Optimize Display for Rearrangements </span>");
 printf("</label>");
 printInfoIcon("<b>Rearrangement display</b> (aka 'snakes' tracks) can show "
 "duplications of the query sequence using multiple lines, "
 "with connecting lines between fragments. It can also "
 "better display inversions. See the "
 "<a href='/goldenPath/help/chain.html#rearrangement'>"
 "snakes documentation"
 "</a> for more "
 "details. You can switch this on or off from the BLAT track configuration "
@@ -2170,31 +2161,31 @@
 printf("</TR>\n");
 
 printf("<TR>\n"); 
 puts("<TD COLSPAN=5 WIDTH=\"100%\">\n" 
     "Paste in a query sequence to find its location in the\n"
     "genome. Multiple sequences may be searched \n"
     "if separated by lines starting with '>' followed by the sequence name.\n"
     "</TD>\n"
     "</TR>\n"
 );
 
 puts("<TR><TD COLSPAN=5 WIDTH=\"100%\">\n"); 
 puts("<BR><B>File Upload:</B> ");
 puts("Rather than pasting a sequence, you can choose to upload a text file containing "
 	 "the sequence.<BR>");
-puts("Upload sequence: <INPUT TYPE=FILE NAME=\"seqFile\">");
+puts("<label>Upload sequence: <INPUT TYPE=FILE NAME=\"seqFile\"></label>");
 puts(" <INPUT TYPE=SUBMIT Name=Submit VALUE=\"Submit file\"><P>\n");
 printf("%s", 
 "<P>Only DNA sequences of 25,000 or fewer bases and protein or translated \n"
 "sequence of 10,000 or fewer letters will be processed.  Up to 25 sequences\n"
 "can be submitted at the same time. The total limit for multiple sequence\n"
 "submissions is 50,000 bases or 25,000 letters.<br> A valid example "
 "is <tt>GTCCTCGGAACCAGGACCTCGGCGTGGCCTAGCG</tt> (human SOD1).\n</P>\n");
 
 printf("%s", 
 "<P>The <b>Search all</b> checkbox allows you to search all genomes at the same time. "
 "Search all is only available for default assemblies and attached hubs with dedicated BLAT servers. "
 "The new dynamic BLAT servers are not supported, and they are noted as skipped in the output. "
 "<b>See our <a href='/FAQ/FAQblat.html#blat9'>BLAT All FAQ</a> for more information.</b>\n"
 );