Tuesday, May 20, 2008

showModelessDialog – Build-in javascript function.


Difference between model and modeless dialog window.

Model Dialog Window prevented user access to the main window until the dialog window closes.
Modelless Dialog Window always stays in front of the main window, but allows access to the main window's user interface elements.

The methods called
1. window.showModalDialog() and
2. window.showModalessDialog()

We will start by designing the session timeout mechanism for a standard small to medium sized web application.

We set the session timeout in web.xml as 20 minutes. We pass this info through the tiles parent(Main) page to the javascript build-in function. After 15 minutes we give the user a pop-up message about the session timeout in another 5 minutes with Yes/No options. If user clicks Yes, then the session gets refreshed and starts from the beginning. For No in another 5 minutes the session is destroyed.

We set the web app session time-out in web.xml

web.xml

<session-timeout>20</session-timeout>

Menu.jsp

We call the function setTimer() from Menu.jsp (This is the Tiles JSP Page where we pass the original page as body using tiles along with header and footer information. Immediately after every page loads we pass the session time-out seconds to setTimer function for calculation.)

<script type="text/javascript">
setTimer(<%=request.getSession().getMaxInactiveInterval()%>);
</script>

Session timeout Requirement

Total user active session time is 20 minutes.

First pop-up at 15 minutes, (No response (or) No from user), second pop-up after 5 minutes indicating the user session has expired.

1 - When first alert opens, give Yes/No buttons.
2 - If the user hits YES we retart the timer and make a call on the web application so it will maintain the session longer.
3 - if user hits No, or does not hit any button and the second alert pops-up, cancel the session like you currently are and just before the second pop-up shows up close the first pop-up.
In this way even if the user clicks NO @ 18th minute session should be killed @ 20th minute instead of extending 5 minutes from 18th minute.

Common.js

To convert seconds to milliseconds we multiply by 1000. We pass 1200 seconds (20 minutes) to setTimer function. In setTimer() function using setTimeout() built-in function we invoke notification1() function after 15 minutes.

// Input to setTimer function is from Menu.jsp page which is 20 minutes (20 * 60 = 1200 seconds).
// We multiply with 1000 to get milliseconds. we multiply by (3/4 = 0.75) to get 15 minutes, when we give the
// first notification message to user along with option to refresh the session.

var sessiontime;
var n2;

function setTimer(sessiontimeout)
{
if (sessiontimeout!= null)
{
sessiontime = sessiontimeout*1000;

// sessiontime = 1200 * 1000 = 1200000 * 0.75 = 900000 milliseconds = 900 seconds = 15 min
var Id1= setTimeout("notification1()",sessiontime*(3/4));
}
}

var wn1;

function notification1() {
var params = new Object();
params.confirmationMsg = "The system has not registered any recent activity. In 5 minutes this connection will timeout as a security feature, unless there is some user input. Data Not Saved will be lost at that time. \n\n To continue this session, click Yes";
params.button1Display = " Yes ";
params.button2Display = " No ";
params.button1Action = resetSessionExpiry;
params.button2Action = setSessionExpiry;
params.button1Visibility = "visible";
params.button2Visibility = "visible";
var url = "../jsp/common/jsp/ExpiredSessionMsg.jsp";

//window.showModelessDialog() returns a window object reference

wn1=showModelessDialog(url,params,"dialogWidth:500px; dialogHeight:250px; status:no; center:yes;help:no");

setNotification2();
}

The third parameter in showModelessDialog() is used to get the pop-up window in the center of the page.

function notification2() {

if(wn1 != null) {
wn1.close();
}

var params = new Object();
params.confirmationMsg = "This session has timed out as a security measure. Unsaved data are not retained"
params.button1Display = " OK ";
params.button2Display = "Cancel";
params.button1Action = dummy;
params.button2Action = dummy;
params.button1Visibility = "visible";
params.button2Visibility = "hidden";
var url = "../jsp/common/jsp/ExpiredSessionMsg.jsp";
showModelessDialog(url,params,"dialogWidth:500px; dialogHeight:250px; status:no; center:yes;help:no");
}

/*
The setTimeout method is available on window objects.
It is used to add a delay to a function (usually one that is going to be executed multiple times.
*/

/*
The clearTimeout method is available on window objects.
It is used to clear a delay to a function that was set using setTimeout().
*/

function resetSessionExpiry(){

clearTimeout(n2);
if (sessiontime!= null)
{
var Id2= setTimeout("notification1()",sessiontime*(3/4));//15 mints==60000*15=900000
//If the user clicks Yes, Reload the page without Refreshing the browser.
var protocol = document.URL.split("//");
var urlParts = protocol[1].split("/");
var url = protocol[0]+"//"+urlParts[0]+"/"+urlParts[1]+"/app/RefreshServlet";
var req3;
if (typeof XMLHttpRequest != "undefined")
{
req3 = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
req3 = new ActiveXObject("Microsoft.XMLHTTP");
}
req3.open("GET", url, true);
req3.onreadystatechange = dummy;
req3.send(null);
}
}


