Customize Summary Detail Link in xPages Dataview - xpages

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>

Related

xpages: how to simulate form's auto launch properties

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>

Show custom controls on webpage in other order than layed out in DDE - Xpages

I have a number of custom controls layed out on an xpage. I want these controls to be displayed in the order of a setting in a notes document
So my xpage might look like this in DDE
CustomControl1
CustomControl2
CustomControl3
CustomControl4
but when the custom control is displyed on the webpage the custom controls should be displayed in the following order (based on the setting document)
CustomControl4
CustomControl1
CustomControl2
CustomControl3
anyone have any ideas how to accomplish this (server side)
You can use the xp:switchFacet in combination with a xp:repeat to calculate the order at runtime like this:
<xp:repeat
id="repeat1"
rows="30"
var="rowEntry">
<xp:this.value><![CDATA[#{javascript:var arr = ["Control1","Control3","Control2"];return arr;}]]></xp:this.value>
<xe:switchFacet
id="switchFacet1"
selectedFacet="#{javascript:rowEntry}">
<xp:this.facets>
<xp:panel xp:key="Control1">Control1</xp:panel>
<xp:panel xp:key="Control2">Control2</xp:panel>
<xp:panel xp:key="Control3">Control3</xp:panel>
</xp:this.facets>
</xe:switchFacet>
</xp:repeat>
Instead of the Array arr you can use data based on a document or xsp.propertie. The Output of this code is Control1 Control3 Control2 and in your Designer you have your controls inside switchFacet in following order: Control1 Control2 Control3.
Without knowing the real pain of your project I can only assume that the individual position needs to be defined at runtime, or something like that.
In general: controlling a page's layout is a pure CSS job. On the resulting page almost anything can be positioned almost anywhere within the page's range, and it doesn't matter where it was placed at design time. So, if you enclose your custom controls within their own containers (panels / divs) then you should be all set. You might define positioning classes in CSS and then have some SSJS code decide which class is assigned to what div.
If for example you have a custom control for each day of the week, and you always want to have the current day at the top-most position, then you could define 7 css classes as in ".today", ".todayPlus1", ".todayPlus2" ... ".todayPlus6". Write your positioning rules for each class. And finally compute each panel's styleClass property based on the current week day.

How do I get the category filter to work with Xpages cloud tag

I have set up a tagcloud from the extension library in Xpages. But what I cannot get to work is when the user clicks on a cloud tag entry, they go to the categorized view but it doesn't position to that category or subset to only that category.
I checked the Xpages Extension Library demo and can't figure out how it is supposed to work.
Any help would be greatly appreciated.
Bryan
You can show all entries from view for a clicked tag:
(1) Create a categorized view in which the tags you want to show are in first categorized column. Add in following columns the values you want to show for a tag.
(2) Put in dominoViewCloudData this view name, the XPage which has to be called when a tag is selected and the parameter name for url where the selected tag will be provided
<xe:dominoViewCloudData
...
viewName="yourViewName"
linkTargetPage="/TagViewEntryList.xsp"
linkRequestParam="tag">
</xe:dominoViewCloudData>
(3) Create the target XPage with a view control and set the categoryFilter to selected tag. You can read the tag from url with param['tag']. If your tag can contain space characters then you have to replace the "+" from url back to space with replace()
<xp:viewPanel
...
<xp:this.data>
<xp:dominoView
var="view1"
viewName="yourViewName">
<xp:this.categoryFilter><![CDATA[#{javascript:
var tag = param['tag'];
if(tag) {
return tag.replace("+", " ");
} return null}]]>
</xp:this.categoryFilter>
</xp:dominoView>
</xp:this.data>
<xp:viewColumn
...
</xp:viewColumn>
</xp:viewPanel>

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.

Dynamically add custom control on Xpage

how can I add custom control on the basis of sessionScope variable. I try include page container control but no luck:
<xp:this.afterPageLoad><![CDATA[#{javascript:sessionScope.put("viewName","ccViewAll.xsp");}]]></xp:this.afterPageLoad>
<xp:text escape="true" id="computedField1">
<xp:this.value><![CDATA[#{javascript:sessionScope.get("viewName")}]]></xp:this.value>
</xp:text>
<xc:appLayout>
<xp:this.facets>
<xp:panel xp:key="facetMiddle">
<xp:include id="include1">
<xp:this.pageName><![CDATA[${javascript:sessionScope.get("viewName")}]]>
</xp:this.pageName>
</xp:include>
</xp:panel>
</xp:this.facets>
</xc:appLayout>
The above code give me error Error 404 HTTP Web Server: Item Not Found Exception. But when I hardcode the viewname that is ccViewAll.xsp instead of sessionScope.get("viewName"), its work fine.
-MAK
You can use the dynamic content control or the switchFacet control if you have the ExtLib for XPages. The Teamroom template (demo application that comes with the ExtLib) uses these in the "allDocuments" Xpage or the "allDocsAllTab" custom control, these are good examples to look at.
If you don't have the ExtLib you could use the loaded / rendered property of a custom control to decide which one gets loaded.
e.g.
<xp:panel key="MiddleColumn">
<xc:customControl1 loaded="${javascript: if(viewScope.control == "customControl1")}"></xc:customControl1>
<xc:customControl2 loaded="${javascript: if(viewScope.control == "customControl2")}"></xc:customControl2>
</xp:panel>
loaded = false means that nothing will be done for this control.
rendered = false means that the control will be created but hidden, you can change this later to show it.
use rendered if its going to change for example when a button is clicked and loaded when its decided at start up and won't change while the user is logged in.
If you are using this to show a different view in the domino database based on some other selection that I would suggest looking at the Extension Libraries 'Dynamic View Panel' control.
Using this control means you won't need to create different custom controls for each view that you want to use, just a single page with this control and point it to the correct view to display via a scope variable.
If you need to customize how each view displays you can create a viewControl bean to set additional properties based on the view that it is showing.
Something worth to mention is that if you don't use the ExtLib - If you're using Partial Refresh then you HAVE to use the rendered property, since the loaded property only can be calculated on pageLoad.
From my understanding this means that every custom control will be computed by the server and that's probably not something you want. (Added overhead, for one thing.)
/J

Resources