xpages: how to simulate form's auto launch properties - xpages

Is there a quick and easy way to convert forms that have auto launch first attachment and/or launch URL?
I know it can be coded in SSJS but I was just wandering if someone had a quick way of doing this.
Thanks

The following Domino URL command will open an attachment ...
http://Host/DatabaseName/View/DocumentName/$File/fileattachmentname
... where the DocumentName is effectively the lookup value shown in the first column which is sorted.
Add an xp:link control and code it open the attachment (in this example in a new window). For example, the following is an xp:link that could be added in an xp:viewColumn or xp:repeat or any iterator control. In this example the var for the iterator is set to "rowData" and the name for the link is returned from the ListName column and the url to launch the attachment is in the cLinkUrl column.
<xp:link escape="true" id="link1" target="_blank">
<xp:this.text><![CDATA[#{javascript:rowData.getColumnValue("ListName");}]]></xp:this.text>
<xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("cLinkUrl")}]]></xp:this.value>
</xp:link>

Since I wanted the code to be in the xpage, as it opens up either the document or the attachment depending on roles, I ended up adding this to the beforepageload event of the xpage (still need to add the role check to this though):
<xp:this.beforePageLoad>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:var url = currentDocument.getDocument().getHttpURL();
var attachmentName = #AttachmentNames();
facesContext.getExternalContext().redirect(url.replace("?OpenDocument","/$File/"+attachmentName+"?OpenElement&target=_new"));}]]></xp:this.script>
</xp:executeScript>
</xp:this.beforePageLoad>

Related

Customize Summary Detail Link in xPages Dataview

I'm using the DataView control from the xPages Extension Library and I would like to use the summary column link to expand rather than open a separate xpage with the current document. What is the best way to achieve this? I thought of using jQuery to click/trigger the expand link but I can't figure out how to pass the current row of the view into a javascript function in the summary column href property. Another option would be to call the same JS that the expand link is calling but that AJAX code seems to be sufficiently abstracted so as to not show up in a cursory analysis of the HTML code generated.
Update: added screen shot
Add CSJS code to viewSummaryColumn's href property to "click" on show/hide details image instead of opening the document.
Find the id of the details element
var id = '#{id:details}'
calculate the image id
id = id.replace(':details', '_shimg')
get parent's link element
var link = document.getElementById(id).parentElement
"click" the link
link.click()
"details" is the id of detail facet's panel. Your code should look like this:
<xe:dataView
...
collapsibleDetail="true">
<xp:this.facets>
<xp:panel
id="details"
xp:key="detail">
...
</xp:panel>
</xp:this.facets>
...
<xe:this.summaryColumn>
<xe:viewSummaryColumn
...
href="javascript:document.getElementById('#{id:details}'.replace(':details', '_shimg')).parentElement.click()">
</xe:viewSummaryColumn>
</xe:this.summaryColumn>
</xe:dataView>

XPages: Wait for backend document to be saved and reload

In one of my XPages application (for Client, XPiNC) I have a link to "Edit" an attachment of this document. I use the technology described in this blog article to get the attachment edited.
In that scenario I have three windows interacting:
The XPage (XPiNC) containing the document where the link is clicked
The Notes Document (called by notes:// URL) containing the attachment
The application window containing the launched attachment (e.G. MS Word).
I managed to let the notes document (2) wait for the application (3) to finish and upload the modified attachment.
Now I need the XPage to wait for the backend change to occur and then to reload the XSP Document from the backend document to prohibit save conflicts.
I think the easiest way would be to pull out the attachments to attachment documents that are responses to the current document, but this is a rather old application that has large amounts of data in many many databases, and it is not feasible to convert all of these existing documents for that.
Now I search for the second best way to do it.
So again the question: How can I make the XPage "wait" for a backend change to occur and then reload the current page.
Second: How do I best "visualize" to the user, that something is running in the backend (Spinner, fade out, etc.).
The servers are 9.0.1FP2, the Clients unfortunately are 8.5.3 (cannot be updated at the moment).
Here is the Code, that I use in my "Open" Link:
<xp:link escape="true" text="Edit" id="attachmentEdit">
<xp:eventHandler event="onclick"
submit="true" refreshMode="partial" refreshId="tableAttachment">
<xp:this.action><![CDATA[#{javascript:var strAttachmentName:String = docs.toString();
var strReplid = database.getReplicaID();
var strUnid = document1.getDocument().getUniversalID();
var strServer = #Name( "[CN]" , database.getServer() );
var strUrl:String = "notes://" + strServer + "/"+strReplid+"/(ShowAttachment)?OpenForm";
session.setEnvironmentVar("InfothekCurrentAction","EDIT~" + strUnid + "~" + strAttachmentName);
view.postScript('window.location.href="'+strUrl+'"');}]]>
</xp:this.action>
</xp:eventHandler>
</xp:link>
I am using an xagent for that. Thats what i do:
1) I am setting the background of a div to a moving css gradient.
2) Set the src of the div to an xagent that is doing some things in the backend
3) The xagent is calling some csjs after its loaded(in your case, you could call a button to refresh the page)
Take a look at this proof-of-concept demo: http://dontpanic82.blogspot.sk/2010/01/xpages-custom-control-that-can-help.html
Simple CSJS chcecks for updated property of the document. In case it was modified (attachment saved), you can show pop up or just reload the XPage.

How to change url parameter openDocument to EditDocument from a client side link in XPages

I have a data source called "doc" and a link control on my xpage. The datasource is bound to a document using the url parameter
documentId=914A....&action=openDocument
When I click the link control I want to change the url parameter action to "editDocument" so that my data source goes into edit mode.
I would like this to be a client side solution, so I am thinking it can be done by constructing the url using EL, so something like this.
<xp:link escape="true" text="Edit Mode" id="link5" value="/documentID=#{doc.getUniversalID...}?action=editDocument"></xp:link>
any ideas?
Thanks
Thomas
What about simply changing the location.href by replacing "openDocument" with "editDocument"?
location.href = location.href.replace(\openDocument\g, "editdocument");

