b49b64da2abd8202b9d2fd5243a777f3906de708
kate
  Fri May 10 13:11:16 2019 -0700
Fix problem with +/- buttons controlling vertical colunmns in matrix.  They were being created with non-unique ids. refs #23452

diff --git src/hg/lib/hui.c src/hg/lib/hui.c
index a38fb62..ca20e1b 100644
--- src/hg/lib/hui.c
+++ src/hg/lib/hui.c
@@ -7477,40 +7477,42 @@
     jsOnEventById("click", id, javascript);
 #define MATRIX_RIGHT_BUTTONS_AFTER 8
 #define MATRIX_BOTTOM_BUTTONS_AFTER 20
 
 static void buttonsForAll(boolean left, boolean top)
 {
 char id[256];
 char javascript[1024];
 char fullname[256];
 safef(fullname, sizeof fullname, "plus_all_%s_%s", left ? "left" : "right", top ? "top" : "bottom");
 PM_MAKE_BUTTON_UC("true", "", "", "", "", "",  fullname,    "add_sm.gif")
 safef(fullname, sizeof fullname, "minus_all_%s_%s", left ? "left" : "right", top ? "top" : "bottom");
 PM_MAKE_BUTTON_UC("false","", "", "", "", "", fullname, "remove_sm.gif")
 }
 
