0

Why does context.redirectToPage behave differently when executed in a view root-event instead of an event handler?

This question came up when I tried to set the language of an xpages application to the language saved in the user profile, once the user is logged in. I use a properties-file with translated strings in a resource bundle, and retrieve the strings like this:

<xp:text value="${langString['WELCOME_TEXT']}" />

When the language is changed and so a different properties-file is loaded, the page needs to be refreshed in order to update those strings. This worked fine when I added a full-refresh event handler to the login button, that executed a server side context.redirectToPage(). No luck with client side refreshes like location.reload or window.location.href=window.location.href (the login-function itself is a client side function though).

But of course the user expects that he is also logged in when he presses the enter key instead of the button after he has entered his credentials. So I added an onkeypress-event to the username and password input fields, and checked for the enter key (if (thisEvent.keyCode==13) dosomething...) before executing the login function.

But now the event handler is called every time a key is pressed and of course I do not want the context.redirectToPage to be executed all the time. Thus I removed the server side event handlers and changed the login function so that it terminated with a partial refresh of the div containing the whole page:

var p = {"execLogin":"true"}; XSP.partialRefreshPost( '#{id:wholePage}', {params: p} );

The parameter sent via the partial refresh now triggers an event in which our context.redirectToPage is executed:

<xp:this.beforeRenderResponse><![CDATA[#{javascript:if (param.containsKey('execLogin') && param.get('execLogin').toString().equals('true')) {
    print("test");
    context.redirectToPage(context.getUrl().toSiteRelativeString(context),true);
}}]]></xp:this.beforeRenderResponse>

The page is refreshed and "test" is printed out, but I still see the old language strings. I have to refresh the page manually again to make the new user language take effect.

Any idea how to execute a genuine full refresh this way, or maybe another way to update the strings retrieved from the property bundle?

Thanks in advance. Regards, Sarah

EDIT

I now have:

<xp:inputText id="cc_login_panel_login_username" styleClass="span2">
<xp:eventHandler event="onkeypress" submit="true" refreshMode="complete">
    <xp:this.script><![CDATA[if (thisEvent.keyCode!=13) {
        return false;
    } else {
        doLogin();
        return true;                                
    }]]></xp:this.script>
    <xp:this.action><![CDATA[#{javascript:context.redirectToPage(context.getUrl().toSiteRelativeString(context));}]]></xp:this.action>
</xp:eventHandler>

Because context.reloadPage() didn't even log me in somehow (strange) I got back to using redirectToPage. The server side event is fired once and at the right time *thumbs up*, but the language properties-bevaviour is still the same.

Sarah Steffen
  • 15
  • 1
  • 8
  • How do you change the language / locale setting in your application? And is there any reason why you are using the *true* parameter in your redirect? Why don't you use a *context.reloadPage*? – Sven Hasselbach Jan 17 '13 at 14:33
  • I just added the _true_ parameter to see if it changed anything (doesn't). I tried using context.reloadPage instead of redirectToPage, but it produced the same behavoir. Actually I am just loading another properties-file to change the language when the user is logged in: `` When I put #{getUserLanguage} into an xp:inputText or something, I can see that it has changed to the right language, but the xpage does not load the new strings from the new file - only when a manual full refresh is performed. – Sarah Steffen Jan 17 '13 at 15:07
  • I am still trying to understand the "keyCode" thing... Why is your code executed every time? You can stop executing the server side event by returning *false* in the client side event. – Sven Hasselbach Jan 17 '13 at 15:09
  • I don't see why this should not work. As you are writing, the button works as expected, but the event triggered by the key does not. Is this correct? If not, please answer my first question: How do you change the locale setting? Is this a timing issue? What if you print out the locale setting in the different phases / events (*beforeRenderResponse* etc). P.S. You can make a partialRefresh of the full page if you just leave the *refershId* property (aka the target) empty. – Sven Hasselbach Jan 17 '13 at 21:22

4 Answers4

1

$ is only set on page load, whereas # is set each time during the partial refresh.

I don't think a partial refresh will work at all though. This will refresh the computed field. However, it will need a full refresh to refresh the part of the XPage that includes the properties file. In other words, you would be refreshing the computed field, but using the same properties file.

I wonder if context.redirectToPage or context.reloadPage is somehow going to the same page but with the cached properties files.

If you're always wanting to come back to the same page, a full refresh instead of partial refresh may be the best option.

Paul Stephen Withers
  • 15,699
  • 1
  • 15
  • 33
0

I think this has something to do with using the $ parameter. this tells the runtime to retrieve the language file the first time the current page is created in the back-end. When a user does a refresh it is actualy retrieving a saved version of the page you are viewing.

jjtbsomhorst
  • 1,667
  • 11
  • 28
  • I just tried out using # to retrieve the language strings, but it didn't help. The strings still are not updated when context.redirectToPage is executed, this happens only when I refresh the page manually. Isn't there a way to force the server to render the page anew when the user is logged in? This is what I thought context.redirectToPage is doing. – Sarah Steffen Jan 17 '13 at 14:27
0

I see you're calling "context.redirectToPage(context.getURL().toSiteRelativeString(context)))" within an xp:this.action tag for the xp:eventHandler.

Try using xp:this.onComplete in place of xp:this.action.

According to the Designer tooltip for the action, the expected return is a string to be passed to the navigation handler. So instead giving the onComplete will execute the redirect command when it's done with the eventHandler group of events.

Event Handler Action Tooltip

Eric McCormick
  • 2,716
  • 2
  • 19
  • 37
0

Thanks for all the helpful answers, in fact all of them did work, the problem turned out to be my misunderstanding of when the properties-file is loaded. It is loaded in an early phase, long before my new language is set to the sessionScope (that sessionScope variable is then used as a part of the name of the properties-file to be loaded, via the VariableResolver).

Now I use a double full refresh to load the new file. When the login function terminates successfully, it executes:

window.location.href = window.location.href + "?doRefresh=true";

And to the view root element I added the following event:

<xp:this.beforeRenderResponse><![CDATA[#{javascript:
if (context.getUrlParameter("doRefresh")!=null&&context.getUrlParameter("doRefresh").equals("true")) {
    var url = context.getUrl().toSiteRelativeString(context);
    url = url.replace("?doRefresh=true","");
    context.redirectToPage(url);}
}]]></xp:this.beforeRenderResponse>

This is not a very sophisticated solution, but at least it works :-)

Sarah Steffen
  • 15
  • 1
  • 8