0748529dccb23f98aa4efa81b110d1dbd9be9421
tdreszer
  Tue Dec 13 12:15:29 2011 -0800
Make [add][clear] buttons use the same javascript that matrix [+][-] buttons use.
diff --git src/hg/lib/hui.c src/hg/lib/hui.c
index 6edf7e4..14638ba 100644
--- src/hg/lib/hui.c
+++ src/hg/lib/hui.c
@@ -2672,30 +2672,51 @@
                 membersForAll->checkedTags[membersForAll->dimMax] = abcMembersChecked(parentTdb,cart,membersForAll->members[membersForAll->dimMax],letter);
             membersForAll->dimMax++;
             }
         else if(letter == 'X')
             {
             membersForAll->members[dimX]=subgroupMembersGet(parentTdb, membersForAll->dimensions->subgroups[ix]);
             membersForAll->letters[dimX]=letter;
             }
         else
             {
             membersForAll->members[dimY]=subgroupMembersGet(parentTdb, membersForAll->dimensions->subgroups[ix]);
             membersForAll->letters[dimY]=letter;
             }
         }
     }
+else // No 'dimensions" setting: treat any subGroups as abc dimensions
+    {
+    char letter = 'A';
+    // walk through numbered subgroups
+    for (ix=1;ix<SUBGROUP_MAX;ix++)  // how many to support?
+        {
+        char group[32];
+        safef(group, sizeof group,"subGroup%d",ix);
+        char *setting = subgroupSettingByTagOrName(parentTdb, group);
+        if (setting != NULL)
+            {
+            char *tag = cloneFirstWord(setting);
+            membersForAll->members[membersForAll->dimMax]=subgroupMembersGet(parentTdb, tag);
+            membersForAll->letters[membersForAll->dimMax]=letter;
+            if(cart != NULL)
+                membersForAll->checkedTags[membersForAll->dimMax] = abcMembersChecked(parentTdb,cart,membersForAll->members[membersForAll->dimMax],letter);
+            membersForAll->dimMax++;
+            letter++;
+            }
+        }
+    }
 membersForAll->abcCount = membersForAll->dimMax - dimA;
 
 membersForAll = membersForAllSubGroupsWeedOutEmpties(parentTdb, membersForAll, cart);
 
 // NOTE: Dimensions must be defined for filterComposite.  Filter dimensioms are all and only ABCs.  Use dimensionAchecked to define selected
 char *filtering = trackDbSettingOrDefault(parentTdb,"filterComposite",NULL);
 if(filtering && !sameWord(filtering,"off"))
     {
     if(membersForAll->dimensions == NULL)
         errAbort("If 'filterComposite' defined, must define 'dimensions' also.");
 
     membersForAll->filters = TRUE;
 #ifdef FILTER_COMPOSITE_ONLYONE
     // Default all to multi
     for(ix=dimA;ix<membersForAll->dimMax;ix++)
@@ -4084,37 +4105,48 @@
 
     // Start the TR which must have an id that is directly related to the checkBox id
     char *id = checkBoxIdMakeForTrack(subtrack,membersForAll->members,membersForAll->dimMax,membership); // view is known tag
 
     printf("<TR valign='top' class='%s%s'",colors[colorIx],(useDragAndDrop?" trDraggable":""));
     printf(" id=tr_%s%s>\n",id,(!visibleCB && !displayAll?" style='display:none'":""));
 
     // Now the TD that holds the checkbox
     printf("<TD%s%s>",
            (enabledCB?"":" title='view is hidden'"),
            (useDragAndDrop?" class='dragHandle' title='Drag to reorder'":""));
 
     // The checkbox has identifying classes including subCB and the tag for each dimension (e.g. class='subCB GM12878 CTCF Peak')
     dyStringClear(dyHtml);
     dyStringAppend(dyHtml, "subCB"); // always first
+    if (membersForAll->dimensions)
+        {
     for(di=dimX;di<membersForAll->dimMax;di++)
         {
         if (membersForAll->members[di] && -1 != (ix = stringArrayIx(membersForAll->members[di]->groupTag, membership->subgroups, membership->count)))
             dyStringPrintf(dyHtml," %s",membership->membership[ix]);
         }
     if (membersForAll->members[dimV] && -1 != (ix = stringArrayIx(membersForAll->members[dimV]->groupTag, membership->subgroups, membership->count)))
         dyStringPrintf(dyHtml, " %s",membership->membership[ix]);  // Saved view for last
+        }
+     else if (membersForAll->abcCount) // "dimensions" don't exist but there may be subgroups anyway
+        {
+        for(di=dimA;di<membersForAll->dimMax;di++)
+            {
+            if (membersForAll->members[di] && -1 != (ix = stringArrayIx(membersForAll->members[di]->groupTag, membership->subgroups, membership->count)))
+                dyStringPrintf(dyHtml," %s",membership->membership[ix]);
+            }
+        }
 
     // And finally the checkBox is made!
     safef(buffer, sizeof(buffer), "%s_sel", subtrack->track);
 #ifdef SUBTRACK_CFG
     if (!enabledCB)
         {
         dyStringAppend(dyHtml, " disabled");
         cgiMakeCheckBoxFourWay(buffer,checkedCB,enabledCB,id,dyStringContents(dyHtml),"onclick='matSubCbClick(this);' style='cursor:pointer' title='view is hidden'");
         }
     else
 #endif///def SUBTRACK_CFG
         cgiMakeCheckBoxFourWay(buffer,checkedCB,enabledCB,id,dyStringContents(dyHtml),"onclick='matSubCbClick(this);' style='cursor:pointer'");
     if (useDragAndDrop)
         printf("&nbsp;");
 
@@ -4323,42 +4355,62 @@
         {
         puts("<TR><TD>");
         cgiMakeCheckBox(htmlIdentifier, checkedCB && enabledCB);
         printf ("</TD><TD>%s</TD></TR>\n", subtrack->longLabel);
         }
     }
 puts("</TBODY><TFOOT></TFOOT>");
 puts("</TABLE>");
 if (slCount(subtrackRefList) > 5)
     puts("&nbsp;&nbsp;&nbsp;&nbsp;<span class='subCBcount'></span>");
 puts("<P>");
 if (!primarySubtrack)
     puts("<script type='text/javascript'>matInitializeMatrix();</script>");
 }
 
