a857c28d322f6bec282372ca7c1d84d4eccdf6a4
tdreszer
  Mon Jan 31 13:35:54 2011 -0800
Reworked searchTracks +/- buttons to use javascript and fixed some bugs seen when files search is enabled as a tab in track search.
diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js
index 5c38ce7..64ae34f 100644
--- src/hg/js/hgTracks.js
+++ src/hg/js/hgTracks.js
@@ -1292,47 +1292,31 @@
     }
     if($('img#chrom').length == 1) {
         if($('area.cytoBand').length > 1) {
             $('img#chrom').chromDrag();
         }
     }
 
     if($("#tabs").length > 0) {
         // Search page specific code
 
         var val = $('#currentTab').val();
         $("#tabs").tabs({
                             show: function(event, ui) {
                                 $('#currentTab').val(ui.panel.id);
                             },
-                            select: function(event, ui) {
-                                if( ui.panel.id == 'simpleTab' && $('div#found').length < 1) {
-                                    setTimeout("$('input#simpleSearch').focus();",20); // delay necessary, since select event not afterSelect event
-                                }
-                                if( $('div#filesFound').length == 1) {
-                                    if( ui.panel.id == 'filesTab')
-                                        $('div#filesFound').show();
-                                    else
-                                        $('div#filesFound').hide();
-                                }
-                                if( $('div#found').length == 1) {
-                                    if( ui.panel.id != 'filesTab')
-                                        $('div#found').show();
-                                    else
-                                        $('div#found').hide();
-                                }
-                            }
+                            select: function(event, ui) { findTracksSwitchTabs(ui); }
                         });
         $('#tabs').show();
         $("#tabs").tabs('option', 'selected', '#' + val);
         if(val =='simpleTab' && $('div#found').length < 1) {
             $('input#simpleSearch').focus();
         }
         $("#tabs").css('font-family', jQuery('body').css('font-family'));
         $("#tabs").css('font-size', jQuery('body').css('font-size'));
         $('.submitOnEnter').keydown(searchKeydown);
         findTracksNormalize();
         updateMetaDataHelpLinks(0);
     }
 
     if(typeof(trackDbJson) != "undefined" && trackDbJson != null) {
         for (var id in trackDbJson) {
@@ -1567,31 +1551,33 @@
                         $.ajax({
                                    type: "GET",
                                    url: "../cgi-bin/hgTracks",
                                    data: "hgt.trackImgOnly=1&hgt.ideogramToo=1&position=" + newPosition + "&hgsid=" + getHgsid(),
                                    dataType: "html",
                                    trueSuccess: handleUpdateTrackMap,
                                    success: catchErrorOrDispatch,
                                    error: errorHandler,
                                    cmd: cmd,
                                    cache: false
                                });
                     }
                 }
             }
     } else if (cmd == 'hgTrackUi_popup') {
+
         hgTrackUiPopUp( selectedMenuItem.id, false );  // Launches the popup but shields the ajax with a waitOnFunction
+
     } else if (cmd == 'hgTrackUi_follow') {
 
         var url = "hgTrackUi?hgsid=" + getHgsid() + "&g=";
         var rec = trackDbJson[id];
         if (tdbHasParent(rec) && tdbIsLeaf(rec))
             url += rec.parentTrack
         else {
             var link = $( 'td#td_btn_'+ selectedMenuItem.id ).children('a'); // The button already has the ref
             if( $(link) != undefined)
                 url = $(link).attr('href');
             else
                 url += selectedMenuItem.id;
         }
         location.assign(url);
 
@@ -2243,106 +2229,90 @@
                                                        style = style.replace(/height:\s*\d+/i, "height:" + rec.height);
                                                        $(this).attr('style', style);
                                                    }
                                                });
         var style = $('#p_btn_' + track).attr('style');
         style = style.replace(/height:\s*\d+/i, "height:" + rec.height);
         $('#p_btn_' + track).attr('style', style);
     }
 }
 
 /////////////////////////////////////////////////////
 // findTracks functions
 
 function findTracksMdbVarChanged(obj)
 { // Ajax call to repopulate a metadata vals select when mdb var changes
-    var newVar = $(obj).val();
-    var a = /hgt_mdbVar(\d+)/.exec(obj.name); // NOTE must match METADATA_NAME_PREFIX in hg/hgTracks/searchTracks.c
-    if(newVar != undefined && a && a[1]) {
-        var num = a[1];
-        $.ajax({
-                   type: "GET",
-                   url: "../cgi-bin/hgApi",
-                   data: "db=" + getDb() +  "&cmd=metaDb&var=" + newVar,
-                   trueSuccess: findTracksHandleNewMdbVals,
-                   success: catchErrorOrDispatch,
-                   error: errorHandler,
-                   cache: true,
-                   cmd: "hgt_mdbVal" + num, // NOTE must match METADATA_VALUE_PREFIX in hg/hgTracks/searchTracks.c
-                   num: num
-               });
-    }
-    //findTracksSearchButtonsEnable(true);
-}
+  // This handles the currnet case when 2 vars have the same name (e.g. advanced, files tabs)
 
