Called for alerts, message boxes and informational message displays. If you return a null from this function, the message is handled normally inside the emulation session. Return a special handler function object to handle the message in your page (advanced!).
// Return null if you just want to inspect the msg but not display your own UI
function onAlert(alertObj, msg, bgColor, fnOnClick, buttons)
{
return new MyAlert(alertObj, msg, bgColor, fnOnClick, buttons); // sample MyAlert below
}
Parameter |
Description |
alertObj |
Information about the message display--includes the following properties: alertType: "status", "alert" or "msgbox" status: The status messages that appear and frequently go away on their own alert: An alert message with a single OK button msgbox: A message with one or more defined buttons, OK, Yes, No and Cancel are options index: For type "alert" or "msgbox" the index in the emulation session for this alert click(buttonText): Calling this will run any fnOnClick completion function as well as closing the alert if it has been displayed (return of null or no return). buttonText can be based on the msg. close(): To avoid a javascript memory leak, call this function with true as the parameter when your alert is closed, except when your close method is called with true for "fromSession" parameter. |
msg |
The text of the message to be displayed |
bgColor |
The background color of the message as requested by the emulation logic |
fnOnClick(buttonText) |
Optional completion function which if present must be called when a button is clicked. For alertType=status, if this parameter is not null, a onclick or onmouseup should be set for the displayed message and set to call this function. Pass the button text that was clicked for type msgbox -- the parameter is ignored for alert and status alertTypes. |
buttons |
For type="msgbox" a string if single characters indicating the buttons requested. If omitted, default is "o".
Create and display the appropriate button for each character found.
Characters are:
o = OK y = Yes n = No c = Cancel |
Optional Return Object Required Members |
Description |
close(fromSession) |
Function called by the emulation session if the session is closing or the alert/msgbox/status should be removed for some other reason--if you use the same name for your method, the fromSession parameter being true can avoid infinite recursion (don't call the alertObj.close() function if this is true) |
Bind your onAlert in the FVMsgApi.ConnectMsgFVTerm or ConnectFVTerm function callback as follows:
fvApi.onalert = onAlert;
Because alerts and message boxes can be "stacked", writing your own handler can be quite complex--the following code is an example of how to implement.
<style type="text/css">
.fvAlert
{
position: absolute;
border: silver thin outset;
padding: 15px;
font-weight: bold;
color: black;
font-family: Arial;
background-color: white;
}
.fv-btn, .fv-button
{
border: none;
display: inline-block;
padding: 8px 16px;
vertical-align: middle;
overflow: hidden;
text-decoration: none;
color: inherit;
background-color: inherit;
text-align: center;
cursor: pointer;
white-space: nowrap
}
.fv-btn:hover
{
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)
}
.fv-btn, .fv-button
{
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none
}
.fv-btn, .fv-btn:link, .fv-btn:visited
{
color: #FFFFFF;
background-color: #5d9afc
}
</style>
<script type="text/javascript">
var fvAlerts = [],
btnText = { "o": "OK", "y": "Yes", "n": "No", "c": "Cancel" },
alertCount=0;
function MyAlert(alertObj, msg, bgColor, fnOnClick, buttons)
{
var vp = GetViewPort(window, document),
isStatus = (alertObj.alertType == 'status'),
alertText=(alertObj.alertType=='alert') ? 'Alert' : 'Message Box',
index = alertCount++,
yOffset=(isStatus) ? 200:100,
clickSty = (fnOnClick) ? 'cursor:pointer;' : '',
width = 300, x = (vp.width / 2 - width / 2) + index * 4, y = 100 + index * 4,
updated=false,
elem, elemSty, me = this, bt = '', t = '', innerID, innerElem, defID, maxWidth = Math.floor(vp.width * 0.8), i;
if (isStatus)
this.divID = 'PopStatus';
else
this.divID = 'PopAlert_' + index;
innerID = 'T' + this.divID;
elem = document.getElementById(this.divID);
if (elem == null)
{
elem = document.createElement('div');
elem.id = this.divID;
elem.className = 'fvAlert';
elemSty = elem.style;
document.body.appendChild(elem);
}
else
{
elemSty = elem.style;
updated = true;
}
elemSty.zIndex = 4001 + index;
if (!updated)
{
elemSty.left = x + 'px';
elemSty.top = y + 'px';
elemSty.width = width + 'px';
}
elemSty.backgroundColor = bgColor;
this.click = function (button)
{
me.close();
if (fnOnClick)
fnOnClick(button);
}
this.close = function (fromSession)
{
try
{
elemSty.display = 'none';
document.body.removeChild(elem);
if (!isStatus)
{
if (!fromSession)
alertObj.close(true);
for (i = 0; i < fvAlerts.length; i++)
{
if (fvAlerts[i] == me)
break;
}
if (i < fvAlerts.length)
fvAlerts = fvAlerts.splice(i, 1);
if (fvAlerts.length > 0)
fvAlerts[fvAlerts.length - 1].defElem.focus();
}
}
catch (e) { }
}
if (isStatus)
{
t += '<table width="100%" height="100%"><tr><td valign="center" align="center" style="'
+ clickSty + 'background-color:'
+ bgColor + ';font-family:Arial;font-weight:bold;color:darkblue;font-size:13pt;"><h3>Status</h3>'
+ msg + '</td></tr></table>';
elem.innerHTML = t;
this.defElem = elem;
if (fnOnClick)
{
elem.onmouseup = function (e) { me.click('ok') };
}
}
else
{
this.btnHtml = function (letter)
{
var text=btnText[letter],
bgSet = (text == 'No' || text == 'Cancel') ? ';background-color:#e3e7ed;color:#0c1e3a' : '',
t = '<a id="'+letter + this.divID + '" href="#" style="margin-left:5px;margin-botton:10px;' + bgSet + '" class="fv-btn">';
return t + text + '</a>';
}
this.btnEvent = function (letter)
{
var text = btnText[letter],
btnElem = document.getElementById(letter + this.divID);
if (btnElem)
btnElem.onmouseup = function (e) { me.click(text) };
}
for (i = 0; i < buttons.length; i++)
bt += this.btnHtml(buttons[i]);
t += '<table width="100%" height="100%" id="' + innerID
+ '"><tr><td valign="center" style="background-color:'
+ bgColor + ';font-family:Arial;font-weight:bold;color:darkblue;font-size:13pt;max-width:'
+ maxWidth + 'px"><h3>' +alertText +'</h3>' + msg + '</td></tr>';
t += '<tr><td style="padding-top:20px;text-align:right;background-color:'
+ bgColor + ';" align="right"><div style="float:right">' + bt
+ '</div></td></tr></table>';
elem.innerHTML = t;
innerElem = document.getElementById(innerID);
for (i = 0; i < buttons.length; i++)
this.btnEvent(buttons[i]);
if (innerElem &&
(innerElem.offsetWidth + 20 > width))
{
width = Math.min(innerElem.offsetWidth + 20, maxWidth);
elemSty.width = width + 'px';
elemSty.left = ((vp.width / 2 - width / 2) + index * 4) + 'px';
}
if (buttons.indexOf('o') != -1)
this.defElem = document.getElementById('o' + this.divID);
else if (buttons.indexOf('y')!=-1)
this.defElem = document.getElementById('y' + this.divID);
if (this.defElem)
{
this.defElem.onkeydown = function (ev)
{
var kc = ev.which || ev.keyCode;
if (kc == 13)
me.click(me.defElem.innerText);
if (kc == 27)
{
if (buttons.indexOf('c') != -1)
me.click('Cancel');
if (buttons.indexOf('n') != -1)
me.click('No');
}
if (flow.macs.cancelEv)
return (flow.macs.cancelEv(ev));
return false;
}
this.defElem.focus();
}
else
this.defElem = this.elem;
}
if (!updated)
fvAlerts.push(this);
}
function GetViewPort(win, doc)
{
var vp = { width: 0, height: 0 };
if (!win)
win = window;
if (!doc)
doc = document;
if (doc.documentElement && (doc.documentElement.clientWidth || doc.documentElement.clientHeight))
{
//IE 6+ in 'standards compliant mode'
vp.width = doc.documentElement.clientWidth;
vp.height = doc.documentElement.clientHeight;
}
else if (typeof (win.innerWidth) == 'number')
{
//Non-IE
vp.width = win.innerWidth;
vp.height = win.innerHeight;
}
return vp;
}
</script>