src/hg/js/hui.js 1.53

1.53 2010/05/14 18:34:39 tdreszer
Supprt for new filterComposite
Index: src/hg/js/hui.js
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/js/hui.js,v
retrieving revision 1.52
retrieving revision 1.53
diff -b -B -U 4 -r1.52 -r1.53
--- src/hg/js/hui.js	30 Apr 2010 00:27:21 -0000	1.52
+++ src/hg/js/hui.js	14 May 2010 18:34:39 -0000	1.53
@@ -155,9 +155,9 @@
         subCDs = $( subCDs ).filter("."+arguments[vIx]);  // Successively limit list by additional classes.
     }
     if(state) { // If clicking [+], further limit to only checked ABCs
         var classes = matAbcCBclasses('unchecked');
-        subCDs = objsFilterByClasses(subCDs,false,classes);  // remove unchecked abcCB classes
+        subCDs = objsFilterByClasses(subCDs,"not",classes);  // remove unchecked abcCB classes
     }
     $( subCDs ).each( function (i) {
         this.checked = state;
         matSubCBsetShadow(this);
@@ -167,8 +167,65 @@
     //jQuery(this).css('cursor', '');
     return true;
 }
 
+function filterCompositeSelectionChanged(obj)
+{ // filterComposite:onchange Set subtrack selection based upon the changed filter
+
+    if($(obj).val() != undefined
+    && $(obj).val().toString().indexOf("All,") != -1) {
+        $(obj).val("All");
+        $(obj).attr('selectedIndex',0);
+    }
+    // Get list of values which should match classes of subtracks
+    var classes = $(obj).val();  // It is already an array!
+    if(classes == null) { // Nothing is selected.  Mark with "[empty]"
+        classes = "";
+        setCartVar($(obj).attr('name'),"[empty]");
+        //$(obj).val("[empty]");
+    }
+
+    // For all subtracks that DO NOT match selected classes AND are checked: uncheck
+    var subCBs = $("input.subCB");
+    var subCBsToUnselect = subCBs;
+    if (classes.length > 0 && classes[0] != "All")
+        subCBsToUnselect = objsFilterByClasses(subCBsToUnselect,"not",classes);  // remove unchecked classes
+    if (subCBsToUnselect.length > 0)
+        subCBsToUnselect = $(subCBsToUnselect).filter(":checked");
+    if (subCBsToUnselect.length > 0)
+        subCBsToUnselect.each( function (i) { matSubCBcheckOne(this,false); });
+
+    // For all subtracks that DO match a selected class AND are NOT checked:
+    //  Figure out if other selection criteria match.  If so: check
+    //var subCBs = $("input.subCB");
+    var subCBsToSelect = subCBs;
+    if(classes.length > 0) {
+        if(classes.length > 0 && classes[0] != "All")
+            subCBsToSelect = objsFilterByClasses(subCBsToSelect,"or",classes);     // Keep any that should be selected
+        // Now deal with all the others
+        if (subCBsToSelect.length > 0) {
+            var filterComp = $("select.filterComp").not("[name='"+obj.name+"']"); // Exclude self from list
+            for(var ix=0;ix<filterComp.length && subCBsToSelect.length > 0;ix++) {
+                var filterClasses = $(filterComp[ix]).val();
+                //alert(filterClasses);
+                if(filterClasses.length > 0 && filterClasses[0] != "All")
+                    subCBsToSelect = objsFilterByClasses(subCBsToSelect,"or",filterClasses);     // Keep any that should be selected
+                else if(filterClasses.length == 0)
+                    subCBsToSelect.length = 0;
+            }
+            //alert("filterComp:"+filterComp.length);
+        }
+        // What to do now?
+        if (subCBsToSelect.length > 0)
+            subCBsToSelect = $(subCBsToSelect).not(":checked");
+        if (subCBsToSelect.length > 0)
+            subCBsToSelect.each( function (i) { matSubCBcheckOne(this,true); });
+    }
+    //alert("Subtracks:"+subCBs.length+"  To be selected:"+subCBsToSelect.length+"  unselected:"+subCBsToUnselect.length)
+    matSubCBsSelected();
+    //$(obj).children("option:even").disabled = true;
+}
+
 ///////////// CB support routines ///////////////
 // Terms:
 // viewDD - view drop-down control
 // matButton: the [+][-] button controls associated with the matrix
@@ -191,9 +248,9 @@
     }
 
     if(state) { // If checking subCBs, then make sure up to 3 dimensions of matCBs agree with each other on subCB verdict
         var classes = matAbcCBclasses('unchecked');
-        subCBs = objsFilterByClasses(subCBs,false,classes);  // remove unchecked abcCB classes
+        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
@@ -265,9 +322,9 @@
     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,false,arguments[1]);
+        subCBs = objsFilterByClasses(subCBs,"not",arguments[1]);
     }
 
     if(subCBs.length > 0) {
         var CBsChecked = subCBs.filter(":checked");
@@ -352,11 +409,13 @@
 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) {
+        if(keep == "and") {
             objs = $( objs ).filter( '.' + classes.join('.') ); // filter('class1.class2') is same as filter('.class1').filter('.class2')
-        } else {
+        } else if(keep == "or") {
+            objs = $( objs ).filter( '.' + classes.join(',.') ); // filter('class1.class2') is same as filter('.class1').filter('.class2')
+        } 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')
             }
         }
@@ -403,9 +462,9 @@
 
 function matSubCBsSelected()
 {
 // Displays visible and checked track count
-    var counter = $('#subCBcount');
+    var counter = $('.subCBcount');
     if(counter != undefined) {
         var subCBs =  $("input.subCB");
         $(counter).text($(subCBs).filter(":enabled:checked").length + " of " +$(subCBs).length+ " selected");
     }
@@ -973,17 +1032,29 @@
     }
     $(sel).show();
 }
 
-function multiSelectBlur(obj)
+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) {
@@ -996,19 +1067,39 @@
         }
     }*/
 }
 
-function multiSelectClick(obj,sizeWhenOpen)
-{
-    if($(obj).attr('size') == 1)
+function multiSelectFocus(obj,sizeWhenOpen)
+{ // Opens multiselect whenever it gets focus
+    if($(obj).attr('size') != sizeWhenOpen) {
+    $(obj).children("option").show();
         $(obj).attr('size',sizeWhenOpen);
-    else if($(obj).attr('selectedIndex') == 0)
+    //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;
 }
 
+
 // The following js depends upon the jQuery library
 $(document).ready(function()
 {
+    //jQuery.each(jQuery.browser, function(i, val) {
+    //    if(val) {
+    //        browser = i;
+    //    }
+    //});
     //matInitializeMatrix();
     //$("div.multiSelectContainer").each( function (i) {
     //    var sel = $(this).children("select:first");
     //    multiSelectLoad(this,sel.openSize);
@@ -1029,5 +1120,7 @@
             function(){$(this).removeClass('pale');}
         );
     }
     $('.halfVis').css('opacity', '0.5'); // The 1/2 opacity just doesn't get set from cgi!
+
+    $('.filterComp').dropdownchecklist({ firstItemChecksAll: true, emptyText: 'Please select ...' });
 });