31a8f798f6eb4466ccb1a7b76e5644b55c369980
max
Fri Mar 13 06:16:40 2026 -0700
subCfg: auto-show/hide composite vis on subtrack checkbox changes, refs #37182
Move the logic that auto-sets composite visibility to pack/hide when
subtracks are checked/unchecked into a separate onUserCbChange handler
bound via native addEventListener. jQuery .trigger('change') only fires
jQuery handlers, not native ones, so this correctly distinguishes real
user clicks from programmatic triggers during page init. Also bind it
on matCB (matrix) checkboxes and check only visible subCBs to avoid
counting hidden-but-checked subtracks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
diff --git src/hg/js/subCfg.js src/hg/js/subCfg.js
index cca8be93433..e2ca2dd1025 100644
--- src/hg/js/subCfg.js
+++ src/hg/js/subCfg.js
@@ -36,59 +36,61 @@
// There is one instance and these vars are page wide
compositeName: undefined,
canPack: true, // if composite vis is only hide,dense,full, then all children also restricted.
visIndependent: false,
viewTags: [],
markChange: function (eventObj, obj)
{ // Marks a control as having been changed by the user. Naming will send value to cart.
// Note this is often called directly as the onchange event function
if (!obj || $.type(obj) === "string")
obj = this;
$(obj).addClass('changed');
- // if the user checked a child checkbox that used to be unchecked, and the parent composite is on hide,
- // then set the parent composite to pack
- var compEl = $("[name='"+this.compositeName+"'");
- if (compEl.length!==0 && obj.type==="checkbox" && obj.checked && compEl.val()==="hide")
- compEl.val("pack").change();
-
// checkboxes have hidden boolshads which should be marked when unchecked
if (obj.type === "checkbox") {
var boolshad = normed($("input.cbShadow#boolshad\\."+obj.id));
if (boolshad) {
$(boolshad).addClass('changed');
} else {
boolshad = normed($("input.cbShadow[name='boolshad\\." + obj.name+"']"));
if (boolshad) {
$(boolshad).addClass('changed');
}
}
-
- // if the user unchecked a child checkbox that used to be checked, and the parent composite is on pack,
- // and no more child is checked, then set the parent composite to hide.
- var subCfgs = $(".subCB:checked");
- if (subCfgs.length===0) {
- //$(obj).val("pack"); //
- //compEl.val("hide").change();
- compEl.val("hide");
- $(obj).val("hide");
- }
}
+ },
+
+ // Called only on real user clicks (bound via native addEventListener, not jQuery,
+ // so jQuery .trigger('change') calls during init do not reach this).
+ // Handles both subCB and matCB clicks.
+ onUserCbChange: function () {
+ var compEl = $("[name='"+subCfg.compositeName+"']");
+ if (compEl.length === 0)
+ return;
+
+ var anyChecked = $(".subCB:checked:visible").length > 0;
+
+ // if any subtracks are now checked and the composite is on hide, set it to pack
+ if (anyChecked && compEl.val() === "hide")
+ compEl.val("pack").change();
+ // if no subtracks are checked, set the composite to hide
+ if (!anyChecked)
+ compEl.val("hide");
},
clearChange: function (obj)
{ // Mark as unchanged
$(obj).removeClass('changed');
// checkboxes have hidden boolshads which should be cleared in tandem
if (obj.type === "checkbox") {
var boolshad = normed($("input.cbShadow#boolshad\\."+obj.id));
if (boolshad) {
$(boolshad).removeClass('changed');
} else {
boolshad = normed($("input.cbShadow[name='boolshad\\." + obj.name+"']"));
if (boolshad) {
$(boolshad).removeClass('changed');
@@ -849,30 +851,42 @@
subCfg.visIndependent = ($('.subVisDD').length > 0); // Can subtracks have their own vis?
// Set up vis propagation and change flagging
compVis = compVis[0];
$(compVis).bind('change',function (e) {
subCfg.markChange(e,compVis);
subCfg.propagateVis(compVis,undefined);
});
// SubCBs will may enable/diable vis/wrench and will be flagged on change
var subCbs = $('input.subCB');
$(subCbs).change( function (e) {
subCfg.enableCfg(this, (this.checked && !isFauxDisabled(this, true)));
subCfg.markChange(e,this);
});
+ // Native listener for user-only actions (auto-show/hide composite).
+ // jQuery .trigger('change') only fires jQuery handlers, not native ones,
+ // so this runs only on real user interactions.
+ $(subCbs).each(function () {
+ this.addEventListener('change', subCfg.onUserCbChange);
+ });
+ // Same for matCBs (matrix checkboxes that check/uncheck groups of subCBs).
+ // The inline onclick handler (matCbClick) updates subCBs first, then this
+ // native listener checks the resulting state.
+ $('input.matCB').each(function () {
+ this.addEventListener('click', subCfg.onUserCbChange);
+ });
// iterate through views
var viewVis = $('select.viewDD');
$(viewVis).each(function (i) {
var classList = $( this ).attr("class").split(" ");
classList = aryRemove(classList,["viewDD","normalText","changed"]);
if (classList.length === 0)
warn('DEBUG: View classlist is missing view class.');
else if (classList.length > 1)
warn('DEBUG: View classlist contains unexpected classes:' + classList);
else {
subCfg.viewTags[i] = classList[0];
subCfg.viewInit(subCfg.viewTags[i]);
}
});