learning how to use xe:dominoViewEntriesTreeNode

I realized my question was too vague on adding navigation items dynamically, so I am rewriting the question.
I have discovered the xe:dominoViewEntriesTreeNode control from the xpages. I think I can use this to add navigation items to the navigator control based on entries in the view.
I am struggling to find very much in the way of documentation or resources that break down how to do that. Can anybody to me to a good reference or example code?
You can use dominoViewListTreeNode to build a menu based on views in a database (and not documents in those views).
Here is an example of using xe:dominoViewListTreeNode to dynamically build a menu based on all views called "Test*" (using regex in the filter property). When selecting a menu item from the menu, the name of the view is submitted to the server (using EL notation for the viewEntry.getName() method).
The example also contains an onItemClick event handler that "catches" the name of the view as the submitted value and stores this in a sessionScope variable. The event handler then redirects to a views.xsp XPage that could contain a Dynamic View Panel control where you could use the sessionScope variable to control what view to show.
The sessionScope variable is also used to mark the selected menu item as "selected".
<xe:navigator id="navigator1">
<xe:this.treeNodes>
<xe:dominoViewListTreeNode filter="Test.*" submitValue="#{viewEntry.name}" var="viewEntry">
<xe:this.selected><![CDATA[#{javascript:viewEntry.getName() == sessionScope.clickedView}]]></xe:this.selected>
</xe:dominoViewListTreeNode>
</xe:this.treeNodes>
<xp:eventHandler event="onItemClick" submit="true" refreshMode="complete">
<xp:this.action>
<![CDATA[#{javascript:sessionScope.clickedView = context.getSubmittedValue();
context.redirectToPage("views.xsp");}]]>
</xp:this.action>
</xp:eventHandler>
</xe:navigator>
Instead of the onItemClick method to redirect to an XPage, you could compute the href property of xe:dominoViewListTreeNode to return the name of an XPage.
I have a short presentation called "XPages Extension Library - Create an app in 1 hour (almost)" that presents this technique (and other techniques).
I assume you have an area on your page carrying the navigation items, e.g. links to some pages with link texts?
I would then use a repeat control with a datasource/javascript source that returns the document item values from your profile document or something.
If you are not into repeat controls then you should consider to read this: http://xpageswiki.com/web/youatnotes/wiki-xpages.nsf/dx/Work_with_repeat_controls
On this page there is also a sample dealing with a profile document.
By the way: using profile documents was always a crutch, so consider to youse "normal" config documents instead.

Creating a response document via a button

I have two forms, Organisation and Contact. Contact is a response to Org, and each form has an XPage where the form can be filled in, saved etc. When opening edit_contact.xsp directly and creating a document (not as a response to an org), everything works fine.
On edit_org.xsp, I have a button with 2 events. The first copies some values into sessionScope so I can inherit them into the Contact. The second is a "Create Response Document" event which creates a new response with the parent ID being the current org document, and sends the user to edit_contact.xsp. Pressing the button changes XPage correctly and the field inheritance works fine, but pressing "Submit" on the Contact form doesn't save anything, and no document is created.
This exact same setup works 100% as desired in another database, I have no idea why it won't work properly here. Is there an obscure setting somewhere I am missing?
<xp:button value="Create Contact" id="button1" rendered="#{javascript:!document1.isEditable()}">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:executeScript>
<xp:this.script>
<![CDATA[#{javascript:var doc = document1.getDocument();
sessionScope.PFirstName = doc.getFirstItem("P_Firstname").getValueString();
sessionScope.PSurname = doc.getFirstItem("P_Surname").getValueString();
sessionScope.PFamily = doc.getFirstItem("P_Family").getValueString();
sessionScope.PDOB = doc.getFirstItem("P_DOB")
sessionScope.PAGE = doc.getFirstItem("P_Age").getValueString();}]]
</xp:this.script>
</xp:executeScript>
<xp:createResponse name="/edit_contact.xsp" parentId="#{javascript:document1.getNoteID()}">
</xp:createResponse>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>`
Here is a link that shows what I am trying to do (minus the field inheritance):
http://min.us/mKSJED8tT
Currently the forms and views all work, but the document created with the "Response" form appears not to be a response document - it has no $REF field. This setup works perfectly in a different database - what is going on?
It's hard to tell what might be happening without seeing any code. Since it works for you in another database, could it be an ACL issue? Where the user you're logging in as - possibly - anonymous - doesn't have the ability to create documents?
Instead of "push" approach go for "pull" - just open response page with url parameter of parent document. In its postNewDocument event initialize field values from it.
It would be useful to get an update on two key points made by others:
Is ignoreRequestParams set on your response document datasource? If not, regardless of what you're trying to define for the second datasource, it's UNID etc are pulled from the request parameters. So both datasources are effectively the same datasource.
Is it throwing a validation error? If so, nothing will be saved.
There are two possible issues:
First the use of getFirstItem("x") is not a best practice. So:
sessionScope.PDOB = doc.getFirstItem("P_DOB")
would be storing a NotesItem in the sessionScope which will not work. It is recommended to use:
sessionScope.PDOB = doc.getItemValueString("P_DOB");
Second the use of getNoteID() might not be returning what you want (Which is the UNID of the document). Use .getDocument().getUniversalID() instead.
<xp:createResponse
name="/edit_contact.xsp"
parentId="#{javascript:document1.getDocument().getUniversalID()}">
</xp:createResponse>
-edited-
/Newbs

Resources