b818160961573cd7b8902303ca4dc532d1366513
max
  Mon Apr 29 11:14:47 2024 -0700
adding name filter and color track options to hgTrackUi, refs #20460

diff --git src/hg/lib/hui.c src/hg/lib/hui.c
index 4df1012..39ccf83 100644
--- src/hg/lib/hui.c
+++ src/hg/lib/hui.c
@@ -4313,52 +4313,61 @@
 if (!tdbIsBigBed(tdb))
     return FALSE;
 
 return  sameString(setting, FILTERBY_MULTIPLE_LIST_OR) || sameString(setting, FILTERBY_MULTIPLE_LIST_AND);
 }
 
 void filterBySetCfgUiGuts(struct cart *cart, struct trackDb *tdb,
 		      filterBy_t *filterBySet, boolean onOneLine,
 		      char *filterTypeTitle, char *selectIdPrefix, char *allLabel, char *prefix, boolean isHighlight)
 // Does the UI for a list of filterBy structure for either filterBy or highlightBy controls
 // isHighlight controls the variable name for the cart
 {
 if (filterBySet == NULL)
     return;
 
-#define FILTERBY_HELP_LINK "<A HREF=\"../goldenPath/help/multiView.html\" TARGET=ucscHelp>help</A>"
+#define FILTERBY_HELP_LINK "<A HREF=\"../goldenPath/help/multiView.html\" TARGET=ucscHelp>Help</A>"
 int count = slCount(filterBySet);
 if (count == 1)
     puts("<TABLE class='trackUiFilterTable'><TR valign='top'>");
 else
-    printf("<B>%s items by:</B> (select multiple categories and items - %s)"
+    printf("<B>%s items by:</B> (select multiple categories and items - %s)&nbsp;&nbsp;<button id='filterResetButton'>Reset filters</button>"
 	   "<TABLE class='trackUiFilterTable'><TR valign='bottom'>\n",filterTypeTitle,FILTERBY_HELP_LINK);
 
+jsInlineF("$(function () { "
+    "$('#filterResetButton').click( "
+       "     function(ev) { ev.preventDefault(); "
+       "     $('.filterBy option[value=\"All\"]').removeAttr(\"selected\");"
+       "     $('.filterBy option[Value=\"All\"]').attr('selected', 'selected');"
+       "     $('.filterBy').dropdownchecklist('refresh'); "
+       " }); "
+"});");
+
 #ifdef ADVANCED_BUTTON
 if (tdbIsBigBed(tdb))
     {
     char varName[1024];
     safef(varName, sizeof(varName), "%s.doAdvanced", tdb->track);
     puts("&nbsp;&nbsp;&nbsp;");
     printf("<a id='%s' style='text-decoration: underline; color: #121E9A' title='Show advanced options..'>%s<img src='../images/downBlue.png'/></a>" ,varName,"Advanced ");
     printf("<BR>");
     jsInlineF("$(function () { advancedSearchOnChange('%s'); });\n", varName);
     }
 #endif // ADVANCED_BUTTON
 
-
 filterBy_t *filterBy = NULL;
+
 if (cartOptionalString(cart, "ajax") == NULL)
     {
     webIncludeResourceFile("ui.dropdownchecklist.css");
     jsIncludeFile("ui.dropdownchecklist.js",NULL);
     jsIncludeFile("ddcl.js",NULL);
     }
 
 // TODO: columnCount (Number of filterBoxes per row) should be configurable through tdb setting
 
 for (filterBy = filterBySet;  filterBy != NULL;  filterBy = filterBy->next)
     {
     puts("<TD>");
     char selectStatement[4096];
     char *setting =  getFilterType(cart, tdb, filterBy->column, FILTERBY_DEFAULT);
     if (filterByColumnIsMultiple(cart, tdb, setting))
@@ -5978,30 +5987,66 @@
 
 // we need to fool the wiggle dialog into defaulting to autoscale and maximum
 char *origType = tdb->type;
 tdb->type = "bedGraph";
 if (hashFindVal(tdb->settingsHash, AUTOSCALE) == NULL)
     hashAdd(tdb->settingsHash, AUTOSCALE, "on");
 if (hashFindVal(tdb->settingsHash, WINDOWINGFUNCTION) == NULL)
     hashAdd(tdb->settingsHash, WINDOWINGFUNCTION, wiggleWindowingEnumToString( wiggleWindowingMean));
 wigCfgUi(cart,tdb,name,title,TRUE);
 tdb->type = origType;
 printf("</DIV>\n\n");
 jsInlineF("$(\"input[name='%s']\").click( function() { $('#densGraphOptions').toggle();} );\n"
     , varName); // XSS FILTER?
 }
 
+void filterNameOption(struct cart *cart, char *name, struct trackDb *tdb)
+/* filter by feature names text input box */
+{
+printf("<DIV><B>Show only transcripts with these accessions:</B> ");
+char varName[1024];
+safef(varName, sizeof(varName), "%s.nameFilter", name);
+
+char *onlyTransStr = cartUsualString(cart, varName, "");
+
+cgiMakeTextVar(varName, onlyTransStr, 60);
+printf("&nbsp;<small>Separate multiple accessions with commas</small>");
+puts("</DIV>\n\n");
+}
+
+void colorTrackOption(struct cart *cart, char *name, struct trackDb *tdb)
+/* color picker for overriding track color */
+{
+printf("<DIV><B>Color for all features:</B> ");
+char varName[1024];
+safef(varName, sizeof(varName), "%s.colorOverride", name);
+
+char *colorValue = cartUsualString(cart, varName, "");
+
+cgiMakeTextVar(varName, colorValue, 10);
+puts("&nbsp;<input id='colorPicker'>");
+puts("&nbsp;&nbsp;<span class='link' id='colorReset'>Reset</span>");
+jsInlineF("activateColorPicker('[id=\"%s\"]', '#colorPicker');", varName); // id="xx" is necessary as id contains a dot
+jsInlineF("$('#colorPicker').spectrum('set', '#%s');", colorValue);
+jsInlineF("$('#colorReset').click(function() { "
+    "$('[id=\"%s\"]').val('');"
+    "$('#colorPicker').spectrum('set', '#000000');"
+    "});", varName);
+
+puts("</DIV>\n\n");
+}
+
 void wiggleScaleDropDownJavascript(char *name)
 /* print some js that deactivates the min/max range if autoscaling is activated */
 {
 struct dyString *dy = dyStringNew(1024);
 dyStringPrintf(dy, "  $(\"[name='%s.autoScale']\").change(function()\n", name);
 dyStringPrintf(dy, "  {\n");
 dyStringPrintf(dy, "  val= $(this).find(':selected').val(); \n");
 dyStringPrintf(dy, "  if (val!=\"use vertical viewing range setting\")\n");
 dyStringPrintf(dy, "     {\n");
 dyStringPrintf(dy, "     $(\"[name='%s.minY']\")[0].disabled=true;\n", name);
 dyStringPrintf(dy, "     $(\"[name='%s.maxY']\")[0].disabled=true;\n", name);
 dyStringPrintf(dy, "     $(\".%sAutoScaleDesc\").attr('style', 'color:grey;');\n", name);
 dyStringPrintf(dy, "     }\n");
 dyStringPrintf(dy, "     else\n");
 dyStringPrintf(dy, "     {\n");
@@ -6955,31 +7000,31 @@
             printHighlightColorPicker(cart, tdb);
         count++;
         printf("<P><B>%s items in '%s' field:</B> ", isHighlight ? "Highlight": "Filter", trackDbLabel);
 
         char cgiVar[128];
         safef(cgiVar,sizeof(cgiVar),"%s.%s",tdb->track,filter->name);
         cgiMakeTextVar(cgiVar, value, 45);
 
         char *setting = getFilterType(cart, tdb, filter->fieldName, FILTERTEXT_WILDCARD);
         safef(cgiVar,sizeof(cgiVar),"%s.%s.%s",tdb->track,FILTER_TYPE_NAME_LOW, filter->fieldName);
         printf(" using ");
         printf("<SELECT name='%s'> ", cgiVar);
         printf("<OPTION %s>%s</OPTION>", sameString(setting, FILTERTEXT_WILDCARD) ? "SELECTED" : "",  FILTERTEXT_WILDCARD );
         printf("<OPTION %s>%s</OPTION>", sameString(setting, FILTERTEXT_REGEXP) ? "SELECTED" : "",  FILTERTEXT_REGEXP );
         printf("</SELECT>");
-        printf("&nbsp;&nbsp;<button class='buttonClear-%s'>Clear</button>\n", tdb->track);
+        printf("&nbsp;&nbsp;<button class='buttonClear-%s'>Reset</button>\n", tdb->track);
         printf("</P>");
         }
         // using jquery id= syntax to make sure that selector works even if trackname has a dot in it
         jsInlineF("$('[class=\"buttonClear-%s\"]').click( function(ev) { \n"
                     "$(ev.target).prevAll('input').val('*').trigger('change');\n"
                     "$(ev.target).prevAll('select').val('%s');\n"
                     "ev.preventDefault();\n"
                   "});", tdb->track, FILTERTEXT_WILDCARD);
     }
 
 return count;
 }
 
 void scoreCfgUi(char *db, struct cart *cart, struct trackDb *tdb, char *name, char *title,
                 int maxScore, boolean boxed)