+#ifdef SUBTRACK_CFG
+static void makeAddClearButtonPair(char *class,char *seperator)
+// Print an [Add][Clear] button pair that uses javascript to check subtracks
+{
+char buf[256];
+if (class)
+    safef(buf, sizeof buf,"matSetMatrixCheckBoxes(true,'%s'); return false;", class);
+else
+    safef(buf, sizeof buf,"matSetMatrixCheckBoxes(true); return false;");
+cgiMakeOnClickButton(buf, ADD_BUTTON_LABEL);
+if (seperator)
+    printf("%s",seperator);
+if (class)
+    safef(buf, sizeof buf,"matSetMatrixCheckBoxes(false,'%s'); return false;", class);
+else
+    safef(buf, sizeof buf,"matSetMatrixCheckBoxes(false); return false;");
+cgiMakeOnClickButton(buf, CLEAR_BUTTON_LABEL);
+}
+#else///ifndef SUBTRACK_CFG
 static void makeAddClearSubmitTweak(char javascript[JBUFSIZE], char *formName,
 				    char *buttonVar, char *label)
 /* safef into javascript a sequence of commands that will force a refresh
  * of this same form, updating the values of whatever variables are necessary
  * to say what we want to do. */
 {
 safef(javascript, JBUFSIZE*sizeof(char),
       "document.%s.action = '%s'; document.%s.%s.value='%s'; "
       "document.%s.submit();",
       formName, cgiScriptName(), formName, buttonVar, label,
       formName);
 }
