fcb6dc8dfa166136193177c895ca181200850e4d max Mon Jan 19 06:02:31 2026 -0800 changing superTrack TrackUi quite a bit. Removing dropdowns and replacing them with buttons. Also adding buttons for setting all tracks or all visible tracks to a visibility. While at it, making a change to the js-query-library function (inversed the order of arguments) which was requested months ago by Brian, but I forgot to make the change after code review. Also shortening the "source data version" label to just "version". refs #36917. I changed the library function hTvDropDownClassVisOnlyAndExtra() rather than copying the code. This was because I was hesitant to copy/paste all this code into a second function, which would have been the only alternative, as the function cannot be reused as-is. So I modified the function to return the list of visibilities. It's never clear whether it's better to modify functions or copy/paste code. here, not breaking the function into smaller parts, so copy/pasting it, would risk requiring more future copy/pasted code. But the risk is to break existing tracks. diff --git src/hg/hgTrackUi/hgTrackUi.c src/hg/hgTrackUi/hgTrackUi.c index 620d8a43375..a3c4af87669 100644 --- src/hg/hgTrackUi/hgTrackUi.c +++ src/hg/hgTrackUi/hgTrackUi.c @@ -2727,91 +2727,145 @@ static boolean isInTrackList(struct trackDb *tdbList, struct trackDb *target) /* Return TRUE if target is in tdbList. */ { struct trackDb *tdb; for (tdb = tdbList; tdb != NULL; tdb = tdb->next) if (tdb == target) return TRUE; return FALSE; } #endif /* UNUSED */ void superTrackUi(struct trackDb *superTdb, struct trackDb *tdbList) /* List tracks in this collection, with visibility controls and UI links */ { jsIncludeFile("hui.js",NULL); -printf("\n

"); +printf("

") +printf("Tracks that are part of this container are listed below. Use the buttons below to set their visibilities.

"); +printf("\n
"); tdbRefSortPrioritiesFromCart(cart, &superTdb->children); struct slRef *childRef; char javascript[1024]; for (childRef = superTdb->children; childRef != NULL; childRef = childRef->next) { struct trackDb *tdb = childRef->val; if (childRef == superTdb->children) // first time through { - printf("\n\n"); } printf("\n\n"); printf(""); } printf("
"); - printf(""); - jsOnEventById("click", "btn_plus_all", "superT.plusMinus(true);"); - printf(""); - jsOnEventById("click", "btn_minus_all", "superT.plusMinus(false);"); - printf(" All
"); + printf("
\n"); + + printf("Apply visibility: \n"); + printf("\n"); + + printInfoIcon("The 'Apply to all' button sets all tracks below to the visibility selected on this dropdown. The 'Apply to all visible' button sets this visibility on all tracks below that are not hidden."); + + printf(" \n"); + // set all selectors to the current value of the top select + jsOnEventById("click", "superVizApplyAllButton", "let newVal = $('#superSubViz').val(); $('#superTrackTable select').val(newVal).trigger('change').removeClass('hiddenText').addClass('normalText');"); + + // set all selectors that are not on 'hide' to the current value of the top select + printf("\n"); + jsOnEventById("click", "superVizApplyButton", "let newVal = $('#superSubViz').val(); $('#superTrackTable select').filter(function() { return $(this).val() !== 'hide'; }).val(newVal).trigger('change').removeClass('hiddenText').addClass('normalText'); "); printf("
"); if (!tdbIsDownloadsOnly(tdb)) { char id[256]; enum trackVisibility tv = hTvFromString(cartUsualString(cart, tdb->track,hStringFromTv(tdb->visibility))); - // Don't use cheapCgi code... no name and no boolshad... just js safef(id, sizeof id, "%s_check", tdb->track); - printf("", + printf("", id, (tv != tvHide?" CHECKED":"")); - jsOnEventById("change", id, "superT.childChecked(this);"); - safef(javascript, sizeof(javascript), "superT.selChanged(this)"); struct slPair *event = slPairNew("change", cloneString(javascript)); + + char *onlyVis = trackDbSetting(tdb, "onlyVisibility"); hTvDropDownClassVisOnlyAndExtra(tdb->track, tv, tdb->canPack, (tv == tvHide ? "hiddenText":"normalText"), - trackDbSetting(tdb, "onlyVisibility"), + onlyVis, event); + // print a group of buttons that act like radiobuttons (see javascript lines below) + printf("
", tdb->track); + char *trackVizStr = hStringFromTv(tv); + + // vizList is e.g. {"Hide", "Dense", "Squish", "Pack", "Full"}, but can be shorter, e.g. when canPack=false + char **vizList = hTvGetVizArr(tv, tdb->canPack, onlyVis); + int vizListLen = arrNullLen(vizList); + for (int i = 0; i < vizListLen; i++) { + char *buttonViz = vizList[i]; + // the currently active viz mode is an 'active' button = pressed + if (strcasecmp(buttonViz, trackVizStr) == 0) + printf("",buttonViz); + } + puts("\n
"); hPrintPennantIcon(tdb); safef(id, sizeof id, "%s_link", tdb->track); + // the "); printf("%s ",tdb->shortLabel); } printf("%s", tdb->longLabel); printf("  "); printDataVersion(database, tdb); //printf("  %s", dataVersion); printf("
"); + +// Now configure the elements above with Javascript: + +// * Clicking a button sets the dropdown to the button's text +jsOnEventBySelector("click", ".seg-btn-group > button", "let dropdown = $('#' + $(this).parent().data('trackname')); let buttonText=$(this).text().toLowerCase(); dropdown.val(buttonText).removeClass('hiddenText').addClass('normalText');"); +// * Clicking buttons does not submit the form (default action of