d247275d8266bad8d22c108df1b40a8665e109bf
tdreszer
  Fri Sep 23 16:16:24 2011 -0700
Another load of subCfg module (scm). Heavy work getting subCbs, matCbs and views all playing nice.
diff --git src/hg/js/hui.js src/hg/js/hui.js
index 479a773..edaca7f 100644
--- src/hg/js/hui.js
+++ src/hg/js/hui.js
@@ -1,2059 +1,1133 @@
 // JavaScript Especially for hui.c
 // $Header: /projects/compbio/cvsroot/kent/src/hg/js/hui.js,v 1.59 2010/06/03 20:27:26 tdreszer Exp $
 
 var compositeName = "";
 //var browser;                // browser ("msie", "safari" etc.)
 //var now = new Date();
 //var start = now.getTime();
 //$(window).load(function () {
 //    if(start != null) {
 //        now = new Date();
 //        alert("Loading took "+(now.getTime() - start)+" msecs.");
 //    }
 //});
 
 
 // The 'mat*' functions are especially designed to support subtrack configuration by 2D matrix of controls
 
 function _matSelectViewForSubTracks(obj,view)
 {
 // viewDD:onchange Handle any necessary changes to subtrack checkboxes when the view changes
 // views are "select" drop downs on a subtrack configuration page
     var classesHidden = ""; // Needed for later
 
     if( obj.selectedIndex == 0) { // hide
         matSubCBsEnable(false,view);
         hideConfigControls(view);
 
         // Needed for later
         classesHidden = matViewClasses('hidden');
         classesHidden = classesHidden.concat( matAbcCBclasses(false) );
     } else {
         // Make main display dropdown show full if currently hide
         compositeName = obj.name.substring(0,obj.name.indexOf(".")); // {trackName}.{view}.vis
         matSubCBsEnable(true,view);
 
         // Needed for later
         classesHidden = matViewClasses('hidden');
         classesHidden = classesHidden.concat( matAbcCBclasses(false) );
 
         // If hide => show then check all subCBs matching view and matCBs
         // If show => show than just enable subCBs for the view.
         if (obj.lastIndex == 0) { // From hide to show
             // If there are matCBs then we will check some subCBs if we just went from hide to show
             var matCBs = $("input.matCB:checked");
             if (matCBs.length > 0) {
                 // Get list of all checked abc classes first
                 var classesAbcChecked = new Array();
                 matCBs.filter(".abc").each( function (i) {
                     var classList = $( this ).attr("class").split(" ");
-                    classesAbcChecked.push( aryRemove(classList,"matCB","halfVis","abc") );
+                    classesAbcChecked.push( aryRemove(classList,["matCB","disabled","abc"]) );
                 });
 
                 // Walk through checked non-ABC matCBs and sheck related subCBs
                 var subCBs = $("input.subCB").filter("."+view).not(":checked");
                 matCBs.not(".abc").each( function (i) {
                     var classList = $( this ).attr("class").split(" ");
-                    classList = aryRemove(classList,"matCB","halfVis");
+                    classList = aryRemove(classList,["matCB","disabled"]);
                     var subCBsMatching = objsFilterByClasses(subCBs,"and",classList);
                     if (classesAbcChecked.length>0)
                         subCBsMatching = objsFilterByClasses(subCBsMatching,"or",classesAbcChecked);
                     // Check the subCBs that belong to this view and checked matCBs
                     subCBsMatching.each( function (i) {
                         this.checked = true;
-                        matSubCBsetShadow(this);
+                        matSubCBsetShadow(this);  // will update "scm" if needed
                         hideOrShowSubtrack(this);
                     });
                 });
             } // If no matrix, then enabling is all that was needed.
 
-            // fix 3-way which may need to go from unchecked to .halfVis
-            var matCBs = $("input.matCB").not(".abc").not(".halfVis").not(":checked");
+            // fix 3-way which may need to go from unchecked to .disabled
+            var matCBs = $("input.matCB").not(".abc").not(".disabled").not(":checked");
             if(matCBs.length > 0) {
                 $( matCBs ).each( function (i) { matChkBoxNormalize( this, classesHidden ); });
             }
         }
     }
-    // fix 3-way matCBs which may need to go from halfVis to checked or unchecked depending
-    var matCBs = $("input.matCB").not(":checked").not(".halfVis");
+    // fix 3-way matCBs which may need to go from disabled to checked or unchecked depending
+    var matCBs = $("input.matCB").not(":checked").not(".disabled");
     var matCBs = matCBsWhichAreComplete(false);
     if(matCBs.length > 0) {
         if($("select.viewDD").not("[selectedIndex=0]").length = 0) { // No views visible so nothing is inconsistent
             $( matCBs ).each( function (i) { matCbComplete( this, true ); });
         } else {
             $( matCBs ).each( function (i) { matChkBoxNormalize( this, classesHidden ); });
         }
     }
     matSubCBsSelected();
     obj.lastIndex = obj.selectedIndex;
 }
 
 function matSelectViewForSubTracks(obj,view)
 {
     waitOnFunction( _matSelectViewForSubTracks, obj,view);
 }
 
 function exposeAll()
 {
     // Make main display dropdown show full if currently hide
     var visDD = normed($("select.visDD")); // limit to hidden
     if (visDD != undefined) {
         if ($(visDD).attr('selectedIndex') == 0) {
             $(visDD).attr('selectedIndex',$(visDD).children('option').length - 1);
             $(visDD).change(); // triggers onchange code effecting inherited subtrack vis
         }
     }
 }
 
 function matSubCbClick(subCB)
 {
 // subCB:onclick  When a subtrack checkbox is clicked, it may result in
 // Clicking/unclicking the corresponding matrix CB.  Also the
 // subtrack may be hidden as a result.
-    if (common.subCfg)
-        scm.checkOneSubtrack(subCB,subCB.checked,!subCB.disabled);
-    //////////matSubCBsetShadow(subCB);
-    //////////hideOrShowSubtrack(subCB);
+
+    // NOTE: if "scm" then 'change' event will update it
+    if (isFauxDisabled(subCB,false)) { // disabled subCB is still clickable when "scm"
+        subCB.checked = true;
+        fauxDisable(subCB,false,""); // enable and get rid of message
+    }
+    matSubCBsetShadow(subCB);
+    hideOrShowSubtrack(subCB);
     // When subCBs are clicked, 3-state matCBs may need to be set
     var classes = matViewClasses('hidden');
     classes = classes.concat( matAbcCBclasses(false) );
     var matCB = matCbFindFromSubCb( subCB );
     if( matCB != undefined ) {
         matChkBoxNormalize( matCB, classes );
     }
     //var abcCB = matAbcCbFindFromSubCb( subCB );
     //if( abcCB != undefined ) {
     //    matChkBoxNormalize( abcCB, classes );
     //}
 
     if(subCB.checked)
         exposeAll();  // Unhide composite vis?
 
     matSubCBsSelected();
 }
 
 function matCbClick(matCB)
 {
 // matCB:onclick  When a matrix CB is clicked, the set of subtracks checked may change
 // Also called indirectly by matButton:onclick via matSetMatrixCheckBoxes
 
     var classList = $( matCB ).attr("class").split(" ");
     var isABC = (aryFind(classList,"abc") != -1);
-    classList = aryRemove(classList,"matCB","halfVis","abc");
+    classList = aryRemove(classList,["matCB","disabled","abc"]);
     if(classList.length == 0 )
        matSubCBsCheck(matCB.checked);
     else if(classList.length == 1 )
        matSubCBsCheck(matCB.checked,classList[0]);               // dimX or dimY or dim ABC
     else if(classList.length == 2 )
        matSubCBsCheck(matCB.checked,classList[0],classList[1]);  // dimX and dimY
     else
         warn("ASSERT in matCbClick(): There should be no more than 2 entries in list:"+classList)
 
     if(!isABC)
         matCbComplete(matCB,true); // No longer partially checked
 
     if(isABC) {  // if dim ABC then we may have just made indeterminate X and Ys determinate
         if(matCB.checked == false) { // checking new dim ABCs cannot change indeterminate state.   IS THIS TRUE ?  So far.
             var matCBs = matCBsWhichAreComplete(false);
             if(matCBs.length > 0) {
                 if($("input.matCB.abc:checked").length == 0) // No dim ABC checked, so leave X&Y checked but determined
                     $( matCBs ).each( function (i) { matCbComplete( this, true ); });
                 else {
                     var classes = matViewClasses('hidden');
                     classes = classes.concat( matAbcCBclasses(false) );
                     $( matCBs ).each( function (i) { matChkBoxNormalize( this, classes ); });
                 }
             }
         }
     }
 
     if(matCB.checked)
         exposeAll();  // Unhide composite vis?
     matSubCBsSelected();
 }
 
 function _matSetMatrixCheckBoxes(state)
 {
 // matButtons:onclick Set all Matrix checkboxes to state.  If additional arguments are passed in, the list of CBs will be narrowed by the classes
     //jQuery(this).css('cursor', 'wait');
     var matCBs = $("input.matCB").not(".abc");
     for(var vIx=1;vIx<arguments.length;vIx++) {
         matCBs = $( matCBs ).filter("."+arguments[vIx]);  // Successively limit list by additional classes.
     }
     $( matCBs ).each( function (i) {
         this.checked = state;
         matCbComplete(this,true);
     });
     var subCbs = $("input.subCB");
     for(var vIx=1;vIx<arguments.length;vIx++) {
         subCbs = $( subCbs ).filter("."+arguments[vIx]);  // Successively limit list by additional classes.
     }
     if(state) { // If clicking [+], further limit to only checked ABCs
         var classes = matAbcCBclasses(false);
         subCbs = objsFilterByClasses(subCbs,"not",classes);  // remove unchecked abcCB classes
     }
-    if (common.subCfg) {
         $( subCbs ).each( function (i) {
-            scm.checkOneSubtrack(this,state,!(this.disabled));
-        /////////this.checked = state;
-        /////////matSubCBsetShadow(this);
-        /////////scm.enableCfg(this,null,this.checked);
-        });
+        if (this.checked != state) {
+            this.checked = state;
+            $(this).change() // NOTE: if "scm" then 'change' event will update it
+            matSubCBsetShadow(this);
     }
+    });
     if(state)
         exposeAll();  // Unhide composite vis?
-    ////////showOrHideSelectedSubtracks();
+    showOrHideSelectedSubtracks();
     matSubCBsSelected();
     //jQuery(this).css('cursor', '');
 
     var tbody = $( subCbs[0] ).parents('tbody.sorting');
     if (tbody != undefined)
          $(tbody).removeClass('sorting');
     return true;
 }
 function matSetMatrixCheckBoxes(state)
