d3ed4e62c1515da4f6c9417545b657a412a8d0df
tdreszer
Fri Feb 25 12:05:08 2011 -0800
Moved code from 'hgTracks.js' to common 'utils.js' and added support for multi-selects in file and track search
diff --git src/hg/js/utils.js src/hg/js/utils.js
index 869d6ba..e6a7efe 100644
--- src/hg/js/utils.js
+++ src/hg/js/utils.js
@@ -1658,15 +1658,481 @@
// return appropriate width for hgTracks image given users current window width
return $(window).width() - 20;
}
function hgTracksSetWidth()
{
var winWidth = calculateHgTracksWidth();
if($("#imgTbl").length == 0) {
// XXXX what's this code for?
$("#TrackForm").append('');
//$("#TrackForm").submit();
} else {
$("input[name=pix]").val(winWidth);
}
}
+
+/////////////////////////////////////////////////////
+// findTracks functions
+
+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 db = getDb();
+ var disabled = { // blackList
+ 'accession': 1, 'dataType': 1, 'dataVersion': 1, 'geoSample': 1, 'grant': 1,
+ 'lab': 1, 'labExpId': 1, 'labVersion': 1, 'origAssembly': 1, 'replicate': 1,
+ 'setType': 1, 'softwareVersion': 1, 'subId': 1, 'view': 1
+ }
+ var expected = $('tr.mdbSelect').length;
+ var ix=1;
+ if (index!=0) {
+ ix=index;
+ expected=index;
+ }
+ for(;ix <= expected;ix++) {
+ var helpLink = $("span#helpLink" + ix);
+ if (helpLink.length > 0) {
+ var val = $("select[name='hgt_mdbVar" + ix + "']").val(); // NOTE must match METADATA_NAME_PREFIX in hg/hgTracks/searchTracks.c
+ var text = $("select[name='hgt_mdbVar" + ix + "'] option:selected").text();
+ helpLink.html(" "); // Do not want this with length == 0 later!
+ if (typeof(disabled[val]) == 'undefined') {
+ var str;
+ if (val == 'cell') {
+ if (db.substr(0, 2) == "mm") {
+ str = "../ENCODE/cellTypesMouse.html";
+ } else {
+ str = "../ENCODE/cellTypes.html";
+ }
+ } else if (val.toLowerCase() == 'antibody') {
+ str = "../ENCODE/antibodies.html";
+ } else {
+ str = "../ENCODE/otherTerms.html#" + val;
+ }
+ helpLink.html("" + text + "");
+ }
+ }
+ }
+}
+
+function findTracksMdbVarChanged(obj)
+{ // Ajax call to repopulate a metadata vals select when mdb var changes
+ // 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 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];
+ if ($('#advancedTab').length == 1 && $('#filesTab').length == 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: 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 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) {
+ var usesFilterBy = ($("select.mdbVar[name='hgt_mdbVar"+this.num+"']").hasClass('noMulti') == false);
+ 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 if (usesFilterBy && $(inp).hasClass('filterBy')) {
+ $(tdIsLike).text('is (any of)');
+ } else {
+ $(tdIsLike).text('is');
+ }
+ }
+ $(td).find('.filterBy').each( function(i) { // Do this by 'each' to set noneIsAll individually
+ if (usesFilterBy) {
+ $(this).dropdownchecklist({ firstItemChecksAll: true, noneIsAll: true });
+ } else {
+ $(this).attr("multiple",false);
+ $(this).removeClass('filterBy');
+ $(this).show();
+ }
+ });
+ }
+ 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
+
+ if ($('#advancedTab').length == 1 && $('#filesTab').length == 1) {
+ 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];
+ $("input.mdbVal[name='hgt_mdbVal"+num+"'][value!='"+newVal+"']").val(newVal);
+ $("select.mdbVal[name='hgt_mdbVal"+num+"'][value!='"+newVal+"']").each( function (i) {
+ $(this).val(newVal);
+ if ($(this).hasClass('filterBy')) {
+ //$(this).dropdownchecklist("refresh"); // requires v1.1
+ $(this).dropdownchecklist("destroy");
+ $(this).dropdownchecklist({ firstItemChecksAll: true, noneIsAll: true });
+ }
+ });
+ }
+ }
+ //findTracksSearchButtonsEnable(true);
+}
+
+function findTracksChangeVis(seenVis)
+{ // called by onchange of vis
+ var visName = $(seenVis).attr('id');
+ var trackName = visName.substring(0,visName.length - "_id".length)
+ var hiddenVis = $("input[name='"+trackName+"']");
+ var tdb = tdbGetJsonRecord(trackName);
+ if($(seenVis).val() != "hide")
+ $(hiddenVis).val($(seenVis).val());
+ else {
+ var selCb = $("input#"+trackName+"_sel_id");
+ $(selCb).attr('checked',false); // Can't set it to [] because that means default setting is used. However, we are explicitly hiding this!
+ $(seenVis).attr('disabled',true); // Can't set it to [] because that means default setting is used. However, we are explicitly hiding this!
+ var needSel = (tdb.parentTrack != undefined);
+ if (needSel) {
+ var hiddenSel = $("input[name='"+trackName+"_sel']");
+ $(hiddenSel).val('0'); // Can't set it to [] because that means default setting is used. However, we are explicitly hiding this!
+ $(hiddenSel).attr('disabled',false);
+ }
+ if(tdbIsSubtrack(tdb))
+ $(hiddenVis).val("[]");
+ else
+ $(hiddenVis).val("hide");
+ }
+ $(hiddenVis).attr('disabled',false);
+
+ $('input.viewBtn').val('View in Browser');
+ //warn("Changed "+trackName+" to "+$(hiddenVis).val())
+}
+
+function findTracksClickedOne(selCb,justClicked)
+{ // called by on click of CB and findTracksCheckAll()
+ var selName = $(selCb).attr('id');
+ var trackName = selName.substring(0,selName.length - "_sel_id".length)
+ var hiddenSel = $("input[name='"+trackName+"_sel']");
+ var seenVis = $('select#' + trackName + "_id");
+ var hiddenVis = $("input[name='"+trackName+"']");
+ var tr = $(selCb).parents('tr.found');
+ var tdb = tdbGetJsonRecord(trackName);
+ var needSel = (tdb.parentTrack != undefined);
+ var shouldPack = tdb.canPack && tdb.kindOfParent == 0; // If parent then not pack but full
+ if (shouldPack && tdb.shouldPack != undefined && !tdb.shouldPack)
+ shouldPack = false;
+ var checked = $(selCb).attr('checked');
+ //warn(trackName +" selName:"+selName +" justClicked:"+justClicked +" hiddenSel:"+$(hiddenSel).attr('name') +" seenVis:"+$(seenVis).attr('id') +" hiddenVis:"+$(hiddenVis).attr('name') +" needSel:"+needSel +" shouldPack:"+shouldPack);
+
+ // First deal with seenVis control
+ if(checked) {
+ $(seenVis).attr('disabled', false);
+ if($(seenVis).attr('selectedIndex') == 0) {
+ if(shouldPack)
+ $(seenVis).attr('selectedIndex',3); // packed
+ else
+ $(seenVis).attr('selectedIndex',$(seenVis).attr('length') - 1);
+ }
+ } else {
+ $(seenVis).attr('selectedIndex',0); // hide
+ $(seenVis).attr('disabled', true );
+ }
+
+ // Deal with hiddenSel and hiddenVis so that submit does the right thing
+ // Setting these requires justClicked OR seen vs. hidden to be different
+ var setHiddenInputs = justClicked;
+ if(!justClicked) {
+ if(needSel)
+ setHiddenInputs = (checked != ($(hiddenSel).val() == '1'));
+ else if (checked)
+ setHiddenInputs = ($(seenVis).val() != $(hiddenVis).val());
+ else
+ setHiddenInputs = ($(hiddenVis).val() != "hide" && $(hiddenVis).val() != "[]");
+ }
+ if(setHiddenInputs) {
+ if(checked)
+ $(hiddenVis).val($(seenVis).val());
+ else if(tdbIsSubtrack(tdb))
+ $(hiddenVis).val("[]");
+ else
+ $(hiddenVis).val("hide");
+ $(hiddenVis).attr('disabled',false);
+
+ if(needSel) {
+ if(checked)
+ $(hiddenSel).val('1');
+ else
+ $(hiddenSel).val('0'); // Can't set it to [] because that means default setting is used. However, we are explicitly hiding this!
+ $(hiddenSel).attr('disabled',false);
+ }
+ }
+
+ // The "view in browser" button should be enabled/disabled
+ if(justClicked) {
+ $('input.viewBtn').val('View in Browser');
+ findTracksCounts();
+ }
+}
+
+
+function findTracksNormalize()
+{ // Normalize the page based upon current state of all found tracks
+ $('div#found').show()
+ var selCbs = $('input.selCb');
+
+ // All should have their vis enabled/disabled appropriately (false means don't update cart)
+ $(selCbs).each( function(i) { findTracksClickedOne(this,false); });
+
+ findTracksCounts();
+}
+
+function findTracksNormalizeWaitOn()
+{ // Put up wait mask then Normalize the page based upon current state of all found tracks
+ waitOnFunction( findTracksNormalize );
+}
+
+function findTracksCheckAll(check)
+{ // Checks/unchecks all found tracks.
+ var selCbs = $('input.selCb');
+ $(selCbs).attr('checked',check);
+
+ // All should have their vis enabled/disabled appropriately (false means don't update cart)
+ $(selCbs).each( function(i) { findTracksClickedOne(this,false); });
+
+ $('input.viewBtn').val('View in Browser');
+ findTracksCounts();
+ return false; // Pressing button does nothing more
+}
+
+function findTracksCheckAllWithWait(check)
+{
+ waitOnFunction( findTracksCheckAll, check);
+}
+
+function findTracksSearchButtonsEnable(enable)
+{ // Displays visible and checked track count
+ var searchButton = $('input[name="hgt_tSearch"]'); // NOTE: must match TRACK_SEARCH in hg/inc/searchTracks.h
+ var clearButton = $('input.clear');
+ if(enable) {
+ $(searchButton).attr('disabled',false);
+ $(clearButton).attr('disabled',false);
+ } 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
+ 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.filterBy').each( function(i) { // Do this by 'each' to set noneIsAll individually
+ //$(this).dropdownchecklist("refresh"); // requires v1.1
+ $(this).dropdownchecklist("destroy");
+ $(this).dropdownchecklist({ firstItemChecksAll: true, noneIsAll: true });
+ });
+
+ $('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("");
+ else
+ $('#sortIt').val($(obj).val());
+
+ // How to hold onto selected tracks?
+ // There are 2 separate forms. Scrape named inputs from searchResults form and dup them on trackSearch?
+ var inp = $('form#searchResults').find('input:hidden').not(':disabled').not("[name='hgsid']");
+ if($(inp).length > 0) {
+ $(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 true;
+}
+
+function findTracksPage(pageVar,startAt)
+{// Called by radio button to sort tracks
+ var pager = $("input[name='"+pageVar+"']");
+ if( $(pager).length == 1)
+ $(pager).val(startAt);
+
+ // How to hold onto selected tracks?
+ // There are 2 separate forms. Scrape named inputs from searchResults form and dup them on trackSearch?
+ var inp = $('form#searchResults').find('input:hidden').not(':disabled').not("[name='hgsid']");
+ if($(inp).length > 0) {
+ $(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 ], [ "[]","[]" ] );
+ }
+
+ findTracksClearFound(); // Changing values so abandon what has been found
+ return false;
+ }
+ }
+ 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("");
+ 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();
+ }
+}
+