+#endif///ndef SUBTRACK_CFG
 
 #define MANY_SUBTRACKS  8
 
 #define WIGGLE_HELP_PAGE  "../goldenPath/help/hgWiggleTrackHelp.html"
 
 boolean cfgBeginBoxAndTitle(struct trackDb *tdb, boolean boxed, char *title)
 /* Handle start of box and title for individual track type settings */
 {
 if(!boxed)
     {
     boxed = trackDbSettingOn(tdb,"boxedCfg");
     if(boxed)
         printf("<BR>");
     }
 if (boxed)
@@ -7051,63 +7103,69 @@
 BUTTON_PLUS_ALL_GLOBAL();
 BUTTON_MINUS_ALL_GLOBAL();
 puts("&nbsp;<B>Select all subtracks</B><BR>");
 return TRUE;
 }
 
 static boolean compositeUiNoMatrix(char *db, struct cart *cart, struct trackDb *parentTdb,
           char *primarySubtrack, char *formName)
 /* UI for composite tracks: subtrack selection.  This is the default UI
 without matrix controls. */
 {
 int i, j, k;
 char *words[SMALLBUF];
 char option[SMALLBUF];
 int wordCnt;
+#ifndef SUBTRACK_CFG
 char javascript[JBUFSIZE];
+#endif///ndef SUBTRACK_CFG
 char *primaryType = getPrimaryType(primarySubtrack, parentTdb);
 char *name, *value;
 char buttonVar[32];
 char setting[] = "subGroupN";
 char *button;
 struct trackDb *subtrack;
 bool hasSubgroups = (trackDbSetting(parentTdb, "subGroup1") != NULL);
 
 if(dimensionsExist(parentTdb))
     return FALSE;
 
 puts ("<TABLE>");
 if (hasSubgroups)
     {
     puts("<TR><B>Select subtracks:</B></TR>");
     puts("<TR><TD><B><EM>&nbsp; &nbsp; All</EM></B>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </TD><TD>");
     }
 else
     {
     puts("<TR><TD><B>All subtracks:</B></TD><TD>");
     }
 safef(buttonVar, sizeof buttonVar, "%s", "button_all");
 if (formName)
     {
+#ifdef SUBTRACK_CFG
+    makeAddClearButtonPair(NULL,"</TD><TD>"); // NULL means all
+#else///ifndef SUBTRACK_CFG
     cgiMakeHiddenVar(buttonVar, "");
     makeAddClearSubmitTweak(javascript, formName, buttonVar,
                 ADD_BUTTON_LABEL);
     cgiMakeOnClickButton(javascript, ADD_BUTTON_LABEL);
     puts("</TD><TD>");
     makeAddClearSubmitTweak(javascript, formName, buttonVar,
                 CLEAR_BUTTON_LABEL);
     cgiMakeOnClickButton(javascript, CLEAR_BUTTON_LABEL);
+#endif///ndef SUBTRACK_CFG
     }
 else
     {
     cgiMakeButton(buttonVar, ADD_BUTTON_LABEL);
     puts("</TD><TD>");
     cgiMakeButton(buttonVar, CLEAR_BUTTON_LABEL);
     }
 button = cgiOptionalString(buttonVar);
 if (isNotEmpty(button))
     {
     struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(parentTdb->subtracks);
     struct slRef *tdbRef;
     for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next)
         {
 	subtrack = tdbRef->val;
@@ -7139,38 +7197,42 @@
         continue;
     subGroup = cloneString(words[0]);
     if(sameWord(subGroup,"view"))
         continue;  // Multi-view should have taken care of "view" subgroup already
     puts ("<TABLE>");
     printf("<TR><TD><B><EM>&nbsp; &nbsp; %s</EM></B></TD></TR>", words[1]);
     for (j = 2; j < wordCnt; j++)
         {
         if (!parseAssignment(words[j], &name, &value))
             continue;
         printf("<TR><TD>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; %s</TD><TD>",
            value);
         safef(buttonVar, sizeof buttonVar, "%s_%s", subGroup, name);
         if (formName)
             {
+        #ifdef SUBTRACK_CFG
+            makeAddClearButtonPair(name,"</TD><TD>");
+        #else///ifndef SUBTRACK_CFG
             cgiMakeHiddenVar(buttonVar, "");
             makeAddClearSubmitTweak(javascript, formName, buttonVar,
                         ADD_BUTTON_LABEL);
             cgiMakeOnClickButton(javascript, ADD_BUTTON_LABEL);
             puts("</TD><TD>");
             makeAddClearSubmitTweak(javascript, formName, buttonVar,
                         CLEAR_BUTTON_LABEL);
             cgiMakeOnClickButton(javascript, CLEAR_BUTTON_LABEL);
+        #endif///ndef SUBTRACK_CFG
             }
         else
             {
             cgiMakeButton(buttonVar, ADD_BUTTON_LABEL);
             puts("</TD><TD>");
             cgiMakeButton(buttonVar, CLEAR_BUTTON_LABEL);
             }
         puts("</TD></TR>");
         button = cgiOptionalString(buttonVar);
         if (isEmpty(button))
             continue;
 	struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(parentTdb->subtracks);
 	struct slRef *tdbRef;
 	for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next)
             {