7dffd035095eda20f701c3342489b7efbae806fc larrym Wed Oct 20 09:59:37 2010 -0700 fix getAllVars to handle radio buttons diff --git src/hg/js/utils.js src/hg/js/utils.js index d804eeb..d0520d8 100644 --- src/hg/js/utils.js +++ src/hg/js/utils.js @@ -1,960 +1,964 @@ // Utility JavaScript // $Header: /projects/compbio/cvsroot/kent/src/hg/js/utils.js,v 1.31 2010/06/02 19:11:53 tdreszer Exp $ var debug = false; function clickIt(obj,state,force) { // calls click() for an object, and click();click() if force if(obj.checked != state) { obj.click(); } else if (force) { obj.click(); obj.click(); //force onclick event } } function setCheckBoxesWithPrefix(obj, prefix, state) { // Set all checkboxes with given prefix to state boolean var list = inputArrayThatMatches("checkbox","id",prefix,""); for (var i=0;i<list.length;i++) { var ele = list[i]; if(ele.checked != state) ele.click(); // Forces onclick() javascript to run } } function setCheckBoxesThatContain(nameOrId, state, force, sub1) { // Set all checkboxes which contain 1 or more given substrings in NAME or ID to state boolean // First substring: must begin with it; 2 subs: beg and end; 3: begin, middle and end. // This can force the 'onclick() js of the checkbox, even if it is already in the state if(debug) alert("setCheckBoxesContains is about to set the checkBoxes to "+state); var list; if(arguments.length == 4) list = inputArrayThatMatches("checkbox",nameOrId,sub1,""); else if(arguments.length == 5) list = inputArrayThatMatches("checkbox",nameOrId,sub1,arguments[4]); else if(arguments.length == 6) list = inputArrayThatMatches("checkbox",nameOrId,sub1,arguments[4],arguments[5]); for (var ix=0;ix<list.length;ix++) { clickIt(list[ix],state,force); } return true; } function inputArrayThatMatches(inpType,nameOrId,prefix,suffix) { // returns an array of input controls that match the criteria var found = new Array(); var fIx = 0; if (document.getElementsByTagName) { var list; if(inpType == 'select') list = document.getElementsByTagName('select'); else list = document.getElementsByTagName('input'); for (var ix=0;ix<list.length;ix++) { var ele = list[ix]; if(inpType.length > 0 && inpType != 'select' && ele.type != inpType) continue; var identifier = ele.name; if(nameOrId.search(/id/i) != -1) identifier = ele.id; var failed = false; if(prefix.length > 0) failed = (identifier.indexOf(prefix) != 0) if(!failed && suffix.length > 0) failed = (identifier.lastIndexOf(suffix) != (identifier.length - suffix.length)) if(!failed) { for(var aIx=4;aIx<arguments.length;aIx++) { if(identifier.indexOf(arguments[aIx]) == -1) { failed = true; break; } } } if(!failed) { found[fIx] = ele; fIx++; } } } else { // NS 4.x - I gave up trying to get this to work. if(debugLevel>2) alert("arrayOfInputsThatMatch is unimplemented for this browser"); } return found; } function showSubTrackCheckBoxes(onlySelected) { // If a Subtrack configuration page has show "only selected subtracks" option, // This can show/hide tablerows that contain the checkboxes // Containing <tr>'s must be id'd with 'tr_' + the checkbox id, // while checkbox id must have 'cb_' prefix (ie: 'tr_cb_checkThis' & 'cb_checkThis') if (document.getElementsByTagName) { var list = document.getElementsByTagName('tr'); for (var ix=0;ix<list.length;ix++) { var tblRow = list[ix]; if(tblRow.id.indexOf("tr_cb_") >= 0) { // marked as tr containing a cb if(!onlySelected) { tblRow.style.display = ''; //'table-row' doesn't work in some browsers (ie: IE) } else { var associated_cb = tblRow.id.substring(3,tblRow.id.length); chkBox = document.getElementById(associated_cb); if(chkBox!=undefined && chkBox.checked && chkBox.disabled == false) tblRow.style.display = ''; else tblRow.style.display = 'none'; // hides } } } } else if (document.all) { if(debug) alert("showSubTrackCheckBoxes is unimplemented for this browser"); } else { // NS 4.x - I gave up trying to get this to work. if(debug) alert("showSubTrackCheckBoxes is unimplemented for this browser"); } } function hideOrShowSubtrack(obj) { // This can show/hide a tablerow that contains a specific object // Containing <tr>'s must be id'd with 'tr_' + obj.id // Also, this relies upon the "displaySubtracks" radio button control var tblRow = document.getElementById("tr_"+obj.id); if(!obj.checked || obj.disabled) { var list = document.getElementsByName("displaySubtracks"); for (var ix=0;ix<list.length;ix++) { if(list[ix].value == "selected") { if(list[ix].checked) tblRow.style.display = 'none'; // hides else tblRow.style.display = ''; //'table-row' doesn't work in some browsers (ie: IE) break; } } } else tblRow.style.display = ''; } function waitCursor(obj) { //document.body.style.cursor="wait" obj.style.cursor="wait"; } function endWaitCursor(obj) { obj.style.cursor=""; } function getURLParam() { // Retrieve variable value from an url. // Can be called either: // getURLParam(url, name) // or: // getURLParam(name) // Second interface will default to using window.location.href var strHref, strParamName; var strReturn = ""; if(arguments.length == 1) { strHref = window.location.href; strParamName = arguments[0]; } else { strHref = arguments[0]; strParamName = arguments[1]; } if ( strHref.indexOf("?") > -1 ){ var strQueryString = strHref.substr(strHref.indexOf("?")).toLowerCase(); var aQueryString = strQueryString.split("&"); for ( var iParam = 0; iParam < aQueryString.length; iParam++ ){ if (aQueryString[iParam].indexOf(strParamName.toLowerCase() + "=") > -1 ){ var aParam = aQueryString[iParam].split("="); strReturn = aParam[1]; break; } } } return unescape(strReturn); } function makeHiddenInput(theForm,aName,aValue) { // Create a hidden input to hold a value $(theForm).find("input:last").after("<input type=hidden name='"+aName+"' value='"+aValue+"'>"); } function updateOrMakeNamedVariable(theForm,aName,aValue) { // Store a value to a named input. Will make the input if necessary var inp = $(theForm).find("input[name='"+aName+"']:last"); if(inp != undefined && inp.length > 0) { inp.val(aValue); inp.disabled = false; } else makeHiddenInput(theForm,aName,aValue); } function disableNamedVariable(theForm,aName) { // Store a value to a named input. Will make the input if necessary var inp = $(theForm).find("input[name='"+aName+"']:last"); if(inp != undefined && inp.length > 0) inp.disabled = true; } function parseUrlAndUpdateVars(theForm,href) { // Parses the URL and converts GET vals to POST vals var url = href; var extraIx = url.indexOf("?"); if(extraIx > 0) { var extra = url.substring(extraIx+1); url = url.substring(0,extraIx); // now extra must be repeatedly broken into name=var extraIx = extra.indexOf("="); for(;extraIx > 0;extraIx = extra.indexOf("=")) { var aValue; var aName = extra.substring(0,extraIx); var endIx = extra.indexOf("&"); if( endIx>0) { aValue = extra.substring(extraIx+1,endIx); extra = extra.substring(endIx+1); } else { aValue = extra.substring(extraIx+1); extra = ""; } if(aName.length>0 && aValue.length>0) updateOrMakeNamedVariable(theForm,aName,aValue); } } return url; } function postTheForm(formName,href) { // posts the form with a passed in href var goodForm=$("form[name='"+formName+"']"); if(goodForm.length == 1) { if(href != undefined && href.length > 0) { $(goodForm).attr('action',href); // just attach the straight href } $(goodForm).attr('method','POST'); $(goodForm).submit(); } return false; // Meaning do not continue with anything else } function setVarAndPostForm(aName,aValue,formName) { // Sets a specific variable then posts var goodForm=$("form[name='"+formName+"']"); if(goodForm.length == 1) { updateOrMakeNamedVariable(goodForm,aName,aValue); } return postTheForm(formName,window.location.href); } // json help routines function tdbGetJsonRecord(trackName) { return trackDbJson[trackName]; } function tdbIsFolder(tdb) { return (tdb.kindOfParent == 1); } // NOTE: These must jive with tdbKindOfParent() and tdbKindOfChild() in trackDb.h function tdbIsComposite(tdb) { return (tdb.kindOfParent == 2); } function tdbIsMultiTrack(tdb) { return (tdb.kindOfParent == 3); } function tdbIsView(tdb) { return (tdb.kindOfParent == 4); } // Don't expect to use function tdbIsContainer(tdb) { return (tdb.kindOfParent == 2 || tdb.kindOfParent == 3); } function tdbIsLeaf(tdb) { return (tdb.kindOfParent == 0); } function tdbIsFolderContent(tdb) { return (tdb.kindOfChild == 1); } function tdbIsCompositeSubtrack(tdb) { return (tdb.kindOfChild == 2); } function tdbIsMultiTrackSubtrack(tdb) { return (tdb.kindOfChild == 3); } function tdbIsSubtrack(tdb) { return (tdb.kindOfChild == 2 || tdb.kindOfChild == 3); } function tdbHasParent(tdb) { return (tdb.kindOfChild != 0 && tdb.parentTrack); } function aryFind(ary,val) {// returns the index of a value on the array or -1; for(var ix=0;ix<ary.length;ix++) { if(ary[ix] == val) { return ix; } } return -1; } function aryRemoveVals(ary,vals) { // removes one or more variables that are found in the array for(var vIx=0;vIx<vals.length;vIx++) { var ix = aryFind(ary,vals[vIx]); if(ix != -1) ary.splice(ix,1); } return ary; } function aryRemove(ary,val) { // removes one or more variables that are found in the array for(var vIx=1;vIx<arguments.length;vIx++) { var ix = aryFind(ary,arguments[vIx]); if(ix != -1) ary.splice(ix,1); } return ary; } function isInteger(s) { return (!isNaN(parseInt(s)) && isFinite(s) && s.toString().indexOf('.') < 0); } function isFloat(s) { return (!isNaN(parseFloat(s)) && isFinite(s)); } function validateInt(obj,min,max) { // validates an integer which may be restricted to a range (if min and/or max are numbers) var title = obj.title; var rangeMin=parseInt(min); var rangeMax=parseInt(max); if(title.length == 0) title = "Value"; var popup=( $.browser.msie == false ); for(;;) { if((obj.value == undefined || obj.value == "") && isInteger(obj.defaultValue)) obj.value = obj.defaultValue; if(!isInteger(obj.value)) { if(popup) { obj.value = prompt(title +" is invalid.\nMust be an integer.",obj.value); continue; } else { alert(title +" of '"+obj.value +"' is invalid.\nMust be an integer."); // try a prompt box! obj.value = obj.defaultValue; return false; } } var val = parseInt(obj.value); if(isInteger(min) && isInteger(max)) { if(val < rangeMin || val > rangeMax) { if(popup) { obj.value = prompt(title +" is invalid.\nMust be between "+rangeMin+" and "+rangeMax+".",obj.value); continue; } else { alert(title +" of '"+obj.value +"' is invalid.\nMust be between "+rangeMin+" and "+rangeMax+"."); obj.value = obj.defaultValue; return false; } } } else if(isInteger(min)) { if(val < rangeMin) { if(popup) { obj.value = prompt(title +" is invalid.\nMust be no less than "+rangeMin+".",obj.value); continue; } else { alert(title +" of '"+obj.value +"' is invalid.\nMust be no less than "+rangeMin+"."); obj.value = obj.defaultValue; return false; } } } else if(isInteger(max)) { if(val > rangeMax) { if(popup) { obj.value = prompt(title +" is invalid.\nMust be no greater than "+rangeMax+".",obj.value); continue; } else { alert(title +" of '"+obj.value +"' is invalid.\nMust be no greater than "+rangeMax+"."); obj.value = obj.defaultValue; return false; } } } return true; } } function validateFloat(obj,min,max) { // validates an float which may be restricted to a range (if min and/or max are numbers) var title = obj.title; var rangeMin=parseFloat(min); var rangeMax=parseFloat(max); if(title.length == 0) title = "Value"; var popup=( $.browser.msie == false ); for(;;) { if((obj.value == undefined || obj.value == "") && isFloat(obj.defaultValue)) obj.value = obj.defaultValue; if(!isFloat(obj.value)) { if(popup) { obj.value = prompt(title +" is invalid.\nMust be a number.",obj.value); continue; } else { alert(title +" of '"+obj.value +"' is invalid.\nMust be a number."); // try a prompt box! obj.value = obj.defaultValue; return false; } } var val = parseFloat(obj.value); if(isFloat(min) && isFloat(max)) { if(val < rangeMin || val > rangeMax) { if(popup) { obj.value = prompt(title +" is invalid.\nMust be between "+rangeMin+" and "+rangeMax+".",obj.value); continue; } else { alert(title +" of '"+obj.value +"' is invalid.\nMust be between "+rangeMin+" and "+rangeMax+"."); obj.value = obj.defaultValue; return false; } } } else if(isFloat(min)) { if(val < rangeMin) { if(popup) { obj.value = prompt(title +" is invalid.\nMust be no less than "+rangeMin+".",obj.value); continue; } else { alert(title +" of '"+obj.value +"' is invalid.\nMust be no less than "+rangeMin+"."); obj.value = obj.defaultValue; return false; } } } else if(isFloat(max)) { if(val > rangeMax) { if(popup) { obj.value = prompt(title +" is invalid.\nMust be no greater than "+rangeMax+".",obj.value); continue; } else { alert(title +" of '"+obj.value +"' is invalid.\nMust be no greater than "+rangeMax+"."); obj.value = obj.defaultValue; return false; } } } return true; } } function metadataShowHide(tableName,showLonglabel,showShortLabel) { // Will show subtrack specific configuration controls // Config controls not matching name will be hidden var divit = $("#div_"+tableName+"_meta"); if($(divit).css('display') == 'none') { $("#div_"+tableName+"_cfg").hide(); // Hide any configuration when opening metadata if($(divit).find('table').length == 0) { lookupMetadata(tableName,showLonglabel,showShortLabel); } } $(divit).toggle(); // jQuery hide/show return false; } function warnBoxJsSetup() { // Sets up warnBox if not already established. This is duplicated from htmshell.c var html = ""; html += "<center>"; html += "<div id='warnBox' style='display:none; background-color:Beige; "; html += "border: 3px ridge DarkRed; width:640px; padding:10px; margin:10px; "; html += "text-align:left;'>"; html += "<CENTER><B id='warnHead' style='color:DarkRed;'></B></CENTER>"; html += "<UL id='warnList'></UL>"; html += "<CENTER><button id='warnOK' onclick='hideWarnBox();return false;'></button></CENTER>"; html += "</div></center>"; html += "<script type='text/javascript'>"; html += "function showWarnBox() {"; html += "document.getElementById('warnOK').innerHTML=' OK ';"; html += "var warnBox=document.getElementById('warnBox');"; html += "warnBox.style.display=''; warnBox.style.width='65%%';"; html += "document.getElementById('warnHead').innerHTML='Error(s):';"; html += "}"; html += "function hideWarnBox() {"; html += "var warnBox=document.getElementById('warnBox');"; html += "warnBox.style.display='none';warnBox.innerHTML='';"; html += "var endOfPage = document.body.innerHTML.substr(document.body.innerHTML.length-20);"; html += "if(endOfPage.lastIndexOf('-- ERROR --') > 0) { history.back(); }"; html += "}"; html += "</script>"; $('body').prepend(html); } function warn(msg) { // adds warnings to the warnBox var warnList = $('#warnList'); // warnBox contains warnList if( warnList == undefined || $(warnList).length == 0 ) { warnBoxJsSetup(); warnList = $('#warnList'); } if( $(warnList).length == 0 ) alert(msg); else { $( warnList ).append('<li>'+msg+'</li>'); if(showWarnBox != undefined) showWarnBox(); else alert(msg); } } function cgiBooleanShadowPrefix() // Prefix for shadow variable set with boolean variables. // Exact copy of code in cheapcgi.c { return "boolshad."; } function getAllVars(obj,subtrackName) { // Returns a hash for all inputs and selects in an obj. // If obj is undefined then obj is document! var urlData = new Object(); if($(obj) == undefined) obj = $('document'); var inp = $(obj).find('input'); var sel = $(obj).find('select'); //warn("obj:"+$(obj).attr('id') + " inputs:"+$(inp).length+ " selects:"+$(sel).length); $(inp).filter('[name]:enabled').each(function (i) { var name = $(this).attr('name'); var val = $(this).val(); if($(this).attr('type') == 'checkbox') { name = cgiBooleanShadowPrefix() + name; val = $(this).attr('checked') ? 1 : 0; + } else if($(this).attr('type') == 'radio') { + if(!$(this).attr('checked')) { + name = undefined; + } } if(name != undefined && name != "Submit" && val != undefined) { urlData[name] = val; } }); $(sel).filter('[name]:enabled').each(function (i) { var name = $(this).attr('name'); var val = $(this).val(); if(name != undefined && val != undefined) { if(subtrackName != undefined && name == subtrackName) { if(val == 'hide') { urlData[name+"_sel"] = 0; // Can't delete "_sel" because default takes over urlData[name] = "[]"; // can delete vis because subtrack vis should be inherited. } else { urlData[name+"_sel"] = 1; urlData[name] = val; } } else urlData[name] = val; } }); return urlData; } function setIdRemoveName(obj) { // This function removes the name of an obj and sets it as the id. This is very useful // to override forms submitting named inputs and instead setCartVarFromObjId() can be used selectively var id = $(obj).attr('name'); if(id != undefined) { $(obj).attr('id',id); $(obj).removeAttr('name'); } //warn($(obj).attr('id')+'='+$(obj).val()+" name:"+$(obj).attr('name')); } function varHashChanges(newVars,oldVars) { // Returns a hash of all vars that are changed between old and new hash. New vars not found in old are changed. var changedVars = new Object(); for (var newVar in newVars) { if(oldVars[newVar] == null || oldVars[newVar] != newVars[newVar]) changedVars[newVar] = newVars[newVar]; } return changedVars; } function varHashToQueryString(varHash) { // return a CGI QUERY_STRING for name/vals in given object var retVal = ""; var count = 0; for (var aVar in varHash) { if(count++ > 0) { retVal += "&"; } // XXXX encode var=val ? retVal += aVar + "=" + varHash[aVar]; } return retVal; } function getAllVarsAsUrlData(obj) { // Returns a string in the form of var1=val1&var2=val2... for all inputs and selects in an obj // If obj is undefined then obj is document! return varHashToQueryString(getAllVars(obj)); } /* function popupBox(popit, content, popTitle) { // Kicks off a Modal Dialog for the provided content. // Requires jquery-ui.js // NEEDS SOME WORK warn(content); // Set up the popit div if necessary if(popit == undefined) { popit = $('#popit'); if(popit == undefined) { $('body').prepend("<div id='popit' style='display: none'></div>"); popit = $('#popit'); } } // Set up the modal dialog $(popit).html("<div style='font-size:80%'>" + content + "</div>"); $(popit).dialog({ ajaxOptions: { // This doesn't work cache: true }, resizable: true, bgiframe: true, height: 'auto', width: 'auto', minHeight: 200, minWidth: 400, modal: true, closeOnEscape: true, autoOpen: false, close: function() { // clear out html after close to prevent problems caused by duplicate html elements $(popDiv).empty(); } }); // Apparently the options above to dialog take only once, so we set title explicitly. if(popTitle != undefined && popTitle.length > 0) $(popit).dialog('option' , 'title' , popTitle ); else $(popit).dialog('option' , 'title' , "Please Respond"); jQuery('body').css('cursor', ''); $(popit).dialog('open'); } */ function embedBoxOpen(boxit, content, reenterable) // 4 extra STRING Params: boxWidth, boxTitle, applyFunc, applyName { // embeds a box for the provided content. // This box has 1 button (close) by default and 2 buttons if the name of an applyFunc is provided (apply, cancel) // If there is no apply function, the box may be reentrent, meaning subsequent calls do not need to provide content // Define extra params now var boxWidth = "80%"; var boxTitle = ""; var applyFunc = ""; var applyName = "Apply"; if (arguments.length > 3 && arguments[3].length > 0) // FIXME: could check type boxWidth = arguments[3]; if (arguments.length > 4 && arguments[4].length > 0) boxTitle = arguments[4]; if (arguments.length > 5 && arguments[5].length > 0) applyFunc = arguments[5]; if (arguments.length > 6 && arguments[6].length > 0) applyName = arguments[6]; // Set up the popit div if necessary if (boxit == undefined) { boxit = $('div#boxit'); if (boxit == undefined) { $('body').prepend("<div id='boxit'></div>"); //$('body').prepend("<div id='boxit' style='display: none'></div>"); boxit = $('div#boxit'); } } if (!reenterable || (content.length > 0)) { // Can reenter without changing content! var buildHtml = "<center>"; if (boxTitle.length > 0) buildHtml += "<div style='background-color:#D9E4F8;'><B>" + boxTitle + "</B></div>"; buildHtml += "<div>" + content + "</div>"; // Set up closing code var closeButton = "Close"; var closeHtml = "embedBoxClose($(\"#"+ $(boxit).attr('id') + "\"),"; if (reenterable && applyFunc.length == 0) closeHtml += "true);" else closeHtml += "false);"; // Buttons buildHtml += "<div>"; if (applyFunc.length > 0) { // "Apply" button and "Cancel" button. Apply also closes! buildHtml += " <INPUT TYPE='button' value='" + applyName + "' onClick='"+ applyFunc + "(" + $(boxit).attr('id') + "); " + closeHtml + "'> "; closeButton = "Cancel"; // If apply button then close is cancel } buildHtml += " <INPUT TYPE='button' value='" + closeButton + "' onClick='" + closeHtml + "'> "; buildHtml += "</div>"; $(boxit).html("<div class='blueBox' style='width:" + boxWidth + "; background-color:#FFF9D2;'>" + buildHtml + "</div>"); // Make it boxed } if ($(boxit).html() == null || $(boxit).html().length == 0) warn("embedHtmlBox() called without content"); else $(boxit).show(); } function embedBoxClose(boxit, reenterable) // 4 extra STRING Params: boxWidth, boxTitle, applyFunc, applyName { // Close an embedded box if (boxit != undefined) { $(boxit).hide(); if(!reenterable) $(boxit).empty(); } } function startTiming() { var now = new Date(); return now.getTime(); } function showTiming(start,whatTookSoLong) { var now = new Date(); var end = (now.getTime() - start); warn(whatTookSoLong+" took "+end+" msecs."); return end; } function getHgsid() { // return current session id var hgsid; var list = document.getElementsByName("hgsid"); if(list.length) { var ele = list[0]; hgsid = ele.value; } if(!hgsid) { hgsid = getURLParam(window.location.href, "hgsid"); } return hgsid; } function getDb() { var db = document.getElementsByName("db"); if(db == undefined || db.length == 0) { db = $("#db"); if(db == undefined || db.length == 0) return ""; // default? } return db[0].value; } function getTrack() { var track = $("#track"); if(track == undefined || track.length == 0) return ""; // default? return track[0].value; } function Rectangle() { // Rectangle object constructor: // calling syntax: // // new Rectangle(startX, endX, startY, endY) // new Rectangle(coords) <-- coordinate string from an area item if(arguments.length == 4) { this.startX = arguments[0]; this.endX = arguments[1]; this.startY = arguments[2]; this.endY = arguments[3]; } else if(arguments.length > 0) { var coords = arguments[0].split(","); this.startX = coords[0]; this.endX = coords[2]; this.startY = coords[1]; this.endY = coords[3]; } else { // what else to do? this.startX = 0; this.endX = 100; this.startY = 0; this.endY = 100; } } Rectangle.prototype.contains = function(x, y) { // returns true if given points are in the rectangle var retval = x >= this.startX && x <= this.endX && y >= this.startY && y <= this.endY; return retval; } function commify (str) { if(typeof(str) == "number") str = str + ""; var n = str.length; if (n <= 3) { return str; } else { var pre = str.substring(0, n-3); var post = str.substring(n-3); var pre = commify(pre); return pre + "," + post; } } function parsePosition(position) { // Parse chr:start-end string into a chrom, start, end object position = position.replace(/,/g, ""); var a = /(\S+):(\d+)-(\d+)/.exec(position); if(a != null && a.length == 4) { var o = new Object(); o.chrom = a[1]; o.start = parseInt(a[2]) o.end = parseInt(a[3]); return o; } return null; } function getSizeFromCoordinates(position) { // Parse size out of a chr:start-end string var o = parsePosition(position); if(o != null) { return o.end - o.start + 1; } return null; } // This code is intended to allow setting up a wait cursor while waiting on the function var gWaitFuncArgs = []; var gWaitFunc; function waitMaskClear() { // Clears the waitMask var waitMask = $('#waitMask'); if( waitMask != undefined ) $(waitMask).hide(); } function waitMaskSetup(timeOutInMs) { // Sets up the waitMask to block page manipulation until cleared // Find or create the waitMask (which masks the whole page) var waitMask = $('#waitMask'); if( waitMask == undefined || waitMask.length != 1) { // create the waitMask $("body").append("<div id='waitMask' class='waitMask');'></div>"); waitMask = $('#waitMask'); // Special for IE if ($.browser.msie) $(waitMask).css('filter','alpha(opacity= 0)'); } $(waitMask).css('display','block'); // Things could fail, so always have a timeout. if(timeOutInMs == undefined || timeOutInMs <=0) timeOutInMs = 5000; // Don't ever leave this as infinite setTimeout('waitMaskClear();',timeOutInMs); // Just in case } function _launchWaitOnFunction() { // should ONLY be called by waitOnFunction() // Launches the saved function var func = gWaitFunc; gWaitFunc = null; var funcArgs = gWaitFuncArgs; gWaitFuncArgs = []; if(func == undefined || !jQuery.isFunction(func)) warn("_launchWaitOnFunction called without a function"); else { if(funcArgs.length == 0) func(); else if (funcArgs.length == 1) func(funcArgs[0]); else if (funcArgs.length == 2) func(funcArgs[0],funcArgs[1]); else if (funcArgs.length == 3) func(funcArgs[0],funcArgs[1],funcArgs[2]); else if (funcArgs.length == 4) func(funcArgs[0],funcArgs[1],funcArgs[2],funcArgs[3]); else if (funcArgs.length == 5) func(funcArgs[0],funcArgs[1],funcArgs[2],funcArgs[3],funcArgs[4]); else warn("_launchWaitOnFunction called with " + funcArgs.length + " arguments. Only 5 are supported."); } // Special if the first var is a button that can visually be inset if(funcArgs.length > 0 && funcArgs[0].type != undefined) { if(funcArgs[0].type == 'button' && $(funcArgs[0]).hasClass('inOutButton')) { $(funcArgs[0]).css('borderStyle',"outset"); } } // Now we can get rid of the wait cursor waitMaskClear(); } function waitOnFunction(func) { // sets the waitMask (wait cursor and no clicking), then launches the function with up to 5 arguments if(!jQuery.isFunction(func)) { warn("waitOnFunction called without a function"); return false; } if(arguments.length > 6) { warn("waitOnFunction called with " + arguments.length - 1 + " arguments. Only 5 are supported."); return false; } waitMaskSetup(5000); // Find or create the waitMask (which masks the whole page) but gives up after 5sec // Special if the first var is a button that can visually be inset if(arguments.length > 1 && arguments[1].type != undefined) { if(arguments[1].type == 'button' && $(arguments[1]).hasClass('inOutButton')) { $(arguments[1]).css( 'borderStyle',"inset"); } } // Build up the aruments array for(var aIx=1;aIx<arguments.length;aIx++) { gWaitFuncArgs.push(arguments[aIx]) } gWaitFunc = func; setTimeout('_launchWaitOnFunction();',50); } function showLoadingImage(id) { // Show a loading image above the given id; return's id of div added (so it can be removed when loading is finished). // This code was mostly directly copied from hgHeatmap.js, except I also added the "overlay.appendTo("body");" var loadingId = id + "LoadingOverlay"; var overlay = $("<div></div>").attr("id", loadingId).css("position", "absolute"); overlay.appendTo("body"); overlay.css("top", $('#'+ id).position().top); var divLeft = $('#'+ id).position().left + 2; overlay.css("left",divLeft); var width = $('#'+ id).width() - 5; var height = $('#'+ id).height(); overlay.width(width); overlay.height(height); overlay.css("background", "white"); overlay.css("opacity", 0.75); var imgLeft = (width / 2) - 110; var imgTop = (height / 2 ) - 10; $("<img src='../images/loading.gif'/>").css("position", "relative").css('left', imgLeft).css('top', imgTop).appendTo(overlay); return loadingId; } function hideLoadingImage(id) { $('#' + id).remove(); }