-function findTracksHandleNewMdbVals(response, status)
-// Handle ajax response (repopulate a metadata val select)
-{   // TODO Support for returning whole control, not list of values.
-    var list = eval(response);
-    var ele = $('select[name=' + this.cmd + ']');
-    ele.empty();
-    ele.append("<option VALUE='Any'>Any</option>");
-    for (var i = 0; i < list.length; i++) {
-        var pair = list[i];
-        ele.append("<option VALUE='" + pair[1] + "'>" + pair[0] + "</option>");
-    }
-    updateMetaDataHelpLinks(this.num);
-}
+    findTracksClearFound();  // Changing values so abandon what has been found
 
-// TODO: Replace findTracksMdbVarChanged() and findTracksHandleNewMdbVals()
-function findTracksMdbVarChanged2(obj)
-{ // Ajax call to repopulate a metadata vals select when mdb var changes
     var newVar = $(obj).val();
     var a = /hgt_mdbVar(\d+)/.exec(obj.name); // NOTE must match METADATA_NAME_PREFIX in hg/hgTracks/searchTracks.c
     if(newVar != undefined && a && a[1]) {
         var num = a[1];
+        $("select.mdbVar[name='hgt_mdbVar"+num+"'][value!='"+newVar+"']").val(newVar);
         $.ajax({
                    type: "GET",
                    url: "../cgi-bin/hgApi",
                    data: "db=" + getDb() +  "&cmd=hgt_mdbVal" + num + "&var=" + newVar,
-                   trueSuccess: findTracksHandleNewMdbVals2,
+                   trueSuccess: findTracksHandleNewMdbVals,
                    success: catchErrorOrDispatch,
                    error: errorHandler,
                    cache: true,
                    cmd: "hgt_mdbVal" + num, // NOTE must match METADATA_VALUE_PREFIX in hg/hgTracks/searchTracks.c
                    num: num
                });
     }
     //findTracksSearchButtonsEnable(true);
 }
 
-function findTracksHandleNewMdbVals2(response, status)
-// Handle ajax response (repopulate a metadata val select)
-{   // TODO Support for returning whole control, not list of values.
-    //var list = eval(response);
+function findTracksHandleNewMdbVals(response, status)
+{ // Handle ajax response (repopulate a metadata val select)
+  // This handles the currnet case when 2 vars have the same name (e.g. advanced, files tabs)
+
     var td = $('td#' + this.cmd );
     if (td != undefined) {
         td.empty();
         td.append(response);
         var inp = $(td).find('.mdbVal');
         var tdIsLike = $('td#isLike'+this.num);
         if (inp != undefined && tdIsLike != undefined) {
             if ($(inp).hasClass('freeText')) {
                 $(tdIsLike).text('contains');
             } else {
                 $(tdIsLike).text('is');
             }
         }
     }
     updateMetaDataHelpLinks(this.num);
 }
 
+function findTracksMdbValChanged(obj)
+{ // Keep all tabs with same selects in sync  TODO: Change from name to id based identification and only have one set of inputs in form
+  // This handles the currnet case when 2 vars have the same name (e.g. advanced, files tabs)
+
+    findTracksClearFound();  // Changing values so abandon what has been found
+
+    var newVal = $(obj).val();
+    var a = /hgt_mdbVal(\d+)/.exec(obj.name); // NOTE must match METADATA_NAME_PREFIX in hg/hgTracks/searchTracks.c
+    if(newVal != undefined && a && a[1]) {
+        var num = a[1];
+        $("select.mdbVal[name='hgt_mdbVal"+num+"'][value!='"+newVal+"']").val(newVal);
+    }
+    //findTracksSearchButtonsEnable(true);
+}
+
 function searchKeydown(event)
 {
     if (event.which == 13) {
         // Required to fix problem on IE and Safari where value of hgt_tSearch is "-" (i.e. not "Search").
         $("input[name=hgt_tsPage]").val(0);  // NOTE: must match TRACK_SEARCH_PAGER in hg/inc/searchTracks.h
         $('#trackSearch').submit();
         // This doesn't work with IE or Safari.
         // $('#searchSubmit').click();
     }
 }
 
 function findTracksChangeVis(seenVis)
 { // called by onchange of vis
     var visName = $(seenVis).attr('id');
     var trackName = visName.substring(0,visName.length - "_id".length)
@@ -2482,35 +2452,44 @@
     } else {
         $(searchButton).attr('disabled',true);
         $(clearButton).attr('disabled',true);
     }
 }
 
 function findTracksCounts()
 {// Displays visible and checked track count
     var counter = $('.selCbCount');
     if(counter != undefined) {
         var selCbs =  $("input.selCb");
         $(counter).text("("+$(selCbs).filter(":enabled:checked").length + " of " +$(selCbs).length+ " selected)");
     }
 }
 