-static void buttonsForOne(char *class, boolean vertical, boolean left)
+static void buttonsForOne(char *class, boolean vertical, boolean left, boolean top)
 {
 char id[256];
 char javascript[1024];
 char fullname[256];
-safef(fullname, sizeof fullname, "plus_%s_all_%s" , class, left?"left":"right");
+safef(fullname, sizeof fullname, "plus_%s_all_%s_%s" , class, left ? "left" : "right",
+                        top ? "top" : "bottom");
 PM_MAKE_BUTTON_UC("true",  ",'", class, "'", "", "", fullname,    "add_sm.gif")
 if (vertical)
     puts("<BR>");
-safef(fullname, sizeof fullname, "minus_%s_all_%s", class, left?"left":"right");
+safef(fullname, sizeof fullname, "minus_%s_all_%s_%s", class, left ? "left" : "right",
+                        top ? "top" : "bottom");
 PM_MAKE_BUTTON_UC("false", ",'", class, "'", "", "", fullname, "remove_sm.gif")
 }
 
 #define MATRIX_SQUEEZE 10
 static boolean matrixSqueeze(membersForAll_t* membersForAll)
 // Returns non-zero if the matrix will be squeezed.  Non-zero is actually squeezedLabelHeight
 {
 char *browserVersion;
 if (btIE == cgiClientBrowser(&browserVersion, NULL, NULL) && *browserVersion < '9')
     return 0;
 
 members_t *dimensionX = membersForAll->members[dimX];
 members_t *dimensionY = membersForAll->members[dimY];
 if (dimensionX && dimensionY)
     {
@@ -7608,100 +7610,100 @@
                    top ? "TOP" : "BOTTOM", dimensionX->groupTitle);
         }
     }
 else if (dimensionY)
     {
     printf("<TH ALIGN=RIGHT WIDTH=100 nowrap>");
     printf("<B><EM>%s</EM></B>", dimensionY->groupTitle);
     printf("</TH><TH ALIGN=CENTER WIDTH=60>");
     buttonsForAll(FALSE, top);
     puts("</TH>");
     }
 puts("</TR>\n");
 }
 
 static void matrixXheadingsRow2(struct trackDb *parentTdb, boolean squeeze,
-                                membersForAll_t* membersForAll)
+                                membersForAll_t* membersForAll, boolean top)
 // prints the 2nd row of a matrix: Y title; X buttons; title Y
 {
 members_t *dimensionX = membersForAll->members[dimX];
 members_t *dimensionY = membersForAll->members[dimY];
 
 // If there are both X and Y dimensions, then there is a row of buttons in X
 if (dimensionX && dimensionY)
     {
     int ixX,cntX=0;
     printf("<TR ALIGN=CENTER><TH ALIGN=CENTER colspan=2><B><EM>%s</EM></B></TH>",
            dimensionY->groupTitle);
     for (ixX = 0; ixX < dimensionX->count; ixX++)    // Special row of +- +- +-
         {
         if (dimensionX->subtrackList
         &&  dimensionX->subtrackList[ixX]
         &&  dimensionX->subtrackList[ixX]->val)
             {
             printf("<TD nowrap class='matCell %s all'>\n",dimensionX->tags[ixX]);
-            buttonsForOne( dimensionX->tags[ixX], squeeze, TRUE);
+            buttonsForOne(dimensionX->tags[ixX], squeeze, TRUE, top);
             puts("</TD>");
             cntX++;
             }
         }
     // If dimension is big enough, then add Y buttons to right as well
     if (cntX>MATRIX_RIGHT_BUTTONS_AFTER)
         printf("<TH ALIGN=CENTER colspan=2><B><EM>%s</EM></B></TH>", dimensionY->groupTitle);
     puts("</TR>\n");
     }
 }
 
 static boolean matrixXheadings(char *db,struct trackDb *parentTdb, membersForAll_t* membersForAll,
                                boolean top)
 // UI for X headings in matrix
 {
 boolean squeeze = matrixSqueeze(membersForAll);
 
 if (top)
     matrixXheadingsRow1(db, parentTdb, squeeze, membersForAll, top);
 
-matrixXheadingsRow2(parentTdb,squeeze,membersForAll);
+matrixXheadingsRow2(parentTdb, squeeze, membersForAll, top);
 
 if (!top)
     matrixXheadingsRow1(db, parentTdb, squeeze, membersForAll, top);
 
 return squeeze;
 }
 
 static void matrixYheadings(char *db,struct trackDb *parentTdb, membersForAll_t* membersForAll,
                             int ixY, boolean left)
 // prints the column of Y labels and buttons
 {
 members_t *dimensionX = membersForAll->members[dimX];
 members_t *dimensionY = membersForAll->members[dimY];
 
 struct trackDb *childTdb = NULL;
 if (dimensionY
 &&  dimensionY->subtrackList
 &&  dimensionY->subtrackList[ixY]
 &&  dimensionY->subtrackList[ixY]->val)
     childTdb = dimensionY->subtrackList[ixY]->val;
 
 if (dimensionX && dimensionY && childTdb != NULL) // Both X and Y, then column of buttons
     {
     printf("<TH class='matCell all %s' ALIGN=%s nowrap colspan=2>",
            dimensionY->tags[ixY],left?"RIGHT":"LEFT");
     if (left)
         printf("%s&nbsp;",compositeLabelWithVocabLink(db,parentTdb,childTdb,dimensionY->groupTag,
                                                       dimensionY->titles[ixY]));
-    buttonsForOne( dimensionY->tags[ixY], FALSE, left);
+    buttonsForOne(dimensionY->tags[ixY], FALSE, left, FALSE);
     if (!left)
         printf("&nbsp;%s",compositeLabelWithVocabLink(db,parentTdb,childTdb,dimensionY->groupTag,
                                                       dimensionY->titles[ixY]));
     puts("</TH>");
     }
 else if (dimensionX)
     {
     printf("<TH ALIGN=%s>",left?"RIGHT":"LEFT");
     buttonsForAll(TRUE, TRUE);  // WARNING: not tested (is this used ?)
     puts("</TH>");
     }
 else if (left && dimensionY && childTdb != NULL)
     printf("<TH class='matCell all %s' ALIGN=RIGHT nowrap>%s</TH>\n",dimensionY->tags[ixY],
            compositeLabelWithVocabLink(db,parentTdb,childTdb,dimensionY->groupTag,
                                        dimensionY->titles[ixY]));