"Please wait...processing request" window
FYI...
There is a neat way to display a "Please wait...processing request" message while the user waits for the system. It's really straightforward and only takes a few lines of code.
Place your form inside of <div></div> tags
Place the code for the "Please wait..." message inside of <div></div> tags
When the jsp is loaded, the tags are defined so that only the code inside the first div tags is displayed - user only sees the form
When the submit button is clicked, a javascript function is called.
The javascript hides the code inside the first div tag (form goes away) and displays the code in the second div tag - "Please wait..." message is displayed
Then the javascript calls submitForm() so that the servlet is called and processing begins
When the servlet is done, he forwards the client to another jsp (Change Verification, Thank You, whatever) and the "Please wait..." message is replaced.
The "Please wait..." message will appear instantly
Lets the customer know that the system is doing something
Since the form is hidden, user cannot hit the submit button twice
There are lots of possibilities with hiding/displaying code.
It can be used on button click, hyperlink click, etc.
Sample jsp:
<html>
<head>
<title>Company Profile</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="shared/estyles.css" type="text/css">
</head>
<body bgcolor="#FFFFFF" text="#000000" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
<div id="formDiv">
<form action="submitCompanyProfileServlet" method="POST" name="COMPANY">
<!-- YOUR FORM GOES HERE -->
</form>
</div>
<div id="pleaseWaitDiv" style="display: none;">
<jsp:include page="pleaseWait.jsp"/>
</div>
<script type="text/javascript">
function submitForm(oForm)
{
// Hide the code in first div tag
document.getElementById('formDiv').style.display ='none';
// Display code in second div tag
document.getElementById('pleaseWaitDiv').style.display ='block';
oForm.submit();
}
</script>
</body>
</html>
[nobr]Here is another one, just for fun.
This one uses a Thread in the servlet to run the long process. It uses a seperate JSP to display a process bar and a META refresh to update the bar, and an c:if test to see if the page is done loading.
No, not as simple as the first one, but it does a little more (like an actual measure of the loading process and/or a message that can be displayed at intervals.
Note, these samples assume TOmcat 5, JSTL, and EL
//This is the processing.jsp, which displays the progress bar
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:url var="processing" value="processing.jsp"/>
<c:url var="display" value="display.jsp"/>
/* If the processing thread isn't still running, go to display page */
<c:if test="${!stillProcessing}">
<c:set var="percentDone" value="${null}" scope="session"/>
<c:redirect url="${display}"/>
</c:if>
<html>
<head>
<title>Processing</title>
/* Show this page again, updating the percentage done
Maybe set content to a higher amount to reduce the request count... */
<META HTTP-EQUIV="REFRESH"
CONTENT="3; ${processing}"/>
<style type="text/css">
//Displays a bounding box with a border
div.outer
{
display: block;
width: 500px;
height: 30px;
background-color: white;
border: 1px solid black;
}
//Fills the bounding box with a percentage based on the processing thread
div.inner
{
display: block;
float: left;
width: ${percentDone}%;
height: 30px;
background-color: blue;
}
</style>
</head>
<body>
<center>
<h2>Processing Your Request</h2>
<h3>Please Wait...</h3>
<div class="outer"><div class="inner"><br/></div></div>
Thank you for your patience
</center>
</body>
</html>
//The LongProcessServlet that invokes this
package servlets;
import javax.servlet.*;
import javax.servlet.http.*;
import beans.SimpleBeanExample_Bean;
public class LongProcessServlet extends HttpServlet
{
public void doGet (HttpServletRequest request, HttpServletResponse response)
throws ServletException, java.io.IOException
{
final HttpSession session = request.getSession();
final double startAt = Double.parseDouble(request.getParameter("startAt"));
final double endAt = Double.parseDouble(request.getParameter("endAt"));
final long sleepTime = Long.parseLong(request.getParameter("sleepTime"));
//This will be tested to see if we are done or not
session.setAttribute("stillProcessing", Boolean.TRUE);
Thread t = new Thread(new Runnable()
{
public void run()
{ //Do your real processing here
for (double i = 0.0; i < (endAt-startAt); i += 1.0)
{
Integer percentDone = new Integer((int)((i / (endAt-startAt))*100)+1);
//Sets a value to be used in the processing jsp
session.setAttribute("percentDone", percentDone);
try {
Thread.sleep(sleepTime);
} catch (InterruptedException ie) {}
}
//Done processing, let processing jsp know
session.setAttribute("stillProcessing", Boolean.FALSE);
}
});
t.start();
response.sendRedirect(response.encodeRedirectURL("processing.jsp"));
}
}
//And a simple form to test it out
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Long Process Setup</title>
</head>
<body>
<c:url var="action" value="LongProcess"/>
/* I should validate this form to make sure the params are all numbers, and endAt >= startAt */
<form name="longProcessForm" action="${action}">
<table>
<tr><td>Start Value</td><td><input type="text" name="startAt" value="0"/></td></tr>
<tr><td>End Value</td><td><input type="text" name="endAt" value="100"/></td></tr>
<tr><td>Sleep Time</td><td><input type="text" name="sleepTime" value="100"/></td></tr>
<tr><td colspan="2" align="left">
<input type="submit" value="Start Process"/>
<input type="reset" value="Reset Form"/>
</td></tr>
</table>
</form>
</body>
</html>
[/nobr]
good one to know (both).. :)
Is there any way to call a javascript function t from java without any eventbeing triggred?Actually i want to hide the div tag with "please wait" to disappear when queried data starts populating the gae?
How could this be implemented using jsf? I got the whole way down to where you have the form page, but there is no action attribute in jsf for a the <h:form> tag. The action is in the button, but this is calling the backing bean which does validation checks, etc.Thanks!!
[nobr]Here is anotherone I came up with. It is simple, like the first javascript one, but uses normal CSS, to hide the PleaseWaitDiv by positioning the resultsDiv right on top of it. It uses plain HTML pages added to the response via ResultDispatcher.includes in a worker Servlet.
//head.html defines the html content independent of the processing. This
//One shows how you might add a header, side bar and footer...
//also define the styles for the overlapping content.
<html>
<head>
<style type="text/css">
.header {
position: absolute;
width: 100%;
height: 50px;
top: 0px;
left: 0px;
text-align: center;
}
.sideBar {
position: absoulte;
width: 100px;
height: 600px;
top: 50px;
left: 0px;
}
.content {
position: absolute;
top: 50px;
left: 100px;
}
.footer {
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
hight: 50px;
}
#resultsDiv {
background-color: white;
}
</style>
</head>
<body>
<div class="header"><h2>My Company Logo</h2></div>
<div class="sideBar">
Link 1<br/>
Link 2<br/>
Link 3<br/>
</div>
<div class="footer">
<span style="font-size:6px;">Contact Us Site Map Company Info</span>
</div>
//pleaseWait.html is displayed first
<div class="content" id="pleaseWaitDiv">
<h3>Please Wait</h3>
The PDF is being processed.
</div>
//datapage.html is displayed when processing is done
<div class="content" id="resultsDiv">
<h3>Processing Complete</h3>
The PDF is ready for access.
</div>
//pdfError.html is displayed if an error occurs
<div class="content" id="resultsDiv">
<h3>Error Processing PDF</h3>
The PDF is unavailabe due to an error while processing.
</div>
//This is the servlet that drives it
package net.thelukes.steven;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PDFProcessor extends HttpServlet {
private boolean doWork() {
try {
Thread.sleep(10000);
return true;
} catch (Exception e) {
log (e.getMessage(), e);
return false;
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getRequestDispatcher("head.html").include(request, response);
request.getRequestDispatcher("pleaseWait.html").include(request, response);
//note I use the outputStream to flush to force content to show
response.getOutputStream().flush();
boolean doneWell = false;
doneWell = doWork();
if (doneWell) {
request.getRequestDispatcher("datapage.html").include(request,response);
} else {
request.getRequestDispatcher("pdfError.html").include(request, response);
}
request.getRequestDispatcher("bottom.html").include(request, response);
}
}
[/nobr]
> Is there any way to call a javascript function t
> from java without any eventbeing triggred?
>
> Actually i want to hide the div tag with "please
> wait" to disappear when queried data starts
> populating the gae?
>
A slight modification of my last post would work I think. Cyclically in the Servlet, you would add data to the results ( yo will have to use the results.getOutputStream, not the results.getWriter). Start by writing the resultsDiv tag, then writing some data, then flushing the stream after each cycle.
You could do this with the method on response #1 as well. Put the data that is ready to write in the session. Then on the display page, make the progress bar take a small portion of the page, and use the rest of the page to write the data out after each refresh, or do a jsp:include of the final display page...
> How could this be implemented using jsf? I got the
> whole way down to where you have the form page, but
> there is no action attribute in jsf for a the
> <h:form> tag. The action is in the button, but this
> is calling the backing bean which does validation
> checks, etc.
>
> Thanks!!
Sorry, don't know JSF.
I try the first approach(Simple.jsp) and t's working perfect. But if I put an animated image in the 'pleaseWait.jsp'. The animated image is not animated any more. Could any body explain why it is happened and how to solve the issue. thanks in advance.Jimmy
See this component from Coldtags suite: http://www.servletsuite.com/servlets/waittag.htm
How do I implement this progress bar in Spring framework?Any help?
I really like the original solution, from the first post, it's very practical.Richard
the first solution works fine. thanks..
iGGy at 2007-7-6 13:53:25 >