-{
+{ // Called exclusively by matrix [+][-] buttons on click
     var tbody = $( 'tbody.sortable');
     if (tbody != undefined)
          $(tbody).addClass('sorting');
 
     if (arguments.length >= 5)
         waitOnFunction(_matSetMatrixCheckBoxes,state,arguments[1],arguments[2],arguments[3],arguments[4]);
     else if (arguments.length >= 4)
         waitOnFunction(_matSetMatrixCheckBoxes,state,arguments[1],arguments[2],arguments[3]);
     else if (arguments.length >= 3)
         waitOnFunction(_matSetMatrixCheckBoxes,state,arguments[1],arguments[2]);
     else if (arguments.length >= 2)
         waitOnFunction(_matSetMatrixCheckBoxes,state,arguments[1]);
     else
         waitOnFunction(_matSetMatrixCheckBoxes,state);
 
 }
 
 ///////////// CB support routines ///////////////
 // Terms:
 // viewDD - view drop-down control
 // matButton: the [+][-] button controls associated with the matrix
 // matCB - matrix dimX and dimY CB controls (in some cases this set contains abcCBs as well because they are part of the matrix)
 // abcCB - matrix dim (ABC) CB controls
 // subCB - subtrack CB controls
 // What does work
 // 1) 4 state subCBs: checked/unchecked enabled/disabled (which is visible/hidden)
 // 2) 3 state matCBs for dimX and Y but not for Z (checked,unchecked,indeterminate (incomplete set of subCBs for this matCB))
 // 3) cart vars for viewDD, abcCBs and subCBs but matCBs set by the state of those 3
 // What is awkward or does not work
 // A) Awkward: matCB could be 5 state (all,none,subset,superset,excusive non-matching set)
 function matSubCBsCheck(state)
 {
 // Set all subtrack checkboxes to state.  If additional arguments are passed in, the list of CBs will be narrowed by the classes
 // called by matCB clicks (matCbClick()) !
     var subCBs = $("input.subCB");
     for(var vIx=1;vIx<arguments.length;vIx++) {
         subCBs = subCBs.filter("."+arguments[vIx]);  // Successively limit list by additional classes.
     }
 
     if(state) { // If checking subCBs, then make sure up to 3 dimensions of matCBs agree with each other on subCB verdict
         var classes = matAbcCBclasses(false);
         if (classes.length > 0)
             subCBs = objsFilterByClasses(subCBs,"not",classes);  // remove unchecked abcCB classes
         if(arguments.length == 1 || arguments.length == 3) { // Requested dimX&Y: check dim ABC state
             $( subCBs ).each( function (i) { matSubCBcheckOne(this,state); });
         } else {//if(arguments.length == 2) { // Requested dim ABC (or only 1 dimension so this code is harmless)
             var matXY = $("input.matCB").not(".abc");  // check X&Y state
             matXY = $( matXY ).filter(":checked");
             for(var mIx=0;mIx<matXY.length;mIx++) {
                 var classes = $(matXY[mIx]).attr("class").split(' ');
-                classes = aryRemove(classes,"matCB","halfVis");
+                classes = aryRemove(classes,["matCB","disabled"]);
                 $( subCBs ).filter('.'+classes.join(".")).each( function (i) { matSubCBcheckOne(this,state); });
             }
         }
     } else  // state not checked so no filtering by other matCBs needed
         subCBs.each( function (i) { matSubCBcheckOne(this,state); });
 
     return true;
 }
 
 function matSubCBsEnable(state)
 {
 // Enables/Disables subtracks checkboxes.  If additional arguments are passed in, the list of CBs will be narrowed by the classes
     var subCBs = $("input.subCB");
     for(var vIx=1;vIx<arguments.length;vIx++) {
         if(arguments[vIx].length > 0)
             subCBs = subCBs.filter("."+arguments[vIx]);  // Successively limit list by additional classes.
     }
     subCBs.each( function (i) {
         if(state) {
-            $(this).parent().attr('title','');
-            $(this).parent().attr('cursor','pointer');
+            fauxDisable(this,false,'');
+            $(this).parent().attr('cursor','');
         } else {
-            $(this).parent().attr('title','view is hidden');
+            fauxDisable(this,true, 'view is hidden');
             $(this).parent().attr('cursor','pointer');
         }
-        this.disabled = !state;
-        matSubCBsetShadow(this);
+        matSubCBsetShadow(this);    // will update "scm" if needed
         hideOrShowSubtrack(this);
     });
 
     return true;
 }
 
 function matSubCBcheckOne(subCB,state)
 {
 // setting a single subCB may cause it to appear/disappear
+    if (subCB.checked != state) {
     subCB.checked = state;
-    if (common.subCfg)
-       scm.checkOneSubtrack(subCB,state,!subCB.disabled);
+        $(subCB).change();  // NOTE: if "scm" then 'change' event will update it
     matSubCBsetShadow(subCB);
     hideOrShowSubtrack(subCB);
 }
+}
 
 function matSubCBsetShadow(subCB)
 {
 // Since CBs only get into cart when enabled/checked, the shadow control enables cart to know other states
+//  will update "scm" if needed
     var shadowState = 0;
     if(subCB.checked)
         shadowState = 1;
-    if(subCB.disabled)
+    //if(subCB.disabled)
+    if (isFauxDisabled(subCB,true))
         shadowState -= 2;
     var fourWay = normed($("input.fourWay#boolshad_-"+subCB.id));
     if (fourWay == undefined && subCB.name != undefined) {
         fourWay = normed($("input.fourWay[name='boolshad\\."+subCB.name+"']"));
         if (fourWay == undefined)
             fourWay = normed($("#"+subCB.name+"_4way"));  // FIXME: obsolete as soon as subCfg is working
     }
-    if (fourWay != undefined)
-        $(fourWay).val(shadowState);
-    else
+    if (fourWay == undefined) {
         warn("DEBUG: Failed to find fourWay shadow for '#"+subCB.id+"' ["+subCB.name+"]");
-    if (common.subCfg)
+        return;
+    }
+    if ($(fourWay).val() != shadowState) {
+        $(fourWay).val(shadowState);
+        if (typeof(scm) !== "undefined") {
         scm.enableCfg(subCB,null,(shadowState == 1));
+            $(subCB).change(); // 'change' event will update "scm"
+        }
+    }
 }
 
 function matChkBoxNormalize(matCB)
 {
 // Makes sure matCBs are in one of 3 states (checked,unchecked,indeterminate) based on matching set of subCBs
     var classList = $( matCB ).attr("class").split(" ");
     var isABC = (aryFind(classList,"abc") != -1);
     if(isABC)
         alert("ASSERT: matChkBoxNormalize() called for dim ABC!");
-    classList = aryRemove(classList,"matCB","halfVis");
+    classList = aryRemove(classList,["matCB","disabled"]);
 
     var classes = '.' + classList.join(".");// created string filter of classes converting "matCB K562 H3K4me1" as ".K562.H3K4me1"
     var subCBs = $("input.subCB").filter(classes); // All subtrack CBs that match matrix CB
 
     if(arguments.length > 1 && arguments[1].length > 0) { // dim ABC NOT classes
         subCBs = objsFilterByClasses(subCBs,"not",arguments[1]);
     }
 
     // Only look at visible views
-    subCBs = $(subCBs).not(":disabled");
+    subCBs = $(subCBs).not('.disabled').not(":disabled");
 
     if(subCBs.length > 0) {
         var CBsChecked = subCBs.filter(":checked");
         if(!isABC) {
             if(CBsChecked.length == subCBs.length) {
                 matCbComplete(matCB,true);
                 $(matCB).attr('checked',true);
             } else if(CBsChecked.length == 0) {
                 matCbComplete(matCB,true);
                 $(matCB).attr('checked',false);
             } else {
                 matCbComplete(matCB,false);
                 $(matCB).attr('checked',true);
             }
         }
     }
     else
         matCbComplete(matCB,true); // If no subs match then this is determined !
 }
 
 function matCbComplete(matCB,complete)
 {
 // Makes or removes the 3rd (indeterminate) matCB state
-    // Too many options:
-    // 1) addClass()/removeClass() (which does not directly support title)
-    // 2) wrap div which could contain border, color, content.  content is not on one line: size is difficult
-    // 3) wrap font which could contain border, color, content.  content is on one line: size is difficult
-    // 4) *[ ]* ?[ ]?  *[ ]*  No text seems right;  borders? colors? opacity? Yes, minimum
     if(complete) {
-        $(matCB).css('opacity', '1');  // For some reason IE accepts direct change but isn't happy with simply adding class!
-        $(matCB).removeClass('halfVis');
-        $(matCB).attr("title","");
+        fauxDisable(matCB,false,"");
     } else {
-        $(matCB).css('opacity', '0.5');
-        $(matCB).addClass('halfVis');
-        $(matCB).attr("title","Not all associated subtracks have been selected");
-        //$('.halfVis').css('opacity', '0.5');
+        fauxDisable(matCB,true, "Not all associated subtracks have been selected");
     }
 }
 
 function matCBsWhichAreComplete(complete)
 {
 // Returns a list of currently indeterminate matCBs.  This is encapsulated to keep consistent with matCbComplete()
     if(complete)
-        return $("input.matCB").not(".halfVis");
+        return $("input.matCB").not(".disabled");
     else
-        return $("input.matCB.halfVis");
+        return $("input.matCB.disabled");
 }
 
 function matCbFindFromSubCb(subCB)
 {
 // returns the one matCB associated with a subCB (or undefined)
     var classList =  $( subCB ).attr("class").split(" ");
     // we need one or 2 classes, depending upon how many dimensions in matrix (e.g. "subDB GM10847 NFKB aNone IGGrab Signal")
-    classList = aryRemove(classList,"subCB","changed");
+    classList = aryRemove(classList,["subCB","changed","disabled"]);
     var classes = classList.slice(0,2).join('.');   // How to get only X and Y classes?  Assume they are the first 2
     var matCB = $("input.matCB."+classes); // Note, this works for filtering multiple classes because we want AND
     if(matCB.length == 1)
         return matCB;
 
     matCB = $("input.matCB."+classList[0]); // No hit so this must be a 1D matrix
     if(matCB.length == 1)
         return matCB;
 
     return undefined;
 }
 
 function matAbcCBfindFromSubCb(subCB)
 {
 // returns the abcCBs associated with a subCB (or undefined)
     var abcCBs = $("input.matCB.abc");
     if( abcCBs.length > 0 ) {
         var classList =  $( subCB ).attr("class").split(" ");
-        classList = aryRemove(classList,"subCB","changed");
+        classList = aryRemove(classList,["subCB","changed","disabled"]);
         classList.shift(); // Gets rid of X and Y associated classes (first 2 after subCB)
         classList.shift();
         classList.pop();   // gets rid of view associated class (at end)
         if(classList.length >= 1) {
             var abcCB = $(abcCBs).filter('.'+classList.join("."));
             if(abcCB.length >= 1)
                 return abcCB;
         }
     }
     return undefined;
 }
 
 function objsFilterByClasses(objs,keep,classes)
 {
 // Accepts an obj list and an array of classes, then filters successively by that list
     if( classes != undefined && classes.length > 0 ) {
         if(keep == "and") {
             objs = $( objs ).filter( '.' + classes.join('.') ); // Must belong to all
         } else if(keep == "or") {
             objs = $( objs ).filter( '.' + classes.join(',.') ); // Must belong to one or more
         } else if(keep == "not") {
             for(var cIx=classes.length-1;cIx>-1;cIx--) {
                 objs = $( objs ).not( '.' + classes[cIx] ); // not('class1.class2') is different from not('.class1').not('.class2')
             }
         }
     }
     return objs;
 }
 
 function matViewClasses(limitTo)
 {
 // returns an array of classes from the ViewDd: converts "viewDD normalText SIG"[]s to "SIG","zRAW"
     var classes = new Array;
     var viewDDs = $("select.viewDD");//.filter("[selectedIndex='0']");
     if(limitTo == 'hidden') {
         viewDDs = $(viewDDs).filter("[selectedIndex=0]");
     } else if(limitTo == 'visible') {
         viewDDs = $(viewDDs).not("[selectedIndex=0]");
     }
     $(viewDDs).each( function (i) {
         var classList = $( this ).attr("class").split(" ");
-        classList = aryRemove(classList,"viewDD","normalText","changed");
+        classList = aryRemove(classList,["viewDD","normalText","changed"]);
         classes.push( classList[0] );
     });
     return classes;
 }
 
 function matAbcCBclasses(wantSelected)
 {// returns an array of classes from the dim ABC CB classes: converts "matCB abc rep1"[]s to "rep1","rep2"
     var classes = new Array;
     var abcCBs = $("input.matCB.abc");
     if(abcCBs.length > 0) {
         if (!wantSelected) {
             abcCBs = abcCBs.not(":checked");
         } else {
             abcCBs = abcCBs.filter(":checked");
         }
         $(abcCBs).each( function (i) {
             var classList = $( this ).attr("class").split(" ");
-            classList = aryRemove(classList,"matCB","abc");
+            classList = aryRemove(classList,["matCB","abc"]);
             classes.push( classList[0] );
         });
     } else { // No abcCBs so look for filterBox classes
         return filterCompositeClasses(wantSelected);
     }
     return classes;
 }
 
 function matSubCBsSelected()
 {
 // Displays visible and checked track count
     var counter = $('.subCBcount');
     if(counter != undefined) {
         var subCBs =  $("input.subCB");
         $(counter).text($(subCBs).filter(":enabled:checked").length + " of " +$(subCBs).length+ " selected");
     }
 }
 
 /////////////////// subtrack configuration support ////////////////
 function compositeCfgUpdateSubtrackCfgs(inp)
 {
 // Updates all subtrack configuration values when the composite cfg is changed
     // If view association then find it:
     var view = "";
     var daddy = normed($(inp).parents(".blueBox"));
     if(daddy != undefined) {
         var classList = $(daddy).attr("class").split(" ");
         if(classList.length == 2) {
             view = classList[1];
         }
     }
     var suffix = inp.name.substring(inp.name.indexOf("."));  // Includes '.'
     //if(suffix.length==0)
     //    suffix = inp.name.substring(inp.name.indexOf("_"));
     if(suffix.length==0) {
         warn("Unable to parse '"+inp.name+"'");
         return true;
     }
     if(inp.type.indexOf("select") == 0) {
         var list = $("select[name$='"+suffix+"']").not("[name='"+inp.name+"']"); // Exclude self from list
         if(view != "") { list =  $(list).filter(function(index) { return normed($(this).parents(".blueBox." + view)) != undefined; });}
         if($(list).length>0) {
             if(inp.multiple != true)
                 $(list).attr('selectedIndex',inp.selectedIndex);
             else {
                 $(list).each(function(view) {  // for all dependent (subtrack) multi-selects
                     sel = this;
                     if(view != "") {
                         var hasClass = $(this).parents(".blueBox." + view);
                         if(hasClass.length != 0)
                             return;
                     }
                     $(this).children('option').each(function() {  // for all options of dependent mult-selects
                         $(this).attr('selected',$(inp).children('option:eq('+this.index+')').attr('selected')); // set selected state to independent (parent) selected state
                     });
                     $(this).attr('size',$(inp).attr('size'));
                 });
             }
         }
     }
     else if(inp.type.indexOf("checkbox") == 0) {
         var list = $("checkbox[name$='"+suffix+"']").not("[name='"+inp.name+"']"); // Exclude self from list
         if(view != "") { list =  $(list).filter(function(index) { return normed($(this).parents(".blueBox." + view)) != undefined; });}
         if($(list).length>0)
             $(list).attr("checked",$(inp).attr("checked"));
     }
     else if(inp.type.indexOf("radio") == 0) {
         var list = $("input:radio[name$='"+suffix+"']").not("[name='"+inp.name+"']");
         list = $(list).filter("[value='"+inp.value+"']")
         if(view != "") { list =  $(list).filter(function(index) { return normed($(this).parents(".blueBox." + view)) != undefined; });}
         if($(list).length>0)
             $(list).attr("checked",true);
     }
     else {  // Various types of inputs
         var list = $("input[name$='"+suffix+"']").not("[name='"+inp.name+"']");//.not("[name^='boolshad.']"); // Exclude self from list
         if(view != "") { list =  $(list).filter(function(index) { return normed($(this).parents(".blueBox." + view)) != undefined; });}
         if($(list).length>0)
             $(list).val(inp.value);
         //else {
         //    alert("Unsupported type of multi-level cfg setting type='"+inp.type+"'");
         //    return false;
         //}
     }
     return true;
 }
 
 function compositeCfgRegisterOnchangeAction(prefix)
 {
 // After composite level cfg settings written to HTML it is necessary to go back and
 // make sure that each time they change, any matching subtrack level cfg setting are changed.
     var list = $("input[name^='"+prefix+".']").not("[name$='.vis']");
     $(list).change(function(){compositeCfgUpdateSubtrackCfgs(this);});
 
     var list = $("select[name^='"+prefix+".']").not("[name$='.vis']");
     $(list).change(function(){compositeCfgUpdateSubtrackCfgs(this);});
 }
 
 function visTriggersHiddenSelect(obj)
 { // SuperTrack child changing vis should trigger superTrack reshaping.
   // This is done by setting hidden input "_sel"
     var trackName_Sel = $(obj).attr('name') + "_sel";
     var theForm = $(obj).closest("form");
     var visible = (obj.selectedIndex != 0);
     if (visible) {
         updateOrMakeNamedVariable(theForm,trackName_Sel,"1");
     } else
         disableNamedVariable(theForm,trackName_Sel);
     return true;
 }
 
 function subtrackCfgHideAll(table)
 {
 // hide all the subtrack configuration stuff
     $("div[id $= '_cfg']").each( function (i) {
         $( this ).css('display','none');
         $( this ).children("input[name$='.childShowCfg']").val("off");
     });
     // Hide all "..." metadata displayed
     $("div[id $= '_meta']:visible").toggle();
     $("img[src$='../images/upBlue.png']").attr('src','../images/downBlue.png');
 }
 
 function subtrackCfgShow(tableName)
 {
 // Will show subtrack specific configuration controls
 // Config controls not matching name will be hidden
     var divit = $("#div_"+tableName+"_cfg");
     if(($(divit).css('display') == 'none')
     && metadataIsVisible(tableName))
         metadataShowHide(tableName,"","");
 
     // Could have all inputs commented out, then uncommented when clicked:
     // But would need to:
     // 1) be able to find composite view level input
     // 2) know if subtrack input is non-default (if so then subtrack value overrides composite view level value)
     // 3) know whether so composite view level value has changed since hgTrackUi displayed (if so composite view level value overrides)
     $(divit).toggle();
     return false;
 }
 
 function enableViewCfgLink(enable,view)
 {
 // Enables or disables a single configuration link.
     var link = $('#a_cfg_'+view);
     if(enable)
         $(link).attr('href','#'+$(link).attr('id'));
     else
         $(link).removeAttr('href');
 }
 
 function enableAllViewCfgLinks()
 {
     $( ".viewDD").each( function (i) {
         var view = this.name.substring(this.name.indexOf(".") + 1,lastIndexOf(".vis"));
         enableViewCfgLink((this.selectedIndex > 0),view);
     });
 }
 
 function hideConfigControls(view)
 {
 // Will hide the configuration controls associated with one name
     $("input[name$='"+view+".showCfg']").val("off");      // Set cart variable
     $("tr[id^='tr_cfg_"+view+"']").css('display','none'); // Hide controls
 }
 
 function showConfigControls(name)
 {
 // Will show configuration controls for name= {tableName}.{view}
 // Config controls not matching name will be hidden
     var trs  = $("tr[id^='tr_cfg_']")
     $("input[name$='.showCfg']").val("off"); // Turn all off
     $( trs ).each( function (i) {
         if( this.id == 'tr_cfg_'+name && this.style.display == 'none') {
             $( this ).css('display','');
 	    $("input[name$='."+name+".showCfg']").val("on");
         }
         else if( this.style.display == '') {
             $( this ).css('display','none');
         }
     });
 
     // Close the cfg controls in the subtracks
     $("table.subtracks").each( function (i) { subtrackCfgHideAll(this);} );
     return true;
 }
 
 function showOrHideSelectedSubtracks(inp)
 {
 // Show or Hide subtracks based upon radio toggle
     var showHide;
     if(arguments.length > 0)
         showHide=inp;
     else {
         var onlySelected = $("input.allOrOnly'");
         if(onlySelected.length > 0)
             showHide = onlySelected[0].checked;
         else
             return;
     }
     showSubTrackCheckBoxes(showHide);
 
     var tbody = $("tbody.sortable")
     $(tbody).each(function (i) {
         sortedTableAlternateColors(this);
     });
 }
 
 ///// Following functions called on page load
 function matInitializeMatrix()
 {
 // Called at Onload to coordinate all subtracks with the matrix of check boxes
 //var start = startTiming();
 jQuery('body').css('cursor', 'wait');
     if (document.getElementsByTagName) {
         matSubCBsSelected();
         showOrHideSelectedSubtracks();
     }
 jQuery('body').css('cursor', '');
 //showTiming(start,"matInitializeMatrix()");
 }
 
 function multiSelectLoad(div,sizeWhenOpen)
 {
     //var div = $(obj);//.parent("div.multiSelectContainer");
     var sel = $(div).children("select:first");
     if(div != undefined && sel != undefined && sizeWhenOpen <= $(sel).length) {
         $(div).css('width', ( $(sel).clientWidth ) +"px");
         $(div).css('overflow',"hidden");
         $(div).css('borderRight',"2px inset");
     }
     $(sel).show();
 }
 
 function multiSelectCollapseToSelectedOnly(obj)
 {
     var items = $(obj).children("option");
     if(items.length > 0) {
         $(items).not(":selected").hide();
     }
     $(obj).attr("size",$(items).filter(":selected").length);
 }
 
 function multiSelectBlur(obj)
 { // Closes a multiselect and colapse it to a single option when appropriate
     if($(obj).val() == undefined || $(obj).val() == "") {
         $(obj).val("All");
         $(obj).attr('selectedIndex',0);
     }
     //if(obj.value == "All") // Close if selected index is 1
     if($(obj).attr('selectedIndex') == 0) // Close if selected index is 1
         $(obj).attr('size',1);
     else
         multiSelectCollapseToSelectedOnly(obj);
 
     /*else if($.browser.msie == false && $(obj).children('option[selected]').length==1) {
         var ix;
         for(ix=0;ix<obj.options.length;ix++) {
             if(obj.options[ix].value == obj.value) {
                 //obj.options[ix].selected = true;
                 obj.selectedIndex = ix;
                 obj.size=1;
                 $(obj).trigger('change');
                 break;
             }
         }
     }*/
 }
 
 function filterCompositeSet(obj,all)
 { // Will set all filter composites via [+] or [-] buttons
 
     matSubCBsCheck(all);
     var vars = [];
     var vals = [];
     var filterComp = $("select.filterComp");
     if(all) {
         $(filterComp).each(function(i) {
             $(this).trigger("checkAll");
             $(this).val("All");
             //vars.push($(this).attr('name'));  // Don't bother ajaxing this over
             //vals.push($(this).val());
         });
     } else {
         $(filterComp).each(function(i) {
             $(this).trigger("uncheckAll");
             $(this).val("");
             vars.push($(this).attr('name'));
             vals.push("[empty]");
         });
     }
     if(vars.length > 0) {
         setCartVars(vars,vals);// FIXME: setCartVar conflicts with "submit" button paradigm
     }
     matSubCBsSelected(); // Be sure to update the counts!
 }
 
 function matCbFilterClasses(matCb,joinThem)
 { // returns the var associated with a filterComp
 
     var classes = $( matCb ).attr("class").split(" ");
-    classes = aryRemove(classes,"matCB","halfVis","abc");
+    classes = aryRemove(classes,["matCB","disabled","abc"]);
     if (joinThem)
         return '.' + classes.join('.');
     return classes;
 }
 
 function filterCompFilterVar(filter)
 { // returns the var associated with a filterComp
 
     if($(filter).hasClass('filterComp') == false)
         return undefined;
 
     // Find the var for this filter
     var parts = $(filter).attr("name").split('.');
     return parts[parts.length - 1];
 }
 
 function filterCompApplyOneFilter(filter,subCbsRemaining)
 { // Applies a single filter to a filterTables TRs
     var classes = $(filter).val();
     if (classes == null || classes.length == 0)
         return []; // Nothing selected so exclude all rows
 
     if(classes[0] == 'All')
         return subCbsRemaining;  // nothing excluded by this filter
 
     var subCbsAccumulating = [];
     for(var ix =0;ix<classes.length;ix++) {
         var subCBOneFIlter = $(subCbsRemaining).filter('.' + classes[ix]);
         if (subCBOneFIlter.length > 0)
             subCbsAccumulating = jQuery.merge( subCbsAccumulating, subCBOneFIlter );
     }
     //warnSince('filterCompApplyOneFilter('+filterCompFilterVar(filter)+','+subCbsRemaining.length+')');
     return subCbsAccumulating;
 }
 
 function filterCompApplyOneMatCB(matCB,remainingCBs)
 { // Applies a single filter to a filterTables TRs
     var classes = matCbFilterClasses(matCB,true);
     if (classes == null || classes.length == 0)
         return []; // Nothing selected so exclude all rows
 
     //warnSince('filterCompApplyOneMatCB('+classes+','+remainingCBs.length+');
     return $(remainingCBs).filter(classes);
 }
 
 function filterCompSubCBsSurviving(filterClass)
 // returns a list of trs that satisfy all filters
 // If defined, will exclude filter identified by filterClass
 {
     // find all filterable table rows
     var subCbsFiltered = $("input.subCB");// Default all
     if (subCbsFiltered.length == 0)
         return [];
 
     //warnSince('filterCompSubCBsSurviving() start: '+ subCbsFiltered.length);
 
     // Find all filters
     var filters = $("select.filterComp");
     if (filters.length == 0)
         return [];
 
     // Exclude one if requested.
     if (filterClass != undefined && filterClass.length > 0)
         filters = $(filters).not("[name$='" + filterClass + "']");
 
     for(var ix =0;subCbsFiltered.length > 0 && ix < filters.length;ix++) {
         subCbsFiltered = filterCompApplyOneFilter(filters[ix],subCbsFiltered);  // successively reduces
     }
 
     // Filter for Matrix CBs too
     if (subCbsFiltered.length > 0) {
         var matCbAll = $("input.matCB");
         var matCb = $(matCbAll).filter(":checked");
         if (matCbAll.length > matCb.length) {
             if (matCb.length == 0)
                 subCbsFiltered = [];
             else {
                 var subCbsAccumulating = [];
                 for(var ix =0;ix<matCb.length;ix++) {
                     var subCBOneFIlter = filterCompApplyOneMatCB(matCb[ix],subCbsFiltered);
                     if (subCBOneFIlter.length > 0)
                         filteredCBs = jQuery.merge( subCbsAccumulating, subCBOneFIlter );
                 }
                 subCbsFiltered = subCbsAccumulating;
             }
         }
     }
     //warnSince('filterCompSubCBsSurviving() matrix: '+subCbsFiltered.length);
     return subCbsFiltered;
 }
 
 function _filterComposite()
 { // Called when filterComp selection changes.  Will check/uncheck subtracks
     var subCbsSelected = filterCompSubCBsSurviving();
 
     // Uncheck:
     var subCbsToUnselect = $("input.subCB:checked");// Default all
     if (subCbsToUnselect.length > 0)
         $(subCbsToUnselect).each( function (i) { matSubCBcheckOne(this,false); });
     //warnSince('done with uncheck');
 
     // check:
     if (subCbsSelected.length > 0)
         $(subCbsSelected).each( function (i) { matSubCBcheckOne(this,true); });
     //warnSince('done with check');
 
     // Update count
     matSubCBsSelected();
     //warnSince('done');
 
     var tbody = $( subCbsSelected[0] ).parents('tbody.sorting');
     if (tbody != undefined)
          $(tbody).removeClass('sorting');
 }
 
 function filterCompositeTrigger()
 { // Called when filterComp selection changes.  Will check/uncheck subtracks
     var tbody = $( 'tbody.sortable');
     if (tbody != undefined)
          $(tbody).addClass('sorting');
 
     waitOnFunction(_filterComposite);
 }
 
 function filterCompositeDone(event)
 { // Called by custom 'done' event
     event.stopImmediatePropagation();
     $(this).unbind( event );
     filterCompositeTrigger();
     //waitOnFunction(filterCompositeTrigger,$(this));
 }
 
 function filterCompositeSelectionChanged(obj)
 { // filterComposite:onchange Set subtrack selection based upon the changed filter  [Not called for filterBy]
 
     var subCBs = $("input.subCB");
     if ( subCBs.length > 300) {
         //if ($.browser.msie) { // IE takes tooo long, so this should be called only when leaving the filterBy box
             $(obj).one('done',filterCompositeDone);
             return;
         //}
     } else
         filterCompositeTrigger();
 }
 
 function filterCompositeExcludeOptions(multiSelect)
 { // Will mark all options in one filterComposite boxes that are inconsistent with the current
   // selections in other filterComposite boxes.  Mark is class ".excluded"
     // Compare to the list of all trs
     var allSubCBs = $("input.subCB");
     if (allSubCBs.length == 0)
         return false;
 
     if ($.browser.msie && $(allSubCBs).filter(":checked").length > 300) // IE takes tooo long, so this should be called only when leaving the filterBy box
         return false;
 
     var filterClass = filterCompFilterVar(multiSelect);
     if (filterClass == undefined)
         return false;
 
     // Look at list of CBs that would be selected if all were selected for this filter
     var subCbsSelected = filterCompSubCBsSurviving(filterClass);
     if (subCbsSelected.length == 0)
         return false;
 
     if (allSubCBs.length == subCbsSelected.length) {
         $(multiSelect).children('option.excluded').removeClass('excluded');   // remove .excluded" from all
         return true;
     }
 
     //warnSince('filterCompositeExcludeOptions('+filterClass+'): subCbsSelected: '+subCbsSelected.length);
     // Walk through all selected subCBs to get other related tags
     var possibleSelections = [];  // empty array
     $( subCbsSelected ).each( function (i)  {
 
         var possibleClasses = $( this ).attr("class").split(" ");
         if( $(possibleClasses).length > 0)
-            possibleClasses = aryRemoveVals(possibleClasses,[ "subCB","changed" ]);
+            possibleClasses = aryRemove(possibleClasses,[ "subCB","changed","disabled" ]);
         if( $(possibleClasses).length > 0)
             possibleSelections = possibleSelections.concat(possibleClasses);
     });
     //warnSince('filterCompositeExcludeOptions('+filterClass+'): possibleSelections: '+possibleSelections.length);
 
     // Walk through all options in this filterBox to set excluded class
     var updated = false;
     if(possibleSelections.length > 0) {
         var opts = $(multiSelect).children("option");
         for(var ix = 1;ix < $(opts).length;ix++) { // All is always allowed
             if(aryFind(possibleSelections,opts[ix].value) == -1) {
                 if($(opts[ix]).hasClass('excluded') == false) {
                     $(opts[ix]).addClass('excluded');
                     updated = true;
                 }
             } else if($(opts[ix]).hasClass('excluded')) {
                 $(opts[ix]).removeClass('excluded');
                 updated = true;
             }
         }
     }
     return updated;
 }
 
 function filterCompositeClasses(wantSelected)
 {// returns an array of classes from the dim ABC filterComp classes: converts "matCB abc rep1"[]s to "rep1","rep2"
     var classes = new Array;
     var abcFBs = $("select.filterComp");
     if(abcFBs.length > 0) {
         $(abcFBs).each( function(i) {
             // Need to walk through list of options
             var ix=0;
             var allAreSelected = false;
             if (this.options[ix].value == "All") {
                 allAreSelected = this.options[ix].selected;
                 ix++;
             }
             for(;ix<this.length;ix++) {
                 if (allAreSelected || this.options[ix].selected) {
                     if (wantSelected)
                         classes.push(this.options[ix].value);
                 } else {
                     if (!wantSelected)
                         classes.push(this.options[ix].value);
                 }
             }
         });
     }
     return classes;
 }
 
 function multiSelectFocus(obj,sizeWhenOpen)
 { // Opens multiselect whenever it gets focus
     if($(obj).attr('size') != sizeWhenOpen) {
     $(obj).children("option").show();
     $(obj).attr('size',sizeWhenOpen);
     //warn("Selected:"+$(obj).children("option").filter(":selected").length);
     }
     //return false;
 }
 
 function multiSelectClick(obj,sizeWhenOpen)
 { // Opens multiselect whenever it is clicked
     if($(obj).attr('size') != sizeWhenOpen) {
         multiSelectFocus(obj,sizeWhenOpen);
         //$(obj).children("option").show();
         //$(obj).attr('size',sizeWhenOpen);
         return false;
     } else if($(obj).attr('selectedIndex') == 0)
         $(obj).attr('size',1);
 return true;
 }
 
 function navigationLinksSetup()
 { // Navigation links let you jump to places in the document
   // If they exist, then they need to be well placed to fit window dimensions
 
     // Put navigation links in top corner
     var navDown = $("#navDown");
     if(navDown != undefined && navDown.length > 0) {
         navDown = navDown[0];
         var winWidth = ($(window).width() - 20) + "px"; // Room for borders
         $('.windowSize').css({maxWidth:winWidth,width:winWidth});
         var sectTtl = $("#sectTtl");
         if(sectTtl != undefined && sectTtl.length > 0) {
             $(sectTtl).css({clear: 'none'});
             $(sectTtl).prepend($(navDown));
         }
         $(navDown).css({'float':'right', 'font-weight':'normal','font-size':'medium'});
         $(navDown).show();
     }
 
     // Decide if top links are needed
     var navUp = $('span.navUp');
     if(navUp != undefined && navUp.length > 0) {
         $(navUp).each(function(i) {
             var offset = $(this).parent().offset();
             if(offset.top  > ($(window).height()*(2/3))) {
                 $(this).show();
             }
         });
     }
 }
 
 function tableSortAtButtonPress(anchor,tagId)
 { // Special ONLY for hgTrackUi sorting.  Others use utils.js::tableSortOnButtonPress()
     var table = $( anchor ).parents("table.sortable");
     if (table) {
         subtrackCfgHideAll(table);
         waitOnFunction( _tableSortOnButtonPressEncapsulated, anchor, tagId);
     }
     return false;  // called by link so return false means don't try to go anywhere
 }
 
-var scm = { // subtrack config module.
-    // This module is for subtrack level config embedded dialogs in hgTrackUi.
-    // Subtrack config dialogs are embedded in the subtrack table and get populated when first
-    // opened.  Composite and view level controls (parents) when updated override related
-    // subtrack controls (children).  Subtrack controls, when updated overide parent controls
-    // for the one subtrack.  Controls have no 'name' attribute until the user alters their value.
-    // Unnamed controls are not sent to the cart!!!
-
-    // Definitions as used here:
-    // obj: an input or select style html control which may be named or unnamed
-    //   parentObj: composite or view level obj which has subtrack level childObjs associated
-    //   childObj: subtrack level obj that has composite and or view level parentObjs
-    // cfg: subtrack level embedded dialog which can be opened or closed (hidden) and isn't
-    //      populated till first opened.  Can also be a viewCfg and maybe a compositeCfg
-    // populate: act of filling a subtrack cfg with controls
-    // named: control with a name attribute which means it has been updated by the user.
-    //        Unfortunately radio buttons are an exception, since they must keep their names.
-    // unnamed: control that has not been updated by the user.  Will not be sent to cart.
-
-    // TODO:
-    //  1) SOLVED: Radio buttons work BUT they require name to keep unified set, so rely upon 'changed' class to detect changes.
-    //  2) SOLVED: checkboxes: working with name = boolshad.{name}   FIXME: multishad?
-    //  3) SOLVED: filterBy,filterComp working: they rely upon id, and id with '.' screwed it all up.  So replaced '.' with '_-'
-    //  4) SOLVED: subCfg not matching parent: solved.
-    //  5) SOLVED: OpenChromSynth: subtrack filterby needs to be updated by composite filterBy.
-    //  6) SOLVED: check subtrack to enable/disable fauxVis and wrench
-    //  7) SOLVED: matCB should effect subCb including enable/disable fauxVis and wrench
-    //  8) SOLVED: composite/view vis should effect subVis and enable/disable fauxVis and wrench
-    //  9) SOLVED: inside out: changing subtrack vis should affect subCB and matCB
-    // 10) SOLVED: Loosing checked tracks!!!  Setting vis clears checkboxes?
-    // 11) When parent vis makes subs hidden, shouuld they go to unchecked?
-    // 12) Should user be able to click on disabled vis to check the CB?
-    // 13) Make vis changes "reshape" composite!  NOTE: Do we want to do this???
-    // 14) Non-configurable will need to show/change vis independently! (separate vis control but no wrench)
-    // - Verify all composites work (conservation and SNPs are likely failures)
-    // - Decide on a name (scm, subCfg, ? ) and then make a module file like ddcl.js.
-    // - Remove debug code when ready
-    // NOTE:
-    // Current implementation relies upon '.' delimiter in name and no '_-' in name.  Nothing breaks rule yet...
-
-    //mySelf: null, // There is no need for a "mySelf" unless this object is being instantiated.
-
-    // There is one instance and these vars are page wide
-    compositeId: undefined,
-    visIndependent: false,
-    viewIds: [],
-
-    markChange: function (obj)
-    { // Marks a control as having been changed by the user.  Naming will send value to cart.
-        $(obj).addClass('changed');
-
-        if(obj.type.indexOf("radio") == 0)   // radios must keep their names!
-            return;
-
-        var oldName = obj.id.replace(/\_\-/g,'.');   // sanitized id replaces '.' with '_-'
-        $(obj).attr('name',oldName);
-
-        // checkboxes have hidden boolshads which should be marked when unchecked
-        if(obj.type.indexOf("checkbox") == 0) {
-            var boolshad = normed($('input#boolshad_-' + obj.id));
-            if (boolshad != undefined) {
-                if(obj.checked == false) {
-                    var oldName = boolshad.id.replace(/\_\-/g,'.');   // sanitized id replaces '.' with '_-'
-                    $(obj).addClass('changed');
-                    $(boolshad).attr('name',oldName);
-                }
-                else
-                    scm.clearChange(boolshad);
-            }
-        }
-    },
-
-    clearChange: function (obj)
-    { // Mark as unchanged
-        $(obj).removeClass('changed');
-
-        if(obj.type.indexOf("radio") == 0)    // radios must keep their names!
-            return;
-
-        $(obj).removeAttr('name');
-
-        // checkboxes have hidden boolshads which should be cleared in tandem
-        if(obj.type.indexOf("checkbox") == 0) {
-            var boolshad = normed($('input#boolshad_-' + obj.id));
-            if (boolshad != undefined) {
-                $(boolshad).removeClass('changed');
-                $(boolshad).removeAttr('name');
-            }
-        }
-    },
-
-    hasChanged: function (obj)
-    { // Is this object updated (value changed by a user)?
-        return $(obj).hasClass('changed');
-    },
-
-    unnameIt: function (obj,setId)
-    { // removes a control's name so that it will not be updated to the cart upon submit
-      // If setId and obj has a name, will set id to current name
-        var myName = $(obj).attr('name');
-        if (myName && myName.length > 0) {
-
-            // checkboxes have hidden boolshads which should be unamed in tandem
-            if(obj.type.indexOf("checkbox") == 0) {
-                var boolshad = normed( $("input[name='boolshad\\."+myName+"']") );  // Not yet sanitized name
-                if (boolshad != undefined) {
-                    scm.unnameIt(boolshad,setId);  // self referencing but boolshad not(':checkbox')
-                }
-            }
-
-            if (setId) {
-                // DEBUG -------------
-                if (myName.indexOf('_-') >= 0)
-                    warn("DEBUG: Found control with '_-' in name: "+myName + "<BR>This violates the naming rules and will break javascript code.");
-                // DEBUG -------------
-                var newId = myName.replace(/\./g,'_-');   // sanitized id replaces '.' with '_-'
-
-                // DEBUG -------------
-                if (obj.id && obj.id.length > 0 && obj.id != myName)
-                    warn("DEBUG: Obj is being re-ID'd but it already has an ID.  Old:'"+obj.id+"'  New:'"+newId+"'");
-                // DEBUG -------------
-                $(obj).attr('id',newId);
-            }
-        }
-
-        scm.clearChange(obj);  // actually removes the name!
-    },
-
-    compositeCfgFind: function ()
-    { // returns the cfg container for the composite controls
-        // TODO: write, create a composite cfg div!
-    },
-
-    compositeObjFind: function (suffix)
-    { // returns the composite level control for this suffix
-        //var compCfg = scm.compositeCfgFind();  // TODO: when there is a composite cfg div!
-        var compObj;
-        if (suffix != undefined) {
-            //compObj = $('#'+ scm.compositeId + '\\.' + suffix);
-            compObj = normed($('#'+ scm.compositeId + '_-' + suffix));
-            if (compObj == undefined) {
-                compObj = normed($('#'+ scm.compositeId + '_' + suffix));
-            }
-        } else {
-            compObj = normed($("#"+scm.compositeId));
-        }
-        return compObj;
-    },
-
-    viewIdFind: function (childObj)
-    { // returns the name of the view that is a parent of this subtrack control
-        var cfg = normed($(childObj).parents('div.subCfg'));
-        if (cfg == undefined) {
-            // could be vis outside of cfg div
-            var subCb = normed($(childObj).closest('tr').find('input.subCB'));
-            if (subCb != undefined) {
-                var classList = $(subCb).attr("class").split(" ");
-                classList = aryRemove(classList,"changed");
-                return classList[classList.length - 1];
-            }
-            warn("Can't find containing div.subCfg of child '"+$(childObj).attr('id')+"'.");
-            return undefined;
-        }
-        var classList = $( cfg ).attr("class").split(" ");
-        classList = aryRemove(classList,"subCfg","filled");
-        if (classList.length == 0) {
-            warn("Subtrack cfg div does not have view class for child '"+$(childObj).attr('id')+"'.");
-            return undefined;
-        } else if (classList.length > 1) {
-            warn("Subtrack cfg div for '"+$(childObj).attr('id')+"' has unexpected class: "+classList);
-            return undefined;
-        }
-        if (classList[0] == 'noView') // valid case
-            return undefined;
-        return classList[0];
-    },
-
-    viewCfgFind: function (viewId)
-    { // returns the cfg container for a given view
-        var viewCfg = normed($('tr#tr_cfg_'+viewId));
-        if (viewCfg == undefined) {
-            warn('Could not find viewCfg for '+viewId);
-        }
-        return viewCfg;
-    },
-
-    viewObjFind: function (viewId,suffix)
-    { // returns the control belonging to this view and suffix
-        var viewObj;
-        if (suffix != undefined) {
-            var viewCfg = scm.viewCfgFind(viewId);
-            viewObj = normed($(viewCfg).find("[id$='_-"+suffix+"']"));
-            if (viewObj == undefined)
-                viewObj = normed($(viewCfg).find("[id$='_"+suffix+"']"));
-        } else
-            viewObj = normed($("#"+scm.compositeId+"_-"+viewId+"_-vis"));
-
-        return viewObj;
-    },
-
-    childObjsFind: function (viewId,suffix)
-    { // returns an array of objs for this view and suffix
-      // Assumes composite wide if viewId is not provided
-      // Assumes vis if suffix is not provided
-
-        if (viewId != undefined) {
-            var childCfgs = $('div.subCfg.filled.'+viewId);
-        } else {
-            var childCfgs = $('div.subCfg.filled');
-        }
-        if (childCfgs == undefined)
-            return [];
-
-        var childObjs = [];
-        if (suffix != undefined)
-            childObjs = $(childCfgs).find('select,input').filter("[id$='_-"+suffix+"']");
-        else
-            childObjs = $(childCfgs).find('select.visDD');
-
-        if (childObjs == undefined)
-            return [];
-
-        return childObjs;
-    },
-
-    objSuffixGet: function (obj)
-    { // returns the identifying suffix of a control.  obj can be parent or child
-        //var nameParts = $(obj).attr('id').split('.');
-        var nameParts = $(obj).attr('id').split('_-');
-        if (nameParts == undefined || nameParts.length == 0) {
-            warn("Can't resolve id for '"+$(obj).attr('id')+"'.");
-            return undefined;
-        }
-        if (nameParts.length < 2)
-            return undefined;
-
-        nameParts.shift();
-        if (scm.viewIds.length > 0 && nameParts.length > 1) // FIXME: I expect more problems with this!
-            nameParts.shift();
-
-        return nameParts.join('_-');
-    },
-
-    childCfgFind: function (childObj)
-    { // returns the cfg wrapper for a child vis object
-        var childCfg = normed($(childObj).parents('div.subCfg.filled'));
-        if (childCfg == undefined)
-            warn("Can't find childCfg for "+childObj.id);
-        return childCfg;
-    },
-
-    subCbFind: function (childObj)
-    { // returns the subCB for a child vis object
-        // Look directly first
-        var subCb = normed($(childObj).closest('tr').find('input.subCB'));
-        if (subCb != undefined)
-            return subCb;
-
-        warn("DEBUG: Failed to find subCb for "+childObj.id);
-        var childCfg = scm.childCfgFind(childObj);
-        if (childCfg == undefined)
-            return undefined;
-
-        var tr = $(childCfg).parents('tr').first();
-        var subtrack = childCfg.id.substring(8); // 'div_cfg_'.length
-        var subCb = normed($(tr).find("input[name='"+subtrack+"_sel']"));
-        if (subCb == undefined)
-            warn("Can't find subCB for subtrack: "+subtrack);
-        return subCb;
-    },
-
-    visChanged: function (childObj)
-    { // called on change for a child vis control
-        var subCb = scm.subCbFind(childObj);
-        if (subCb != undefined) {
-            if (childObj.selectedIndex > 0)
-                subCb.checked = true;
-                matSubCbClick(subCb);
-        }
-        $(childObj).attr('name',childObj.id);
-    },
-
-    parentsFind: function (childObj)
-    { // returns array of composite and/or view level parent controls
-        var myParents = [];
-        var suffix = scm.objSuffixGet(childObj);
-        var notRadio = (childObj.type.indexOf("radio") != 0);
-
-        // find view name
-        var viewId = scm.viewIdFind(childObj);
-        if (viewId != undefined) {
-            var viewObj = scm.viewObjFind(viewId,suffix);
-            if (viewObj != undefined) {
-                if (notRadio)
-                    myParents[0] = viewObj;
-                else {
-                    $(viewObj).each(function (i) { // radios will have more than one
-                        if(childObj.value == this.value) {
-                            myParents[0] = this;
-                            return false; // breaks each, but not parentsFind
-                        }
-                    });
-                }
-            }
-        }
-
-        var compObj = scm.compositeObjFind(suffix);
-        if (compObj != undefined) {
-            if (notRadio)
-                myParents[myParents.length] = compObj;
-            else {
-                $(compObj).each(function (i) { // radios will have more than one
-                    if(childObj.value == this.value) {
-                        myParents[myParents.length] = this;
-                        return false;
-                    }
-                });
-            }
-        }
-        return myParents;
-    },
-
-    childrenFind: function (parentObj)
-    { // returns array of all currently populated child controls related to this parent control
-      // parentObj could be composite level or view level
-      // parent object could be for vis which has special rules
-
-        var isComposite = false;
-        var isVis = false;
-        var suffix = scm.objSuffixGet(parentObj);
-        isVis = (suffix != undefined && suffix == 'vis');  // vis inside of subCfg
-
-        var viewId = undefined;
-        if (isVis) { // This is a view control
-
-            isComposite = (suffix == undefined);
-            suffix = undefined;
-            if (!isComposite) {
-                var classList = $( parentObj ).attr("class").split(" ");
-                classList = aryRemove(classList,"viewDD","normalText","changed");
-                if (classList.length != 1) {
-                    warn("Unexpected view vis class list:"+classList);
-                    return [];
-                }
-                viewId = classList[0];
-            }
-        } else { // normal obj
-
-            var viewCfg = normed($(parentObj).parents("tr[id^='tr_cfg_']"));
-            isComposite = (viewCfg == undefined); // is composite
-            if (!isComposite) {
-                viewId = viewCfg.id.substring(7); // 'tr_cfg_'.length
-            }
-        }
-
-        if (isComposite) {
-
-            // There may be views
-            if (scm.viewIds.length > 0) {
-                var allChildren = [];
-                for (var ix = 0;ix < scm.viewIds.length;ix++) {
-                    viewId = scm.viewIds[ix];
-                    // Get any view objs first
-                    var viewObj = scm.viewObjFind(viewId,suffix);
-                    if (viewObj != undefined)
-                        allChildren[allChildren.length] = viewObj;
-                    // Now get children
-                    var viewChildren = scm.childObjsFind(viewId,suffix);
-                    if (viewChildren.length > 0) {
-                        if (allChildren.length == 0)
-                            allChildren = viewChildren;
-                        else
-                            allChildren = jQuery.merge( allChildren, viewChildren );
-                    }
-                }
-                return allChildren;
-            } else { // if no views then just get them all
-                return scm.childObjsFind(undefined,suffix);
-            }
-
-        } else {
-            return scm.childObjsFind(viewId,suffix);
-        }
-    },
-
-    visChildrenFind: function (parentObj)
-    { // returns array of all currently faux and populated vis child controls (which are not in subCfg div)
-      // parentObj could be composite level or view level
-
-        var isVis = false;
-        var suffix = scm.objSuffixGet(parentObj);
-        isVis = (suffix == undefined || suffix == 'vis');
-        var isComposite = (suffix == undefined);
-
-        var subVis = $('.subVisDD');  // select:vis or faux:div
-        if (isComposite) {
-
-            return subVis;
-
-        } else {
-            var classList = $( parentObj ).attr("class").split(" ");
-            classList = aryRemove(classList,"viewDD","normalText","changed");
-            if (classList.length != 1) {
-                warn("Unexpected view vis class list:"+classList);
-                return [];
-            }
-            return $(subVis).filter('.' + classList[0]);
-        }
-    },
-
-    checkOneSubtrack: function (subCb,check,enable)
-    { // Handle a single check of a single subCb
-        subCb.checked = check;
-        subCb.dsabled = enable;
-        scm.markChange(subCb);
-        matSubCBsetShadow(subCb);
-        hideOrShowSubtrack(subCb);
-        scm.enableCfg(subCb,undefined,check);
-    },
-
-    propagateSetting: function (parentObj)
-    { // propagate composite/view level setting to subtrack children
-        var children = scm.childrenFind(parentObj);
-        if(parentObj.type.indexOf("checkbox") == 0) {
-            var parentChecked = parentObj.checked;
-            $(children).each(function (i) {
-                // Note checkbox and boolshad are children.
-                if (this.type != 'hidden')
-                    this.checked = parentObj.checked;
-                scm.clearChange(this);
-            });
-        } else if(parentObj.type.indexOf("radio") == 0) {
-            var parentVal = $(parentObj).val();
-            $(children).each(function (i) {
-                this.checked = ($(this).val() == parentVal);
-                scm.clearChange(this);
-            });
-        } else {// selects and inputs are easy
-            var parentVal = $(parentObj).val();
-            var updateDdcl = ($(parentObj).hasClass('filterBy') || $(parentObj).hasClass('filterComp'));
-            $(children).each(function (i) {
-                $(this).val(parentVal);
-                scm.clearChange(this);
-                if (updateDdcl)
-                    ddcl.onComplete(this);
-            });
-        }
-        scm.markChange(parentObj);
-    },
-
-    propagateViewVis: function (viewObj,compositeVis)
-    { // propagate vis from a view limiting with compositeVis
-        var limitedVis = Math.min(compositeVis,viewObj.selectedIndex);
-        var visText = 'hide';
-        if (limitedVis == 1)
-            visText = 'dense';
-        else if (limitedVis == 2)
-            visText = 'squish';
-        else if (limitedVis == 3)
-            visText = 'pack';
-        else if (limitedVis == 4)
-            visText = 'full';
-
-        var children = scm.visChildrenFind(viewObj);
-        $(children).each(function (i) {
-            if ($(this).hasClass('fauxInput')) {
-                $(this).text(visText);
+function fauxDisable(obj,disable,title)
+{
+// Makes an obj appear diabled, but it isn't
+//       span.disabled & input.disabled is opacity 0.5
+//       div.disabled is border-color: gray; color: gray;
+    if ($(obj).hasClass('subCB') == false || typeof(scm) !== "undefined") {
+        if(disable) {
+            if ($.browser.msie)
+                $(obj).css('opacity', '0.5');
+            $(obj).addClass('disabled');
             } else {
-                $(this).attr('selectedIndex',limitedVis);
-                scm.clearChange(this);
+            if ($.browser.msie)
+                $(obj).css('opacity', '1');  // For some reason IE<9 accepts direct change but isn't happy with simply adding class!
+            $(obj).removeClass('disabled');
             }
-        });
-    },
-
-    propagateVis: function (parentObj,viewId)
-    { // propagate vis settings to subtrack children
-        if (viewId == undefined) {
-            // Walk through views and set with this
-            var parentVis = parentObj.selectedIndex;
-            if (scm.viewIds.length > 0) {
-                for (var ix=0;ix<scm.viewIds.length;ix++) {
-                    var viewObj = scm.viewObjFind(scm.viewIds[ix]);//,undefined);
-                    if (viewObj != undefined)
-                        scm.propagateViewVis(viewObj,parentVis);
-                }
-            } else { // No view so, simple
-
-                var visText = 'hide';
-                if (parentVis == 1)
-                    visText = 'dense';
-                else if (parentVis == 2)
-                    visText = 'squish';
-                else if (parentVis == 3)
-                    visText = 'pack';
-                else if (parentVis == 4)
-                    visText = 'full';
-                var children = scm.visChildrenFind(parentObj);
-                $(children).each(function (i) {
-                    if ($(this).hasClass('fauxInput')) {
-                        $(this).text(visText);
                     } else {
-                        $(this).attr('selectedIndex',parentVis);
-                        scm.clearChange(this);
+        obj.disabled = disable;
                     }
-                });
-            }
-        } else {
-            // First get composite vis to limit with
-            var compObj = scm.compositeObjFind(undefined);
-            if (compObj == undefined) {
-                warn('Could not find composite vis object!');
-                return false;
+    if (arguments.length > 2)
+        $(obj).attr("title",title);
             }
-            scm.propagateViewVis(parentObj,compObj.selectedIndex);
-        }
-    },
 
-    inheritSetting: function (childObj,force)
-    { // update value if parents values override child values.
-        var myParents = scm.parentsFind(childObj);
-        if (myParents == undefined || myParents.length < 1) {
-            // DEBUG -------------  It is probably okay to subCfg without parent cfg, but we need to be sure
-            warn('DEBUG No parents were found for childObj: '+childObj.id);
-            // DEBUG -------------
+function isFauxDisabled(obj,orReallyDisabled)
+{
+// Is object [faux] disabled?
+    if (orReallyDisabled && obj.disabled)
             return true;
-        }
-        var isVis = (undefined == scm.objSuffixGet(childObj));
-        if (isVis) {
-            var subCb = scm.subCbFind(childObj);
-            if (subCb != undefined) {
-                var limitedVis = 9;
-                if (myParents.length == 1 && (force || scm.hasChanged(myParents[0])))
-                    limitedVis = myParents[0].selectedIndex;
-                else if (myParents.length == 2) {
-                    if (force || scm.hasChanged(myParents[0]) || scm.hasChanged(myParents[1]))
-                        limitedVis = Math.min(myParents[0].selectedIndex,myParents[1].selectedIndex);
-                }
-                if (limitedVis < 9)
-                    $(childObj).attr('selectedIndex',limitedVis);
-           }
-        } else {
-            var count = 0;
-            if(childObj.type.indexOf("checkbox") == 0) {
-                $(myParents).each(function (i) {
-                    if (force || scm.hasChanged(this)) {
-                        childObj.checked = this.checked;
-                        // can ignore boolshad because this does not change
-                        count++;
-                    }
-                });
-            } else if(childObj.type.indexOf("radio") == 0) {
-                $(myParents).each(function (i) {
-                    if (force || scm.hasChanged(this)) {
-                        childObj.checked = this.checked;
-                        // parentObj is already "tuned" to the correct radio, so this works
-                        count++;
-                    }
-                });
-            } else {// selects and inputs are easy
-                $(myParents).each(function (i) {
-                    if (force || scm.hasChanged(this)) {
-                        $(childObj).val($(this).val());
-                        count++;
-                    }
-                });
-            }
-            if (count > 1) // if hasChanged() is working, there should never be more than one
-                warn('Both composite and view are seen as updated!  Named update is not working.');
-        }
-    },
-
-    currentCfg: undefined, // keep track of cfg while ajaxing, man
-    currentSub: undefined, // keep track of subtrack while ajaxing, dude
-
-    cfgFill: function (content, status)
-    { // Finishes the population of a subtrack cfg.  Called by ajax return.
-        var cfg = scm.currentCfg;
-        scm.currentCfg = undefined;
-        var cleanHtml = content;
-        var shlurpPattern=/\<script type=\'text\/javascript\' SRC\=\'.*\'\>\<\/script\>/gi;
-        // DEBUG -------------
-            var jsFiles = cleanHtml.match(shlurpPattern);
-            if (jsFiles && jsFiles.length > 0)
-                alert("jsFiles:'"+jsFiles+"'\n---------------\n"+cleanHtml); // warn() interprets html, etc.
-        // DEBUG -------------
-        cleanHtml = cleanHtml.replace(shlurpPattern,"");
-        shlurpPattern=/\<script type=\'text\/javascript\'>.*\<\/script\>/gi;
-        // DEBUG -------------
-            var jsEmbeded = cleanHtml.match(shlurpPattern);
-            if (jsEmbeded && jsEmbeded.length > 0)
-                alert("jsEmbeded:'"+jsEmbeded+"'\n---------------\n"+cleanHtml);
-        // DEBUG -------------
-        cleanHtml = cleanHtml.replace(shlurpPattern,"");
-        shlurpPattern=/\<LINK rel=\'STYLESHEET\' href\=\'.*\' TYPE=\'text\/css\' \/\>/gi;
-        // DEBUG -------------
-            var cssFiles = cleanHtml.match(shlurpPattern);
-            if (cssFiles && cssFiles.length > 0)
-                alert("cssFiles:'"+cssFiles+"'\n---------------\n"+cleanHtml);
-        // DEBUG -------------
-        cleanHtml = cleanHtml.replace(shlurpPattern,"");
-        if (scm.visIndependent) {
-            ix = cleanHtml.indexOf('</SELECT>');
-            if (ix > 0)
-                cleanHtml = cleanHtml.substring(ix+'</SELECT>'.length);
-            while(cleanHtml.length > 0) {
-                ix = cleanHtml.search("<");
-                cleanHtml = cleanHtml.substring(ix);
-                ix = cleanHtml.search(/\<BR\>/i);
-                if (ix != 0)
-                    break; // Not found or not at start.
-                else
-                    cleanHtml = cleanHtml.substring(4); // skip past <BR> and continue
-            }
-        } else {
-            var ix = cleanHtml.indexOf('<B>Display&nbsp;mode:&nbsp;</B>');
-            if (ix > 0)
-                cleanHtml = cleanHtml.substring(ix+'<B>Display&nbsp;mode:&nbsp;</B>'.length);
-        }
-            //cleanHtml = cleanHtml.substring(ix);
-        ix = cleanHtml.indexOf('</FORM>'); // start of form already chipped off
-        if (ix > 0)
-            cleanHtml = cleanHtml.substring(0,ix - 1);
-
-        //cleanHtml = "<div class='blueBox' style='background-color:#FFF9D2; padding:0.2em 1em 1em; float:left;'><CENTER><B>Subtrack Configuration</B></CENTER><BR>" + cleanHtml + "</div>"
-        //cleanHtml = "<div class='blueBox' style='background-color:#FFF9D2; padding:0.2em 1em 1em; float:left;'><B>Subtrack visibility:</B>&nbsp;" + cleanHtml + "</div>"
-        cleanHtml = "<div class='blueBox' style='background-color:#FFF9D2; padding:0.5em 1em 1em;'>" + cleanHtml + "</div>"
-        $(cfg).html(cleanHtml);
-        $(cfg).addClass('filled');
-        var boxWithin = $(cfg).find('.blueBox');
-        if (boxWithin.length > 1)
-            $(boxWithin[1]).removeClass('blueBox');
-
-        //$(cfg).html("<div style='font-size:.9em;'>" + cleanHtml + "</div>");
-        var subObjs = $(cfg).find('input,select').filter("[name]");
-        if (subObjs.length == 0) {
-            warn('Did not find controls for cfg: ' + cfg.id);
-            return;
-        }
-        $(subObjs).each(function (i) {
-            if (this.name != undefined) { // The filter("[name]") above didn't do it!
-                if (this.type != 'hidden') {
-                    scm.unnameIt(this,true);
-                    scm.inheritSetting(this,false); // updates any values that have been changed on this page
-                    // if view vis do more than just name it on change
-                    var suffix = scm.objSuffixGet(this);
-                    if (suffix == undefined) // vis
-                        $(this).bind('change',function (e) {
-                            scm.visChanged(this);
-                        });
-                    else {
-                        $(this).bind('change',function (e) {
-                            scm.markChange(this);
-                        });
-                    }
-                }
-            }
-        });
-        // finally show
-        $(cfg).show();
-        // Tricks to get this in the size and position I want
-        $(cfg).css({ position: 'absolute'});
-        var myWidth = $(cfg).width();
-        var shiftLeft = -1;
-        if (scm.visIndependent) {
-            shiftLeft *= ($(cfg).position().left - 125);
-            var subVis = normed($('div#' + scm.currentSub+'_faux'));
-            if (subVis != undefined)
-                scm.replaceWithVis(subVis,scm.currentSub,false);
-        }
-        else
-            shiftLeft *= ($(cfg).position().left - 40);
-        $(cfg).css({ width: myWidth+'px',position: 'relative', left: shiftLeft + 'px' });
 
-        // Setting up filterBys must follow show because sizing requires visibility
-        $(cfg).find('.filterBy,.filterComp').each( function(i) {
-            if ($(this).hasClass('filterComp'))
-                ddcl.setup(this);
-            else
-                ddcl.setup(this, 'noneIsAll');
-        });
-    },
-
-    cfgPopulate: function (cfg,subtrack)
-    { // Populates a subtrack cfg dialog via ajax and update from composite/view parents
-        scm.currentCfg = cfg;
-        scm.currentSub = subtrack;
-
-        $.ajax({
-            type: "GET",
-            url: "../cgi-bin/hgTrackUi?ajax=1&g=" + subtrack + "&hgsid=" + getHgsid() + "&db=" + getDb(),
-            dataType: "html",
-            trueSuccess: scm.cfgFill,
-            success: catchErrorOrDispatch,
-            error: errorHandler,
-            cmd: "cfg",
-            cache: false
-        });
-    },
-
-    replaceWithVis: function (obj,subtrack,open)
-    { // Replaces the current fauxVis object with a true visibility selector
-
-        if ($(obj).hasClass('disabled'))
-            return;
-        var classList = $( obj ).attr("class").split(" ");
-        var view = classList[classList.length - 1];
-        var classList = $(obj).attr('class').split(' '); // This relies on view being the last class!!!
-        var selectHtml = "<SELECT id='"+subtrack+"' class='normalText subVisDD "+view+"' style='width:70px;'";
-        selectHtml += ">";
-        var selected = $(obj).text();
-        var visibilities = ['hide','dense','squish','pack','full'];
-        $(visibilities).each( function (ix) {
-             selectHtml += "<OPTION" + (visibilities[ix] == selected ? " SELECTED":"") + ">"+visibilities[ix]+"</OPTION>";
-        });
-        selectHtml += "</SELECT>";
-        $(obj).replaceWith(selectHtml);
-        if (open) {
-            var newObj = $('select#'+subtrack);
-            $(newObj).css({'zIndex':'2','vertical-align':'top'});
-            $(newObj).attr('size',5);
-            $(newObj).one('blur',function (e) {
-                $(this).attr('size',1);
-                $(this).unbind('blur');
-            });
-            $(newObj).change(function (e) {
-                if ($(this).attr('size') > 1)
-                    $(this).attr('size',1);
-                if (this.selectedIndex == 0) { // setting to hide so uncheck and disable.
-                    // Easiest is to uncheck subCB and reset vis
-                    //    so that the reverse action makes sense
-                    var subCb = normed($('input#' + this.id + '_sel'));
-                    if (subCb != undefined) {
-                        scm.checkOneSubtrack(subCb,false,true);
-                        matSubCbClick(subCb);
-                        scm.inheritSetting(this,true);
-                        scm.unnameIt(this);
-                    // DEBUG -------------
-                    } else {
-                        warn('DEBUG: Cant find subCB for ' + this.id);
-                    // DEBUG -------------
+    return ($(obj).hasClass('disabled'));
                     }
-                } else
-                    scm.markChange(this);
-            });
-            $(newObj).focus();
-        }
-    },
 
-    enableCfg: function (subCb,subtrack,setTo)
-    { // Enables or disables subVis and wrench
-        if (subCb == undefined) {
-            if (subtrack == undefined || subtrack.length == 0) {
-                warn("DEBUG: scm.enableCfg() called without CB or subtrack.");
-                return false;
-            }
-            subCb = normed($("input[name='"+subtrack+"'_sel]"));
-            if (subCb == undefined) {
-                warn("DEBUG: scm.enableCfg() could not find CB for subtrack: "+subtrack);
-                return false;
-            }
-        }
-
-        var td = normed($(subCb).parent('td'));
-        if (td == undefined) {
-            warn("DEBUG: scm.enableCfg() could not find TD for CB: "+subCb.name);
-            return false;
-        }
-        var subFaux = normed($(td).find('div.subVisDD'));
-        if (subFaux != undefined) {
-            if (setTo == true)
-                $(subFaux).removeClass('disabled');
-            else
-                $(subFaux).addClass('disabled');
-        } else {
-            var subVis = normed($(td).find('select.subVisDD'));
-            if (subVis != undefined) {
-                $(subVis).attr('disabled',!setTo);
-            }
-        }
-        var wrench = normed($(td).find('span.clickable')); // TODO tighten this
-        if (wrench != undefined) {
-            if (setTo == true)
-                $(wrench).removeClass('halfVis');
-            else
-                $(wrench).addClass('halfVis');
-        }
-    },
-
-    cfgToggle: function (wrench,subtrack)
-    { // Opens/closes subtrack cfg dialog, populating if empty
-        var cfg = normed($("div#div_cfg_"+subtrack));
-        if (cfg == undefined) {
-            warn("DEBUG: Can't find div_cfg_"+subtrack);
-            return false;
-        }
-
-        if ($(cfg).css('display') == 'none') {
-            if ($(wrench).hasClass('halfVis'))
-                return;
-            // Don't allow if this composite is not enabled!
-            // find the cb
-            var tr = $(cfg).parents('tr').first();
-            var subCb = normed($(tr).find("#"+subtrack+"_sel"));
-            if (subCb == undefined) {
-                warn("Can't find subCB for "+subtrack);
-                return false;
-            }
-            if (subCb.disabled == true) // || subCb.checked == false)
-                return false;
-
-            if(metadataIsVisible(subtrack))
-                metadataShowHide(subtrack,"","");
-            if ($(cfg).hasClass('filled'))
-                $(cfg).show();
-            else
-                waitOnFunction( scm.cfgPopulate, cfg, subtrack );
-        } else
-            $(cfg).hide();
-        return false; // called by link!
-    },
-
-    subCbInit: function (subCb)
-    { // unnames the subCb control and sets up on change envent
-        scm.unnameIt(subCb,true);
-
-        var boolshad = normed( $("input[name='boolshad\\."+subCb.id+"']") );  // Not yet sanitized name
-        if (boolshad != undefined) {
-            scm.unnameIt(boolshad,true);
-        }
-        $(subCb).bind('click',function (e) {
-            scm.markChange(subCb);
-        });
-    },
-
-    viewInit: function (viewId)
-    { // unnames all view controls
-        // iterate through all matching controls and unname
-        var tr = normed($('tr#tr_cfg_'+viewId));
-        if (tr == undefined) {
-            warn('DEBUG: Did not find view: ' + viewId);
-            return;
-        }
-        var viewAllObjs = $(tr).find('input,select')
-        var viewObjs = $(viewAllObjs).not("input[type='hidden']");
-        if (viewObjs.length > 0) {
-            $(viewObjs).each(function (i) {
-                scm.unnameIt(this,true);
-                $(this).bind('change',function (e) {
-                    scm.propagateSetting(this);
-                });
-            });
-        }
-        // Special for checkboxes: boolshad
-        var boolObjs = $(viewAllObjs).filter("input[type='hidden']").filter("[name^='boolshad\\.']");
-        $(boolObjs).each(function (i) {
-            scm.unnameIt(this,true);
-        });
-
-        // Now vis control
-        var visObj = normed($("select[name='"+scm.compositeId+"\\."+viewId+"\\.vis']"));
-        if (visObj == undefined) {
-            warn('DEBUG: Did not find visibility control for view: ' + viewId);
-            return;
-        }
-        scm.unnameIt(visObj,true);
-        $(visObj).bind('change',function (e) {
-            scm.propagateVis(visObj,viewId);
-            scm.markChange(visObj);
-        });
-    },
-
-    initialize: function ()
-    { // unnames all composite controls and then all view controls
-      // names will be added back in onchange events
-        // mySelf = this; // There is no need for a "mySelf" unless this object is being instantiated.
-
-        var visObj = $('.visDD');
-        if (visObj == undefined || visObj.length < 1) {
-            warn('DEBUG: Did not find visibility control for composite.');
-            return;
-        }
-        if (visObj.length > 1) {
-            warn('DEBUG: Multiple visibility controls for composite???');
-            return;
-        }
-
-        scm.compositeId = $(visObj).attr('name');
-        scm.visIndependent = ($('.subVisDD').length > 0);  // Can subtracks have their own vis?
-
-        // Unname and set up vis propagation
-        visObj = visObj[0];
-        scm.unnameIt(visObj,true);
-        $(visObj).bind('change',function (e) {
-            scm.propagateVis(visObj,undefined);
-            scm.markChange(visObj);
-        });
-
-        // Find all appropriate controls and unname
-
-        // matCBs are easy, they never get named again
-        var matCbs = $('input.matCB');
-        $(matCbs).each(function (i) {
-            scm.unnameIt(this,false);
-        });
-
-        // SubCBs will get renamed and on change will name them back.
-        var subCbs = $('input.subCB');
-        $(subCbs).each(function (i) {
-            scm.subCbInit(this);
-        });
-
-        // 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 {
-                scm.viewIds[i] = classList[0];
-                scm.viewInit(scm.viewIds[i]);
-            }
-        });
-
-        // Tricky for composite level controls.  Could wrap cfg controls in new div.
-        // DO THIS AFTER Views
-        // NOTE: excluding sortOrder and showCfg which are special cases we don't care about in scm
-        var compObjs = $('select,input').filter("[name^='"+scm.compositeId+"\\.'],[name^='"+scm.compositeId+"_']");
-        if (compObjs != undefined && compObjs.length > 0) {
-            compObjs = $(compObjs).not("[name$='showCfg']");
-            $(compObjs).each(function (i) {
-                // DEBUG -------------
-                if (this.id != undefined
-                && this.id.length > 0
-                && $(this).hasClass('filterBy') == false
-                && $(this).hasClass('filterComp') == false)
-                    warn('DEBUG: Not expected control with name ['+this.name + '], and id #'+this.id);
-                // DEBUG -------------
-                scm.unnameIt(this,true);
-                $(this).bind('change',function (e) {
-                    scm.propagateSetting(this);
-                });
-            });
-        }
-        // Special for checkboxes: boolshad
-        var boolObjs = $("input[type='hidden']");
-        var boolObjs = $(boolObjs).filter("[name^='boolshad\\."+scm.compositeId+"\\.'],[name^='boolshad\\."+scm.compositeId+"_']");
-        $(boolObjs).each(function (i) {
-            scm.unnameIt(this,true);
-        });
-
-    }
-};
 
 // The following js depends upon the jQuery library
 $(document).ready(function()
 {
     // If divs with class 'subCfg' then initialize the subtrack cfg code
     // NOTE: must be before any ddcl setup
-    if (common.subCfg) {
+    if (typeof(scm) !== "undefined") {
         var divs = $("div.subCfg");
         if (divs != undefined && divs.length > 0) {
             scm.initialize();
         }
     }
 
     // Initialize sortable tables
     $('table.sortable').each(function (ix) {
         sortTableInitialize(this,true,true);
     });
 
     // Register tables with drag and drop
     $("table.tableWithDragAndDrop").each(function (ix) {
         tableDragAndDropRegister(this);
     });
 
-    //$('.halfVis').css('opacity', '0.5'); // The 1/2 opacity just doesn't get set from cgi!
-
     // Put navigation links in top corner
     navigationLinksSetup();
 });