function setSessionExpiry(){
//clearTimeout(n2);
//setTimeout("notification2()",sessiontime*(1/4));//5mints === 60000*5=300000
}
function setNotification2(){
n2 = setTimeout("notification2()",sessiontime*(1/4));//5mints === 60000*5=300000
}
function dummy(){
}

ExpiredSessionMsg.jsp

window.dialogArguments:
Whatever parameter that is passed to the params
var params = new Object(); // This Object where we set the paramaters in notification1 and 2
// in common.js
become the dialogArguments property of the window object in the HTML that is being displayed.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<script type="text/javascript" src="../jsp/request/js/common.js">
</script>
<script type="text/javascript">

var args = window.dialogArguments;
function display()
{

var confirmationMsg = document.getElementById("confirmationMsg");
confirmationMsg.innerText = args.confirmationMsg;
var button1 = document.getElementById("button1");
var button2 = document.getElementById("button2");
button1.value = args.button1Display;
button2.value = args.button2Display;
button1.style.visibility=args.button1Visibility;
button2.style.visibility=args.button2Visibility;
button1.onclick=args.button1Action;
button2.onclick=args.button2Action;
}

</script>
</head>

In the display() function we are setting the visibility style as well. Here is the link which talks more about setting the style property using Javascript.

<body onLoad="display();" style="background-color:#DEDFDE"; >
<p><b id="confirmationMsg" > </b> </p>

<p> <br><br>
<%for(int i=0;i<50;i++){ %> <%}; %>
<input class="primarybutton" id="button1" align="middle" onmouseup="window.close();" type="button" value="" />

<input class="primarybutton" id="button2" align="middle" onmouseup="window.close();" type="button" value="" /> </p>
</div>

</body>
</html>

Version-II
------------


var sessiontime;
function setTimer(sessiontimeout)
{
if (sessiontimeout!= null)
{
sessiontime = sessiontimeout*1000;
var Id1= setTimeout("notification1()",sessiontime*(3/4));//15 mints==60000*15=900000
}
}
function notification1() {
var params = new Object();
params.confirmationMsg = "The system has not registered any recent activity. In 5 minutes this connection will timeout as a security feature, unless there is some user input. Data Not Saved will be lost at that time.";
var url = "../jsp/common/jsp/ExpiredSessionMsg.jsp";
showModelessDialog(url,params,"dialogWidth:400px; dialogHeight:225px; status:no; center:yes;help:no");
setTimeout("notification2()",sessiontime*(1/4));//5mints === 60000*5=300000
}

function notification2() {
var params = new Object();
params.confirmationMsg = "This session has timed out as a security measure. Unsaved data are not retained"
var url = "../jsp/common/jsp/ExpiredSessionMsg.jsp";
showModelessDialog(url,params,"dialogWidth:400px; dialogHeight:225px; status:no; center:yes;help:no");
}


<script type="text/javascript">

var args = window.dialogArguments;
function display()
{
var confirmationMsg = document.getElementById("confirmationMsg");
confirmationMsg.innerText = args.confirmationMsg;
}

ExpiredSessionMessage JSP

</script>

</head>
<body onLoad="display();" style="background-color:#DEDFDE"; >
<div id="confirmBox">
<p><b id="confirmationMsg" > </b> </p>
<p> <br><br>


<input type="button" class="primarybutton" id="button1" value=" OK " align="middle" onclick="window.close();" />
</div>

</body>
</html>

Monday, May 5, 2008

Resetting the drop-downs (3 Drop - Downs)

Requirement:
We have 3 drop downs each containing the same values. If user selects one value (Search Criteria) in the first drop-down then he shouldn’t select the same in the next drop down. If the user selects the same value, then we need a throw a pop-up message saying this value is already selected and reset the drop down to default value.


<html:select size="1" property="advSearchCriteria1" name="RequestForm" styleClass="rmt-formTxt" style="margin-right:6px;" onchange="selectAdvSearchCriteria1();">
<html:option value="">Search Criteria1</html:option>
<logic:present name="RequestForm" property="searchDropList">
<bean:define id="row" name="RequestForm" property="searchDropList" />
<html:options collection="row" property="code" labelProperty="display" />
</logic:present>
</html:select>

function selectAdvSearchCriteria3()
{

var criteria1=document.forms[0].advSearchCriteria1.value;
var criteria2=document.forms[0].advSearchCriteria2.value;
var criteria3=document.forms[0].advSearchCriteria3.value;

if(criteria3 != '' && ((criteria3 == criteria1 ) (criteria3 == criteria2)))
{
alert("Already selected ");
document.forms[0].advSearchCriteria3.selectedIndex=0;
}
}

In the above function advSearchCriteria1 is a string property which will holds the selected search criteria by the user. Similarly we get the values of other drop-downs as well.