XPages: how to automatically redirect to external url after timeout

Hi,

I’m currently trying to implement something that (imho) is a standard scenario in web apps:

after a user has submitted a form they should be shown some “Thank you” message. Then, after some timeout (say: 5 seconds) they shall be redirected to some fixed url which is outside of my current context (i.e.: a company home page).

I found this thread in the discussion:

http://www-10.lotus.com/ldd/nd85forum.nsf/5f27803bba85d8e285256bf10054620d/f847e44b47d18bba8525758a007880e8?OpenDocument

Philippe Riand suggested to use

context.redirect();

passing the target url.

Well, for one: the documentation doesn’t mention a “redirect()” method; instead, there’s only

a .redirectToPage() method

which leads to what was described by Barry McGovern in the thread’s final post.

Nevertheless, I played around with

context.redirect(“newUrl”)

in various combinations (and from various events), but always receiving a “Command Not Handled Exception” from it.

I then tried to pass a new URL using

XSPUrl.setAddress(myUrl)

which in fact seems to exchange the URL in memory, but with no consequences… (obviously I completely misinterpreted that method)

I’m assuming that I’m just missing a small detail, as I’m sure that something like that MUST be possible.

Any hint is more than welcome!

-Lothar

Subject: JSF redirect()

Hi Lothar,

You can use the JSF facesContext redirect:

externalCtx = facesContext.getExternalContext();

externalCtx.redirect(“http://www.jmackey.net”);

I just tested it and it works well.

-John

Subject: “Of course it worked” revisited…

ok yes, it worked indeed. Unfortunately not the way I expected. And now I see why: reason is that I’m programming a server side event, not a client side one. Stupid me!

Let me explain: what I’d like to achieve is a page popping up that’s thanking the users for their input. Then, after say 5 seconds they shall automatically be re-directed to the company homepage. I’ve done this numerous times in classical web design: write a function that’s setting a timer and then doing the re-directing job. The function is called from the page’s “onLoad” event. Doh! We don’t have client side page events in XPages, that’s why no thank you page is showing up, instead the user stares at a blank screen for 5 seconds :-o

I’m sure I must be missing something, but I can’t see any client side events for pages. Only for buttons, fields and other UI stuff (btw: there’s not even an onClick event for the page; didn’t think of that until today…).

Question 1: is this something that was left out intentionally, or has it just been forgotten to implement client-side page events?

Question 2: how can I achieve my client-side processing goal? Do I have to write my own event handler? Is this possible? If so: are there some examples available how to do it? I found the “Event Handler” control in the “Other” menu, but that’s not really intuitive to work with…

Edit:

meanwhile I found my workaround by displaying my thank you message in a plain javascript alert. Works nicely but is quite ugly, and the user still has to click onto another button.

Any hint as how to get it done the elegant way is still very welcome.

-Lothar

Subject: Client Side Javascript

Sorry - I have no answer for you. I have also been searching for ability to initiate a client side call from server side. I have yet to find any way. Will be interesting to see if you get a response.

I’ve almost given up on client side javascript. The more you get into the server side and partial refreshes, you realize there is very little need for client side javascript. It’s one of the many ‘ah-ha’ moments I’ve had with xPages.

But at the same time - it would be nice to have a few more controls for client side javascript.

Subject: I have a workaround

I don’t have the answer but a workaround.

Insert a Scriptblock control on your page, this will contain your clientside javascript that you want to trigger. Then set a requestScope variable in your serverside code that will be used to control the visibilty of the scriptblock. So when the page reloads, the clientside script is now visible on the page and will trigger your window.open.

The scriptblock can be found at Other->Other Controls->Output Script

Here’s an example with an alert():

<xp:scriptBlock id=“scriptBlock1”

	rendered="#{javascript:requestScope.showPopupWindow==true}">



	<xp:this.value><![CDATA[alert("Popup");]]></xp:this.value>

</xp:scriptBlock>

In your serverside code set: requestScope.showPopupWindow=true;

-John

Subject: also you can use dojo.addOnLoad(function_name)

You can also use the dojo.addOnLoad in a Script block to call your function. This will enforce that all the dojo modules are properly loaded prior to calling your JS function.

-John

Subject: Not for Partial Refreshes

Hi John -

The script block doesn’t work for partial refreshes in IE. The javascript is only called when you first load the page (or refresh the entire page).

I don’t like to refresh the entire page unless I have to. But if you need to call client side JS - I believe that’s the only way you are going to get it.

It does work fine in FF. Any javascript in the section refreshed is called everytime you refresh it. But nothing in IE…

FYI - I don’t use the script block - I just output script in a computed field with output as HTML. It’s easier then that crazy script block control. I mean could they have made it any more confusing!

Note > I could have these browsers backwards - I know it worked in one and not the other - pretty sure it was IE that it did not work in.

Subject: addOnLoad()…

John,

thanks for your workaround tip, that sounds promising, and I’ll give it a try asap.

I already have been considering to implement some

XSP.addOnLoad

call as I felt this would be the most elegant way to do it. But to be honest I’m not too sure how to implement it, and documentation (once more) is sparse.

Is there a difference between the dojo and the XSP implementations of “addOnLoad”? Do I have to bind a specific dojo module resource into my page to be able to call dojo.addOnLoad? Or is this implemented by default?

At the moment I simply call a standard alert from the submit button’s onClick; the solution isn’t pretty as the alert looks more like a system error rather than a “thank you” sign. But the app is working now, so the pressure isn’t too big anymore, and other jobs are waiting…

All the best,

-Lothar

Subject: example

There’s an addOnLoad() example(s) in that same Wiki article: http://www-10.lotus.com/ldd/ddwiki.nsf/dx/Client_Side_JavaScript_Libraries_in_XPages.htm

XSP is the variable used for the dojo instance on an XPage, so you should use XSP.addOnLoad.

-John

Subject: Works perfectly for me!

Great, more or less exactly what I was looking for!

Subject: of course it worked :slight_smile:

thanks once more; whithout that invaluable help from people like you… ah you know aht I mean.

I had realized the facesContext object, but simply didn’t have a clue how to use it.

There’s another bunch of methods to this object, like .wait() to give one example. I thought that maybe that would give me a simple wait timer but using it as in

facesContext.wait(5000)

resulted in Command not handled exceptions.

I wrote my timer standard way now, but being curious I tried to find out more about facesContext.

I assume that this object directly comes from JSF, right? I checked sun’s JSF API reference but there’s no .wait method listed for facesContext…

Any hints as to what that method can be used for and how to use it?

Thanks,

-Lothar

Subject: inherited from java.lang.Object

Hi Lothar,

It’s inherited from java.lang.Object. I have not used it myself but here’s some info on the method:

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

public final void wait(long timeout,

                   int nanos)

Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed.

There’s an example here:

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#wait(long,%20int)

-John

Subject: Timer…

Many thanks indeed; I’ll surely store this for future reference!Meanwhile I solved my task programming my own little timer.

Best regards,

-Lothar