1a89c8e587e4cdbdb94430448caaa19247871cb8 tdreszer Thu Sep 22 13:01:11 2011 -0700 Big load of changes for subCfg. diff --git src/hg/js/hui.js src/hg/js/hui.js index 1344e76..479a773 100644 --- src/hg/js/hui.js +++ src/hg/js/hui.js @@ -19,31 +19,30 @@ { // 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 - exposeAll(); 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) { @@ -85,65 +84,63 @@ $( 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 = $("select.visDD"); // limit to hidden - if ($(visDD).length == 1) { - visDD = visDD[0]; // limit to hidden + var visDD = normed($("select.visDD")); // limit to hidden + if (visDD != undefined) { if ($(visDD).attr('selectedIndex') == 0) { $(visDD).attr('selectedIndex',$(visDD).children('option').length - 1); - scm.propagateVis(visDD); + $(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); // 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? - ///////////scm.enableCfg(subCB,null,subCB.checked); - 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"); if(classList.length == 0 ) matSubCBsCheck(matCB.checked); else if(classList.length == 1 ) matSubCBsCheck(matCB.checked,classList[0]); // dimX or dimY or dim ABC @@ -183,36 +180,38 @@ 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(state) exposeAll(); // Unhide composite vis? ////////showOrHideSelectedSubtracks(); matSubCBsSelected(); //jQuery(this).css('cursor', ''); var tbody = $( subCbs[0] ).parents('tbody.sorting'); if (tbody != undefined) $(tbody).removeClass('sorting'); return true; } function matSetMatrixCheckBoxes(state) { var tbody = $( 'tbody.sortable'); if (tbody != undefined) @@ -290,44 +289,56 @@ $(this).parent().attr('title','view is hidden'); $(this).parent().attr('cursor','pointer'); } this.disabled = !state; matSubCBsetShadow(this); hideOrShowSubtrack(this); }); return true; } function matSubCBcheckOne(subCB,state) { // setting a single subCB may cause it to appear/disappear subCB.checked = state; - scm.enableCfg(subCB,null,state); + if (common.subCfg) + scm.checkOneSubtrack(subCB,state,!subCB.disabled); 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 var shadowState = 0; if(subCB.checked) shadowState = 1; if(subCB.disabled) shadowState -= 2; - $("#"+subCB.name+"_4way").val(shadowState); + 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 + warn("DEBUG: Failed to find fourWay shadow for '#"+subCB.id+"' ["+subCB.name+"]"); + if (common.subCfg) + scm.enableCfg(subCB,null,(shadowState == 1)); } 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"); 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 @@ -378,50 +389,50 @@ 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"); else return $("input.matCB.halfVis"); } 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"); + classList = aryRemove(classList,"subCB","changed"); 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"); + classList = aryRemove(classList,"subCB","changed"); 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 @@ -439,31 +450,31 @@ 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"); + 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"); } @@ -482,82 +493,82 @@ { // 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 = $(inp).parents(".blueBox"); - if(daddy.length == 1) { - var classList = $(daddy[0]).attr("class").split(" "); + 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 $(this).parents(".blueBox." + view).length == 1; });} + 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 $(this).parents(".blueBox." + view).length == 1; });} + 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 $(this).parents(".blueBox." + view).length == 1; });} + 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 $(this).parents(".blueBox." + view).length == 1; });} + 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']"); @@ -936,31 +947,31 @@ 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" ]); + possibleClasses = aryRemoveVals(possibleClasses,[ "subCB","changed" ]); 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; } @@ -1057,214 +1068,235 @@ { // 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. + // 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) outside in: matrix and subtrack checkboxes to affect vis - // 2) Non-configurable will need to show/change vis independently! (separate vis control instead of wrench?) - // 3) SOLVED: Radio buttons work BUT they require name to keep unified set, so rely upon 'changed' class to detect changes. - // 4) SOLVED: checkboxes: working with name = boolshad.{name} FIXME: multishad? - // 5) SOLVED: filterBy,filterComp working: they rely upon id, and id with '.' screwed it all up. So replaced '.' with '_-' - // 6) SOLVED: subCfg not matching parent: solved. - // 7) SOLVED: OpenChromSynth: subtrack filterby needs to be updated by composite filterBy. - // 8) Remove debug code when ready - // - check subtrack to enable/disable fauxVis and wrench - // - matCB should effect subCb including enable/disable fauxVis and wrench - // - composite/view vis should effect subVis and enable/disable fauxVis and wrench + // 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: null, + 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! + + 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! + + if(obj.type.indexOf("radio") == 0) // radios must keep their names! + return; + $(obj).removeAttr('name'); - }, - markCheckboxChange: function (obj) - { // Marks a checkbox as having changed and the boolshad too if there is one - scm.markChange(obj); - - //var safeId = obj.id.replace(/\./g,"\\."); - //var boolshad = $('input#boolshad\\.' + safeId); - var boolshad = $('input#boolshad_-' + obj.id); - if (boolshad != undefined && boolshad.length > 0) { - if (boolshad.length == 1) - boolshad = boolshad[0]; - if(obj.checked == false) - scm.markChange(boolshad); - else - scm.clearChange(boolshad); + // 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 - if (setId) { 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("Found control with '_-' in name: "+myName + "<BR>This violates the naming rules and will break javascript code."); + 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 ------------- - myName = myName.replace(/\./g,'_-'); // sanitized id replaces '.' with '_-' - $(obj).attr('id',myName); + $(obj).attr('id',newId); } } - scm.clearChange(obj); + + 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(); - var compObj = undefined; + //var compCfg = scm.compositeCfgFind(); // TODO: when there is a composite cfg div! + var compObj; if (suffix != undefined) { //compObj = $('#'+ scm.compositeId + '\\.' + suffix); - compObj = $('#'+ scm.compositeId + '_-' + suffix); - if (compObj == undefined || compObj.length == 0) { - compObj = $('#'+ scm.compositeId + '_' + suffix); + compObj = normed($('#'+ scm.compositeId + '_-' + suffix)); + if (compObj == undefined) { + compObj = normed($('#'+ scm.compositeId + '_' + suffix)); } } else { - compObj = $("#"+scm.compositeId); + compObj = normed($("#"+scm.compositeId)); } - if (compObj == undefined || compObj.length == 0) { - //warn('Could not find viewObj for '+suffix); - return undefined; - } - if (compObj.length == 1) - compObj = compObj[0]; return compObj; }, viewIdFind: function (childObj) { // returns the name of the view that is a parent of this subtrack control - var cfg = $(childObj).parents('div.subCfg'); - if (cfg == undefined || cfg.length == 0) { + 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[0] ).attr("class").split(" "); + 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 = $('tr#tr_cfg_'+viewId); - if (viewCfg == undefined || viewCfg.length == 0) { + var viewCfg = normed($('tr#tr_cfg_'+viewId)); + if (viewCfg == undefined) { warn('Could not find viewCfg for '+viewId); } - if (viewCfg.length == 1) - viewCfg = viewCfg[0]; return viewCfg; }, viewObjFind: function (viewId,suffix) { // returns the control belonging to this view and suffix - var viewObj = undefined; + var viewObj; if (suffix != undefined) { var viewCfg = scm.viewCfgFind(viewId); - //viewObj = $(viewCfg).find("[id$='\\."+suffix+"']"); - viewObj = $(viewCfg).find("[id$='_-"+suffix+"']"); - if (viewObj == undefined || viewObj.length == 0) { - viewObj = $(viewCfg).find("[id$='_"+suffix+"']"); - } - } else { - //viewObj = $("#"+scm.compositeId+"\\."+viewId+"\\.vis"); - viewObj = $("#"+scm.compositeId+"_-"+viewId+"_-vis"); - } - if (viewObj == undefined || viewObj.length == 0) { - // Okay not to find a view for this composite level obj - //warn('Could not find viewObj for '+viewId+'.'+suffix); - return undefined; - } - if (viewObj.length == 1) - viewObj = viewObj[0]; + 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 || childCfgs.length == 0) + 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) @@ -1275,55 +1307,53 @@ 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 = $(childObj).parents('div.subCfg.filled'); - if (childCfg == undefined || childCfg.length == 0) { + var childCfg = normed($(childObj).parents('div.subCfg.filled')); + if (childCfg == undefined) warn("Can't find childCfg for "+childObj.id); - return false; - } - if (childCfg.length == 1) - childCfg = childCfg[0]; 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 = $(tr).find("input[name='"+subtrack+"_sel']"); - if (subCb == undefined || subCb.length == 0) { + var subCb = normed($(tr).find("input[name='"+subtrack+"_sel']")); + if (subCb == undefined) warn("Can't find subCB for subtrack: "+subtrack); - return undefined; - } - if (subCb.length == 1) - subCb = subCb[0]; 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) @@ -1371,44 +1401,42 @@ // 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"); + 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 = $(parentObj).parents("tr[id^='tr_cfg_']"); - isComposite = (viewCfg == undefined || viewCfg.length == 0); // is composite + var viewCfg = normed($(parentObj).parents("tr[id^='tr_cfg_']")); + isComposite = (viewCfg == undefined); // is composite if (!isComposite) { - if (viewCfg.length == 1) - viewCfg = viewCfg[0]; 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; @@ -1435,242 +1463,207 @@ { // 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"); + 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,null,check); + 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); }); - // deal with hidden boolshads! - //var parentIdSafe = parentObj.id.replace(/\./g,"\\."); - //var boolshad = $('input#boolshad\\.'+parentIdSafe); - var boolshad = $('input#boolshad_-'+parentObj.id); - if (boolshad != undefined && boolshad.length > 0) { - if (boolshad.length == 1) - boolshad = boolshad[0]; - if (parentObj.checked == false) - scm.markChange(boolshad); - else - scm.clearChange(boolshad); - } } else if(parentObj.type.indexOf("radio") == 0) { - var parentChecked = parentObj.checked; var parentVal = $(parentObj).val(); $(children).each(function (i) { - if ($(this).val() == parentVal) - this.checked = parentObj.checked; + 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'; - // vis outside of subCfg + var children = scm.visChildrenFind(viewObj); $(children).each(function (i) { if ($(this).hasClass('fauxInput')) { $(this).text(visText); } else { $(this).attr('selectedIndex',limitedVis); scm.clearChange(this); } }); - // vis inside of subCfg - //var children = scm.childrenFind(viewObj); - //$(children).each(function (i) { - // // TODO: only set if selected? - // $(this).attr('selectedIndex',limitedVis); - // scm.clearChange(this); - //}); }, propagateVis: function (parentObj,viewId) { // propagate vis settings to subtrack children - if (viewId == null) { + 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 - // vis outside of subCfg + 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); } }); - // vis inside of subCfg - //var children = scm.childrenFind(parentObj); - //$(children).each(function (i) { - // var subCb = scm.subCbFind(this); - // if (subCb != undefined) { - // if (subCb.disabled != true && subCb.checked) { // TODO: Integrate with things that enable/check! - // $(this).attr('selectedIndex',parentVis); - // scm.clearChange(this); - // } - // } - //}); } } 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; } scm.propagateViewVis(parentObj,compObj.selectedIndex); } }, - inheritSetting: function (childObj) + 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('No parents were found for childObj: '+childObj.id); + warn('DEBUG No parents were found for childObj: '+childObj.id); // DEBUG ------------- return true; } var isVis = (undefined == scm.objSuffixGet(childObj)); if (isVis) { var subCb = scm.subCbFind(childObj); if (subCb != undefined) { - if (subCb.disabled == true || subCb.checked == false) // TODO: Integrate with _sel subCbs and matCbs - $(childObj).attr('selectedIndex',0); - else { var limitedVis = 9; - if (myParents.length == 1 && scm.hasChanged(myParents[0])) + if (myParents.length == 1 && (force || scm.hasChanged(myParents[0]))) limitedVis = myParents[0].selectedIndex; else if (myParents.length == 2) { - if (scm.hasChanged(myParents[0]) || scm.hasChanged(myParents[1])) + 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 (scm.hasChanged(this)) { + 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 (scm.hasChanged(this)) { + 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 (scm.hasChanged(this)) { + 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: null, // keep track of cfg while ajaxing, man - currentSub: null, // keep track of subtrack while ajaxing, dude + 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 = null; + 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,""); @@ -1711,374 +1704,356 @@ $(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); // updates any values that have been changed on this page + 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) { - if(this.type.indexOf("checkbox") == 0) - scm.markCheckboxChange(this); - else scm.markChange(this); }); } - } else {//if (this.type == 'hidden') { - // Special for checkboixes with name = boolshad.{name}. - if ("boolshad." == this.name.substring(0,9)) { - scm.unnameIt(this,true); - } } } }); // 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 = $('div#' + scm.currentSub+'_faux'); - if (subVis != undefined && subVis.length == 1) { - // SHOULD NOT NEED $(subVis[0]).removeClass('disabled'); - scm.replaceWithVis(subVis[0],scm.currentSub,false); - } + 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 - if (newJQuery) { $(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'"; - if (open) - selectHtml += " size=5"; + var selectHtml = "<SELECT id='"+subtrack+"' class='normalText subVisDD "+view+"' style='width:70px;'"; selectHtml += ">"; var selected = $(obj).text(); - if (selected == 'hide') - selectHtml += "<OPTION SELECTED>hide</OPTION><OPTION>dense</OPTION><OPTION>squish</OPTION><OPTION>pack</OPTION><OPTION>full</OPTION>"; - else if (selected == 'dense') - selectHtml += "<OPTION>hide</OPTION><OPTION SELECTED>dense</OPTION><OPTION>squish</OPTION><OPTION>pack</OPTION><OPTION>full</OPTION>"; - else if (selected == 'squish') - selectHtml += "<OPTION>hide</OPTION><OPTION>dense</OPTION><OPTION SELECTED>squish</OPTION><OPTION>pack</OPTION><OPTION>full</OPTION>"; - else if (selected == 'full') - selectHtml += "<OPTION>hide</OPTION><OPTION>dense</OPTION><OPTION>squish</OPTION><OPTION>pack</OPTION><OPTION SELECTED>full</OPTION>"; - else - selectHtml += "<OPTION>hide</OPTION><OPTION>dense</OPTION><OPTION>squish</OPTION><OPTION>pack</OPTION><OPTION>full</OPTION>"; + 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).attr('size',5) + $(newObj).css({'zIndex':'2','vertical-align':'top'}); + $(newObj).attr('size',5); $(newObj).one('blur',function (e) { $(this).attr('size',1); - $(this).unbind() + $(this).unbind('blur'); }); - $(newObj).one('change',function (e) { + $(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 ------------- + } + } else + scm.markChange(this); }); - // Doesn't work! - //$(newObj).parents('td').first().attr('valign','top'); $(newObj).focus(); } }, enableCfg: function (subCb,subtrack,setTo) { // Enables or disables subVis and wrench - if (subCb == null || subCb == undefined) { - if (subtrack == null || subtrack.length == 0) { - warn("scm.enableCfg() called without CB or subtrack."); + if (subCb == undefined) { + if (subtrack == undefined || subtrack.length == 0) { + warn("DEBUG: scm.enableCfg() called without CB or subtrack."); return false; } - subCb = $("input[name='"+subtrack+"'_sel]"); - if (subCb == undefined || subCb.length == 0) { - warn("scm.enableCfg() could not find CB for subtrack: "+subtrack); + subCb = normed($("input[name='"+subtrack+"'_sel]")); + if (subCb == undefined) { + warn("DEBUG: scm.enableCfg() could not find CB for subtrack: "+subtrack); return false; } } - if (subCb.length == 1) - subCb = subCb[0]; - var td = $(subCb).parent('td'); - if (td == undefined || td.length == 0) { - warn("scm.enableCfg() could not find TD for CB: "+subCb.name); + var td = normed($(subCb).parent('td')); + if (td == undefined) { + warn("DEBUG: scm.enableCfg() could not find TD for CB: "+subCb.name); return false; } - if (td.length == 1) - td = td[0]; - var subFaux = $(td).find('div.subVisDD'); - if (subFaux != undefined && subFaux.length > 0) { + var subFaux = normed($(td).find('div.subVisDD')); + if (subFaux != undefined) { if (setTo == true) $(subFaux).removeClass('disabled'); else $(subFaux).addClass('disabled'); } else { - var subVis = $(td).find('select.subVisDD'); - if (subVis != undefined && subVis.length > 0) { - $(subVis).attr('disable',!setTo); + var subVis = normed($(td).find('select.subVisDD')); + if (subVis != undefined) { + $(subVis).attr('disabled',!setTo); } } - var wrench = $(td).find('span.clickable'); // TODO tighten this - if (wrench != undefined && wrench.length > 0) { + 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 = $("div#div_cfg_"+subtrack); - if (cfg == undefined || cfg.length == 0) { - warn("Can't find div_cfg_"+subtrack); + var cfg = normed($("div#div_cfg_"+subtrack)); + if (cfg == undefined) { + warn("DEBUG: Can't find div_cfg_"+subtrack); return false; } - if (cfg.length == 1) - cfg = cfg[0]; 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 = $(tr).find("input[name='"+subtrack+"_sel']"); - if (subCb == undefined || subCb.length == 0) { + var subCb = normed($(tr).find("#"+subtrack+"_sel")); + if (subCb == undefined) { warn("Can't find subCB for "+subtrack); return false; } - if (subCb.length == 1) - subCb = subCb[0]; 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 = $('input#boolshad_-'+subCb.id); - if (boolshad != undefined && boolshad.length == 1) { - scm.unnameIt(boolshad[0],false); + + var boolshad = normed( $("input[name='boolshad\\."+subCb.id+"']") ); // Not yet sanitized name + if (boolshad != undefined) { + scm.unnameIt(boolshad,true); } $(subCb).bind('click',function (e) { - // deal with hidden boolshads! - var boolshad = $('input#boolshad_-'+subCb.id); - if (boolshad != undefined && boolshad.length == 1) { - if (subCb.checked == false) - scm.markChange(boolshad[0]); - else - scm.clearChange(boolshad[0]); - } scm.markChange(subCb); }); }, viewInit: function (viewId) { // unnames all view controls // iterate through all matching controls and unname - var tr = $('tr#tr_cfg_'+viewId); - if (tr == undefined || tr.length == 0) { - warn('Did not find view: ' + viewId); + var tr = normed($('tr#tr_cfg_'+viewId)); + if (tr == undefined) { + warn('DEBUG: Did not find view: ' + viewId); return; } - if (tr.length == 1) - tr = tr[0]; 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 = $("select[name='"+scm.compositeId+"\\."+viewId+"\\.vis']"); - if (visObj == undefined || visObj.length == 0) { - warn('Did not find visibility control for view: ' + viewId); + var visObj = normed($("select[name='"+scm.compositeId+"\\."+viewId+"\\.vis']")); + if (visObj == undefined) { + warn('DEBUG: Did not find visibility control for view: ' + viewId); return; } - if (visObj.length == 1) - visObj = visObj[0]; 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. - scm.compositeId = $('.visDD').first().attr('name'); - scm.visIndependent = ($('.subVisDD').length > 0); + + 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); }); - // Now vis control - var visObj = $("select[name='"+scm.compositeId+"']"); - if (visObj == undefined || visObj.length == 0) { - warn('Did not find visibility control for composite.'); - return; - } - if (visObj.length == 1) - visObj = visObj[0]; - scm.unnameIt(visObj,true); - $(visObj).bind('change',function (e) { - scm.propagateVis(visObj,null); - }); - // iterate through views var viewVis = $('select.viewDD'); $(viewVis).each(function (i) { var classList = $( this ).attr("class").split(" "); - classList = aryRemove(classList,"viewDD","normalText"); + classList = aryRemove(classList,"viewDD","normalText","changed"); if (classList.length == 0) - warn('View classlist is missing view class.'); + warn('DEBUG: View classlist is missing view class.'); else if (classList.length > 1) - warn('View classlist contains unexpected classes:' + classList); + warn('DEBUG: View classlist contains unexpected classes:' + classList); else { - scm.viewIds[scm.viewIds.length] = classList[0]; - scm.viewInit(classList[0]); + 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('['+this.name + '] #'+this.id); + 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) { 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! - $('.filterComp').each( function(i) { // Do this by 'each' to set noneIsAll individually - if (newJQuery == false) - $(this).dropdownchecklist({ firstItemChecksAll: true, noneIsAll: $(this).hasClass('filterBy'), maxDropHeight: filterByMaxHeight(this) }); - }); - // Put navigation links in top corner navigationLinksSetup(); });