//All Javascript function gaevt(Category,Action,Label,Value) { //console.log("gaevt: "+Category+":"+Action+":"+Label+":"+Value); if (typeof ga==="function") { try { var iValue=0; if(Value) iValue=Value; //replace commas var sCategory=replaceAllSubstrings(Category,","," "); var sAction=replaceAllSubstrings(Action,","," "); sAction=replaceAllSubstrings(sAction,"\x27"," "); sAction=replaceAllSubstrings(sAction,"\x22"," "); var sLabel=replaceAllSubstrings(Label,","," "); sLabel=replaceAllSubstrings(sLabel,"\x27"," "); sLabel=replaceAllSubstrings(sLabel,"\x22"," "); var sFunc="ga('send','event','"+sCategory+"','"+sAction+"','"+sLabel+"','"+iValue+"')"; //appendToLog(sFunc); setTimeout(sFunc,100); } catch(e) { appendToLog("Error in gaevt: "+e.message); }; } else { appendToLog("Error in gaevt: ga is undefined"); }; }; function initVideoListeners(eVideo) { eVideo.addEventListener('ended', videoEnd, false) eVideo.addEventListener('timeupdate', videoTimeUpdate, false) eVideo.addEventListener('play', videoPlay, false) eVideo.addEventListener('pause', videoPause, false) } function getVideoTitle(e) { var s=e.getAttribute("title"); if(s) return(s); return("Untitled"); }; function getVideoID(e) { var s=e.getAttribute("VideoID"); if(s) return(s); return("Undefined"); }; function setKeyFrames(duration) { var quarter=(duration / 4).toFixed(1) sessionStorage.setItem('one', quarter) sessionStorage.setItem('two', (quarter * 2).toFixed(1)) sessionStorage.setItem('three', (quarter * 3).toFixed(1)) } function videoTimeUpdate() { var curTime=this.currentTime.toFixed(1) switch (curTime) { case sessionStorage.getItem('one'): gaevt('video','25% played',getVideoID(this)+"|"+getVideoTitle(this)); sessionStorage.setItem('one', null); break; case sessionStorage.getItem('two'): gaevt('video','50% played',getVideoID(this)+"|"+getVideoTitle(this)); sessionStorage.setItem('two', null); break; case sessionStorage.getItem('three'): gaevt('video','75% played',getVideoID(this)+"|"+getVideoTitle(this)); sessionStorage.setItem('three', null); break; } } function videoEnd() { gaevt('video','100% played',getVideoID(this)+"|"+getVideoTitle(this)); } function videoPlay() { gaevt('video','play',getVideoID(this)+"|"+getVideoTitle(this)); setKeyFrames(this.duration) } function videoPause() { gaevt('video','pause',getVideoID(this)+"|"+getVideoTitle(this)); } /****************************************************************** Closed the select file dialog by removing the div containing the dialog. The additional div created by the selectFile() function is also removed, so the cleanup is complete. ******************************************************************/ function closeSelectFileDialog(salt,fnCancel) { var e=document.getElementById(salt+"SelectFile"); appendToLog("e.id="+e.id); eParent=e.parentNode; eParent.removeChild(e); if(eParent.getAttribute("removeme")) { eParent.parentNode.removeChild(eParent); }; if(fnCancel) eval(fnCancel+"('"+salt+"')"); }; /****************************************************************** Called when the user clicks the select button in the dialog used to select a file or directory ******************************************************************/ function fileSelected(salt,fnOk) { var sFilename=document.getElementById(salt+"SelectFileFileSpec").value; closeSelectFileDialog(salt); sFilename=replaceAllSubstrings(sFilename,"\\","\\\\"); if(fnOk) eval(fnOk+"('"+salt+"','"+sFilename+"')"); }; /****************************************************************** Displays a dialog used to select a file or directory. Params: Salt - An identifier that is included with the filename when a selection has been made. The function called is fnOk(Salt,Filename) e - An element beneath which the dialog will be displayed. If null, the dialog is centered and 100px down from the top of the page Filespec - The default filename or directory Select - Either File or Directory Exists - If true, the user must select from a list of files and directories. If false, the user may type a name, including the name of a file or directory that does not exist. fnOk - Name of a javascript function that will be called when the user makes a selection. This is only the function name. The function will be called using fnOK(Filespec) fnCancel - Name of a javascript function to be called if the user closes the dialog without making a selection. Center - If true, the dialog will be centered horizontally Top - Top position offset Left - Left position offset. The value "center" can be used to center the dialog horizontally. Source - HashID of the computer used to process the request ******************************************************************/ function selectFile(Salt,Filespec,Select,Exists,fnOk,fnCancel,Top,Left,Source) { var eDiv=document.createElement("div"); eDiv.id="selectFile"+getSalt(4); eDiv.setAttribute("RemoveMe","true"); eDiv.setAttribute("class","select_file_dialog"); document.body.appendChild(eDiv); var L=0; if(typeof(Left)=="string") { if(Left.equalsIgnoreCase("center")) { var iDivWidth=Math.min(window.outerWidth,550); L=Math.max(0,window.outerWidth/2 - iDivWidth/2); }; } else { L=Left; }; if(Top>=0) eDiv.style.top=Top+"px"; if(L>=0) eDiv.style.left=L+"px"; sUrl=getServer()+"/?Network=GreenLight&ID=getWidget&DocumentID=K4Ui6j3Y1rwlvukPkOqn25Em"; sUrl +="&Widget=Notification Container 2&ContainerItemID=648693"; sUrl +="&Salt="+Salt+"&Filespec="+Filespec+"&Select="+Select+"&Exists="+Exists; sUrl +="&FnOk="+fnOk+"&FnCancel="+fnCancel; sUrl +="&Source="+Source; asynchInclude(eDiv,sUrl,"",""); }; var PositionLatitude=0.0; var PositionLongitude=0.0; var PositionAccuracy=0.0; var PositionAltitude=0.0; var PositionAltitudeAccuracy=0.0; var PositionHeading=0; var PositionSpeed=0; var PositionTimestamp=0; function watchPosition() { if (navigator.geolocation) { navigator.geolocation.watchPosition(updateSharedLocationValues); } else { appendToLog("Geolocation is not supported by this browser."); } }; function getCurrentPosition() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(updateSharedLocationValues); } else { appendToLog("Geolocation is not supported by this browser."); } } function updateSharedLocationValues(position) { //alert("Latitude: "+position.coords.latitude+" Longitude: "+position.coords.longitude); if(!position) { alert("position is undefined"); return; }; PositionLatitude=position.coords.latitude; PositionLongitude=position.coords.longitude; PositionAccuracy=position.coords.accuracy; PositionAltitude=position.coords.altitude; PositionAltitudeAccuracy=position.coords.altitudeAccuracy; PositionHeading=position.coords.heading; PositionSpeed=position.coords.speed; PositionTimestamp=position.coords.timestamp; } function getLatitude() {return(PositionLatitude)}; function getLongitude() {return(PositionLongitude)}; function getPositionAccuraryMeters() {return(PositionAccuracy)}; function getPositionAccuraryFeet() {return(PositionAccuracy*3.28084)}; function getPositionAltitudeMeters() {return(PositionAltitude)}; function getPositionAltitudeFeet() {return(PositionAltitude*3.28084)}; function getPositionAltitudeAccuracyMeters() {return(PositionAltitudeAccuracy)}; function getPositionAltitudeAccuracyFeet() {return(PositionAltitudeAccuracy*3.28084)}; function getPositionHeading() { if(isNaN(PositionHeading)) return(-1); return(PositionHeading) }; function getPositionSpeedMetersPerSecond() { if(isNaN(PositionSpeed)) return(-1); {return(PositionSpeed)}; }; function getPositionSpeedMilesPerHour() { if(isNaN(PositionSpeed)) return(-1); return(PositionSpeed*3.28084/60/60); }; function getPositionTimestamp() { return(PositionTimestamp); }; /****************************************************************************************************** FUNCTIONS USED TO DISPLAY SYSTEM DIALOG The showDialog function is called to display the dialog. params is a & delimited string of arguments. The following arguments can be defined: icon - If the value is true, a status icon is displayed before the message msg - the message to be displayed. ProgressMax - If specified, a progress bar wll be displayed with a value of ProgressMax ProgressToken - Must be specified when ProgressMax is defined. This is a token that wlil be requested at a 1 second interval to update the progress bar. The token can contain a single number indicating the number of steps (out of max) completed so far or it can be a pipe-delimited string that contains the number followed by a new message to be displayed in the dialog. Currently ProgressMax and ProgressToken only work when the token is defined on the machine specified by getServer() (i.e. the local computer) (these arguments cause a button to be displayed when defined. The argument defines the function to be called when the button is pressed. For example fnOK=myfunction()&fnCancel= The value can also be 'close' which will just hide the dialog without calling a function fnOk fnYes fnNo fnCancel fnOther1 - Pass a value in Other1 to set the label of the button fnOther2 - "" fnOther3 - "" Quotes can be included in the function definitions by using $q examples: showDialog('icon=true&msg=this is a test') showDialog('icon=true&msg=this is a test&top=200&left=200&width=400&height=100') showDialog('icon=true&msg=this is a test&fnOk=alert($qtest$q)&fnCancel=close') showDialog('icon=true&msg=this is a test&fnOk=alert($qtest$q)&fnOther1=alert($qOther$q)&Other1=Other&fnCancel=close') showDialog('close') ******************************************************************************************************/ var bShowingSystemDialog=false; function showDialog(params) { //always close the dialog to avoid multiple ones being opened var e=document.getElementById("SystemDialog"); if(e) document.body.removeChild(e); //if no params were passed, just exit after closing the dialog if(!params) return; var d=document.createElement('div'); d.id="SystemDialog"; d.style.zIndex=99; d.className="showdialog"; //d.style.width=(bIsMobileDevice) ? "270px" : "300px"; d.style.width="75%"; d.style.maxWidth="300px"; var bTopSpecified=false; var bLeftSpecified=false; var arCommands=new Array("ICON","MSG","LEFT","TOP","WIDTH","HEIGHT","FNOK","FNYES","FNNO","FNCANCEL","FNOTHER1","FNOTHER2","FNOTHER3","POSITION","MAX-WIDTH","PROGRESSMAX","PROGRESSTOKEN"); aParams=getSubStringArray(params,"&",true); var bAddProgressBar=false; var ProgressMax=0; var sProgressToken=""; for (var i=0;i0) { var sName=aParams[i].substring(0,n); var sNameUpper=sName.toUpperCase(); var sValue=aParams[i].substring(n+1); if(sValue.equalsIgnoreCase("close")) sValue="showDialog()"; var iCommand=-1; for (var j=0;j0)) { var eProgress=document.createElement("progress"); eProgress.id="SystemDialogProgress"; eProgress.style.width="100%"; if(ProgressMax>0) { eProgress.setAttribute("max",ProgressMax); eProgress.setAttribute("value",0); }; d.appendChild(eProgress); }; document.body.appendChild(d); //set top and left position if not specified if(!bLeftSpecified) { //position in the middle of the screen var Middle=document.body.offsetWidth/2 - d.offsetWidth/2; d.style.left=Middle+"px"; }; if(!bTopSpecified) { d.style.top="100px"; }; //if a progress token and max value have been specified, call the function to update the progress bar if((ProgressMax>0) && (sProgressToken.length>0)) { var sUrl=getServer()+"/?Network=greenlight&id=eval&expression=getToken("+sProgressToken+")"; var sFunc="updateDialog('"+sProgressToken+"',s)"; setTimeout("asynchInclude(null,\""+sUrl+"\",\""+sFunc+"\",\""+sFunc+"\");",1000); }; }; /************************************************************************ This function is called by showDialog when a progress bar has been specified using ProgressMax and ProgressToken. This function makes a request to the server for the given token and then updates the dialog. The token is a number indicating the number of steps (out of max steps) completed. It can also be of the form [steps completed]|[message] which will also update the message in the dialog. ************************************************************************/ function updateDialog(_progresstoken,_tokenvalue) { //return if the dialog has been closed var eDialog=document.getElementById("SystemDialog"); if(!eDialog) { return; }; if(_tokenvalue) { var iValue=0; var sMsg=""; sTokenValue=_tokenvalue.trim(); if(sTokenValue.length>0) { var n=sTokenValue.indexOf("|"); if(n<0) { iValue=parseInt(sTokenValue); } else { iValue=parseInt(sTokenValue.substring(0,n)); sMsg=sTokenValue.substring(n+1); }; if(sMsg.length>0) { var eMsg=document.getElementById("SystemDialogMsg"); eMsg.innerHTML=sMsg; }; if(!isNaN(iValue)) { var eProgress=document.getElementById("SystemDialogProgress"); if(eProgress) eProgress.value=iValue; }; }; var sUrl=getServer()+"/?Network=greenlight&id=eval&expression=getToken("+_progresstoken+")"; var sFunc="updateDialog('"+_progresstoken+"',s)"; setTimeout("asynchInclude(null,\""+sUrl+"\",\""+sFunc+"\",\""+sFunc+"\");",1000); }; }; function showDialogSub(t,top,left,width,height) { //appendToLog("showDialogSub"); bShowingSystemDialog=false; var e=document.getElementById("SystemDialogContainer"); if(!e) { e=document.createElement("div"); e.id="SystemDialogContainer"; document.body.appendChild(e); }; e.style.zIndex=99; e.innerHTML=t; var e2=document.getElementById("SystemDialog"); if(e2) { (top==0) ? e2.style.top="100px" : e2.style.top=top+"px"; (left==0) ? e2.style.left="100px" : e2.style.left=left+"px"; (width==0) ? e2.style.width="300px" : e2.style.width=width+"px"; (height==0) ? e2.style.height="auto" : e2.style.height=height+"px"; }; setVisible(e,true); }; function oldshowDialog(params,count) { //appendToLog("showDialog params="+params+" count="+count); if(!params) { //If the system dialog is still initializing, then wait 1 second and try again to hide it //Otherwise, the dialog will not be hidden if the dialog is shown and then hidden before it becomes visible (bShowingSystemDialog) ? setTimeout("showDialog()",1000) : setVisible("SystemDialogContainer",false); return; }; bShowingSystemDialog=false; //var strUrl="http://127.0.0.1:4446/?Network=GreenLight&ID=getCachedWidget&DocumentID=77NaWu0FhKDKXL7C70JpnKmy&Widget=HTML Status Message"; var strUrl=getServer()+"/?Network=GreenLight&ID=getCachedWidget&DocumentID=77NaWu0FhKDKXL7C70JpnKmy&Widget=HTML Status Message"; if (params) strUrl +="&"+params; //Try to load the dialog up to 5 times if an error occurs //Count will only be defined if an error has occurred in asynchInclude var n=0; if(count) { if(count>5) { alert("An error has occurred. Please refresh the page."); return; }; n=count+1; setTimeout("showDialog(\""+params+"\","+n+")",1000); return; }; var t=getElementValue(params,"top","&"); var l=getElementValue(params,"left","&"); var w=getElementValue(params,"width","&"); var h=getElementValue(params,"height","&"); (t.length>0) ? t=parseInt(t) : t=0; (l.length>0) ? l=parseInt(l) : l=0; (w.length>0) ? w=parseInt(w) : w=0; (h.length>0) ? h=parseInt(h) : h=0; var sFuncOk="showDialogSub(req.responseText,"+t+","+l+","+w+","+h+")"; var sFuncErr="showDialog(\""+params+"\",1)"; bShowingSystemDialog=true; asynchInclude(null,strUrl,sFuncOk,sFuncErr); }; /****************************************************************************************************** FUNCTIONS USED FOR DROP-DOWN MENUS ******************************************************************************************************/ var timerDropDownMenu=null; // open drop-down list function menuOpen(id) { menuCancelTimeout(); menuCloseAll(); setVisible(id,true); }; // close drop-down list function menuCloseAll() { var arMenu=document.getElementsByTagName("div"); for (var i=0;i=table.rows.size)) { alert("Error: showTableEditDialogForRow: Invalid RowIndex: "+RowIndex); printStackTrace(); return; }; //record metadata for the table including HashID, DriverID, etc. so data can be submitted //even if the table is closed before the data is submitted recordTableMetadata(table.getAttribute("ID")); for(var i=0;i if(td.nodeName.equalsIgnoreCase("td")==false) td=td.parentNode; var tr=td.parentNode; var tbody=tr.parentNode; var table=tbody.parentNode; if(table.nodeName.equalsIgnoreCase("table")==false) { alert("Error reading driver information"); return; }; var sTableID=table.getAttribute("ID"); var sDialogID=table.getAttribute("EditDialogID"); appendToLog("showTableEditDialog sTableID="+sTableID); //abort if the row is currently being deleted var sDeleted=tr.getAttribute("deleted"); if((sDeleted) && (sDeleted.equalsIgnoreCase("true"))) { appendToLog("showTableEditDialog: Aborted because record is being deleted"); setVisible(sDialogID,false); return; }; //record metadata for the table including HashID, DriverID, etc. so data can be submitted //even if the table is closed before the data is submitted recordTableMetadata(table.getAttribute("ID")); //initialize the dialog header. It is initially outside the dialog div and needs to be //moved inside the div initializeTableDialogHeader(sTableID,sDialogID,tr.getAttribute("KeyValue")); //hide the disable div if(document.getElementById("EditDialogDisable"+sTableID)) setVisible("EditDialogDisable"+sTableID,false); //get array of all field ID's and field types from the table header sAllFieldID=table.getAttribute("aspectAllFieldID"); sAllFieldType=table.getAttribute("aspectAllFieldType"); if((sAllFieldID==null) || (sAllFieldType==null)) { alert("No fields included for editing"); return; }; var arFieldID=getSubStringArray(sAllFieldID,",",true); var arFieldType=getSubStringArray(sAllFieldType,",",true); //get array of all values from the row var arValues=getSubStringArray(getAttr(tr,"aspectAllValues"),",",true); for(var i=0;idiv.offsetWidth) { //don't shift the dialog toward the center if the left position will be small. //Otherwise, a small (e.g. 9px) margin can be introduced for small screens. //Might have something to do with the scroll bar var left=Math.min(250,(maxwidth-div.offsetWidth)/2); if(left>20) div.style.left=left; }; div.style.top=(xy[1]+e.offsetHeight+5)+"px"; }; }; //set focus to the input with a DefaultFocus attribute. Do this before calling the initialization function //so the initialization function can override the focus set here var arInputElements=new Array(); getAllInputNodes(div,arInputElements); for(var i=0;i