Redirecting from a data view
I have a mobile XPage application where I had a data view that listed several documents. For various reasons, I wanted the documents to open in a different XPage instead of a different mobile page. But the data view has a pageName attribute that says which mobile page to open. I found a clever way to open up that content in a new XPage. My initial thought was to use jQuery to change the HREF attribute on all the links after the mobile page was opened. But that wasn't going to work for one major reason. I only open up a few lines of the data view initially, then load up more if the user scrolls. I'd have to run through the freshly loaded data view entries and change the attribute whenever more were loaded. As a second reason, if the user clicked on an entry from the data view before I had a chance to change the HREF, then the user would be stuck.
This method works flawlessly in my testing and has a backup if it doesn't work as expected.
First, set the pageName of the data view to open the document in a specific mobile page. For consistency's sake, let's call it "launchDoc". So your data view code looks something like this:
<xe:dataView id="vwMobileDataView" pageName="launchDoc" openDocAsReadonly="true" rows="20">.....</xe:dataView>
Next, create that application page on the current XPage. This page will have a data source of the document being opened. Put it inside a Panel to get the data source to be used properly
<xe:appPage id="launchDoc" pageName="launchDoc" resetContent="true">
<xp:panel>
<xp:this.data>
<xp:dominoDocument var="frmDocument" formName="frmDocument">
</xp:dominoDocument>
</xp:this.data>
Next, this page will create a global JavaScript variable that is the URL of the actual page you want to open. This is the name of the XPage with the ?documentId parameter added in. I do this through a text field that does not convert its html:
<xp:text escape="false" disableTheme="true">
<xp:this.value><![CDATA[#{javascript:var html:string = "<script type=\"text/javascript\">\n";
var doc:NotesDocument = frmDocument.getDocument();
html += "var url = \"/";
html += @ReplaceSubstring(@DbName()[1], "\\", "/");
html += "/mobileDifferentXPage.xsp?documentId=";
html += doc.getUniversalID() + "\";\n";
html += "</script>\n";
return html;}]]></xp:this.value>
</xp:text>
When the mobile page opens, a variable called "url" will be created via JavaScript and set to the proper XPage to open (based on the data source inside this mobile page).
Later on we'll write the code that automatically redirects the user to this new URL. But in case the redirect doesn't happen, and also to give the user an indication of what's going on (they are on a mobile device, after all, so they might be on a slow connection), I include text of what's happening and a link they can click if the redirect doesn't happen.
<h4>
Please wait while your document is loaded. If it doesn't load in a few seconds, you can try the link below:
<xp:br></xp:br>
<xp:br></xp:br>
<xp:text escape="false" disableTheme="true">
<xp:this.value><![CDATA[#{javascript:var doc:NotesDocument = frmDocument.getDocument();
var newURL:string = "/";
newURL += @ReplaceSubstring(@DbName()[1], "\\", "/");
newURL += "/mobileDifferentXPage.xsp?documentId=";
newURL += doc.getUniversalID();
var html:string = "<a href=\"" + newURL + "\">Link To Document</a>";
return html}]]></xp:this.value>
</xp:text>
</h4>
</xp:panel>
</xe:appPage>
The panel and mobile page are closed out at the bottom. The URL is computed the same way, and I compute an HTML link for them to click if they want.
Finally, the code is needed to redirect the user. This is done OUTSIDE OF THE SINGLE PAGE APP. So I put it way at the bottom of the XPage - right before the "view" is closed (the XPage view). Note how it attaches itself to the mobile page "launchDoc" - that's key. After that mobile page is loaded, it runs the script. The script simply redirects the user to the page defined by the global JavaScript variable "url" which was set as the mobile page was being loaded.
<xp:scriptBlock>
<xp:this.value><![CDATA[dojo.addOnLoad(function(){
var page = dijit.byId("launchDoc");
dojo.connect(page, "onAfterTransitionIn", function() {
document.location = url;
});
});]]></xp:this.value>
</xp:scriptBlock>
Like I said, I think this is pretty clever. And it works great.