@@ -7794,30 +7839,32 @@
 if (filterBySet != NULL)
     {
     printf("<BR>");
     filterBySetCfgUi(cart,tdb,filterBySet,FALSE, name);
     filterBySetFree(&filterBySet);
     }
 filterBy_t *highlightBySet = highlightBySetGet(tdb,cart,name);
 if (highlightBySet != NULL)
     {
     printf("<BR>");
     highlightBySetCfgUi(cart,tdb,highlightBySet,FALSE, name, TRUE);
     filterBySetFree(&highlightBySet);
     }
 
 squishyPackOption(cart, name, title, tdb);
+filterNameOption(cart, name, tdb);
+colorTrackOption(cart, name, tdb);
 wigOption(cart, name, title, tdb);
 cfgEndBox(boxed);
 }
 
 static boolean isSpeciesOn(struct cart *cart, struct trackDb *tdb, char *species, char *option, int optionSize, boolean defaultState)
 /* check the cart to see if species is turned off or on (default is defaultState) */
 {
 boolean parentLevel = isNameAtParentLevel(tdb,option);
 if (*option == '\0')
     safef(option, optionSize, "%s.%s", tdb->track, species);
 else
     {
     char *suffix = option + strlen(option);
     int suffixSize = optionSize - strlen(option);
     safef(suffix,suffixSize,".%s",species);