+function findTracksClearFound()
+{// Clear found tracks and all input controls
+    var found = $('div#found');
+    if(found != undefined)
+        $(found).remove();
+    found = $('div#filesFound');
+    if(found != undefined)
+        $(found).remove();
+    return false;
+}
+
 function findTracksClear()
 {// Clear found tracks and all input controls
-    var foundTracks = $('div#found');
-    if(foundTracks != undefined)
-        $(foundTracks).remove();
+    findTracksClearFound();
     $('input[type="text"]').val(''); // This will always be found
     //$('select.mdbVar').attr('selectedIndex',0); // Do we want to set the first two to cell/antibody?
     $('select.mdbVal').attr('selectedIndex',0); // Should be 'Any'
     $('select.groupSearch').attr('selectedIndex',0);
     $('select.typeSearch').attr('selectedIndex',0);
     //findTracksSearchButtonsEnable(false);
     return false;
 }
 
 function findTracksSortNow(obj)
 {// Called by radio button to sort tracks
     if( $('#sortIt').length == 0 )
         $('form#trackSearch').append("<input TYPE=HIDDEN id='sortIt' name='"+$(obj).attr('name')+"' value='"+$(obj).val()+"'>");
     else
         $('#sortIt').val($(obj).val());
@@ -2540,45 +2519,141 @@
         $(inp).appendTo('form#trackSearch');
         $('form#trackSearch').attr('method','POST'); // Must be post to avoid url too long  NOTE: probably needs to be post anyway
     }
 
     $('#searchSubmit').click();
     return false;
 }
 
 function findTracksConfigureSet(name)
 {// Called when configuring a composite or superTrack
     var thisForm =  $('form#searchResults');
     $(thisForm).attr('action',"../cgi-bin/hgTrackUi?hgt_tSearch=Search&g="+name);
     $(thisForm).find('input.viewBtn').click();
 }
 
-/////////////////////////////////////////////////////
+function findTracksMdbSelectPlusMinus(obj, rowNum)
+{ // Now [+][-] mdb var rows with javascript rather than cgi roundtrip
+  // Will remove row or clone new one.  Complication is that 'advanced' and 'files' tab duplicate the tables!
+
+    var objId = $(obj).attr('id');
+    rowNum = objId.substring(objId.length - 1);
+    if ($(obj).val() == '+') {
+        var buttons = $("input#plusButton"+rowNum);  // Two tabs may have the exact same buttons!
+        if (buttons.length > 0) {
+            $(buttons).each(function (i) {
+                var tr = $(this).parents('tr.mdbSelect')[0];
+                if (tr != undefined)
+                    $(tr).after( $(tr).clone() );
+                findTracksMdbSelectRowsNormalize($(tr).parents('table')[0]); // magic is in this function
+            });
+            return false;
+        }
+    } else { // == '-'
+        var buttons = $("input#minusButton"+rowNum);  // Two tabs may have the exact same buttons!
+        if (buttons.length > 0) {
+            var remaining = 0;
+            $(buttons).each(function (i) {
+                var tr = $(this).parents('tr')[0];
+                var table = $(tr).parents('table')[0];
+                if (tr != undefined)
+                    $(tr).remove();
+                remaining = findTracksMdbSelectRowsNormalize(table);  // Must renormalize since 2nd of 3 rows may have been removed
+            });
+            if (remaining > 0) {
+                removeNum = remaining + 1;  // Got to remove the cart vars, though it doesn't matter which as count must not be too many.
+                setCartVars( [ "hgt_mdbVar"+removeNum, "hgt_mdbVal"+removeNum ], [ "[]","[]" ] );
+            }
 
-function delSearchSelect(obj, rowNum)
-{
-    obj = $(obj);
-    $("input[name=hgt_tsDelRow]").val(rowNum);  // NOTE: Must match TRACK_SEARCH_DEL_ROW in hg/inc/searchTracks.h
+            findTracksClearFound();  // Changing values so abandon what has been found
+            return false;
+        }
+    }
     return true;
 }
 
-function addSearchSelect(obj, rowNum)
-{
-    obj = $(obj);
-    $("input[name=hgt_tsAddRow]").val(rowNum);  // NOTE: Must match TRACK_SEARCH_ADD_ROW in hg/inc/searchTracks.h
-    return true;
+function findTracksMdbSelectRowsNormalize(table)
+{ // Called when [-][+] buttons changed the number of mdbSelects in findTracks\
+  // Will walk through each row and get the numberings of addressable elements correct.
+    if (table != undefined) {
+        var mdbSelectRows = $(table).find('tr.mdbSelect');
+        var needMinus = (mdbSelectRows.length > 2);
+        $(table).find('tr.mdbSelect').each( function (ix) {
+            var rowNum = ix + 1;  // Each [-][+] and mdb var=val pair of selects must be numbered
+
+            // First the [-][+] buttons
+            var plusButton = $(this).find("input[value='+']")[0];
+            if (plusButton != undefined) {
+                $(plusButton).attr('id',"plusButton"+rowNum);
+                $(plusButton).unbind('click')
+                $(plusButton).click(function() { return findTracksMdbSelectPlusMinus($(plusButton), rowNum); });
+                var minusButton = $(this).find("input[value='-']")[0];
+                if (needMinus) {
+                    if (minusButton == undefined) {
+                        $(plusButton).before("<input type='button' id='minusButton"+rowNum+"' value='-' style='font-size:.7em;' title='delete this row' onclick='return findTracksMdbSelectPlusMinus(this,"+rowNum+");'>");
+                        minusButton = $(this).find("input[value='-']")[0];
+                    } else {
+                        $(minusButton).attr('id',"minusButton"+rowNum);
+                        $(minusButton).unbind('click');
+                        $(minusButton).click(function() { return findTracksMdbSelectPlusMinus($(minusButton), rowNum); });
+                    }
+                } else if (minusButton != undefined)
+                    $(minusButton).remove();
+            }
+            // Now the mdb var=val pair of selects
+            var element = $(this).find("select[name^='hgt_mdbVar']")[0];
+            if (element != undefined)
+                $(element).attr('name','hgt_mdbVar' + rowNum);
+
+            element = $(this).find("select[name^='hgt_mdbVal']")[0];
+            if (element != undefined)
+                $(element).attr('name','hgt_mdbVal' + rowNum);
+
+            // A couple more things
+            element = $(this).find("td[id^='isLike']")[0];
+            if (element != undefined)
+                $(element).attr('id','isLike' + rowNum);
+            element = $(this).find("td[id^='hgt_mdbVal']")[0];
+            if (element != undefined)
+                $(element).attr('id','hgt_mdbVal' + rowNum);
+        });
+        return mdbSelectRows.length;
+    }
+    return 0;
+}
+
+function findTracksSwitchTabs(ui)
+{ // switching tabs on findTracks page
+
+    if( ui.panel.id == 'simpleTab' && $('div#found').length < 1) {
+        setTimeout("$('input#simpleSearch').focus();",20); // delay necessary, since select event not afterSelect event
+    }
+    if( $('div#filesFound').length == 1) {
+        if( ui.panel.id == 'filesTab')
+            $('div#filesFound').show();
+        else
+            $('div#filesFound').hide();
 }
+    if( $('div#found').length == 1) {
+        if( ui.panel.id != 'filesTab')
+            $('div#found').show();
+        else
+            $('div#found').hide();
+    }
+}
+
+/////////////////////////////////////////////////////
 
 function updateMetaDataHelpLinks(index)
 {
 // update the metadata help links based on currently selected values.
 // If index == 0 we update all help items, otherwise we only update the one == index.
     var i;
     var db = getDb();
     var disabled = {
         'accession': 1,
         'dataType': 1,
         'dataVersion': 1,
         'geoSample': 1,
         'grant': 1,
         'lab': 1,
         'labExpId': 1,