How var in view works - Xpages - xpages

In view, I set var in All Properties to "rowVar".
Code for viewColumn.
if (!rowVar.getDocument().getItemValue("NAPAKA").isEmpty()) { return "NAPAKA"}
else {return rowVar.getColumnValue("STANJE")};
And code for this.rowClasses:
if (!rowVar.getDocument().getItemValue("NAPAKA").isEmpty())
{return "hoverCls napakaBlue";}
else{return "hoverCls";}
Former works for view with no documents, but later throws exception. Why?

The first one belongs to the view column. So if there is no document, that will not be evaluated.
However the second one will be evaluated everytime the view is rendered. Therefore if there is no document, rowVar will not exist and your code will fail.
In your rowClasses formula, you can add a condition as the following:
if(requestScope.containsKey("rowVar") && ...(your conditions)...)
Since row is not going to be exist in anyway, null-checking will also fail.

Serdar's answer is correct. This answer is just about efficiency.
If you are dealing with many documents in the Domino View data source, you should add the NAPAKA column to the Domino view and avoid the rowVar.getDocument() to the underlying document which in not efficient. Also, you can improve efficiency by using EL instead of SSJS. For example:
<xp:viewColumn id="viewColumn3" value="#{(empty rowVar.NAPAKA) ? rowVar.STANJE: rowVar.NAPAKA}">
<xp:this.facets>
<xp:viewColumnHeader xp:key="header"
id="viewColumnHeader3" value="column header">
</xp:viewColumnHeader>
</xp:this.facets>
</xp:viewColumn>

Related

XPages Pager with Last and lots of pages

I am looking at a way to bypass a bug in the standard pager with views that contain a large numbers of documents. When I use the code below, the "Last" won't show up:
<xp:this.facets>
<xp:pager layout="First Previous Group Next Last" xp:key="header"
id="pager1" for="myView" partialRefresh="true">
</xp:pager>
Anyone got around this, or has an alternate solution?
Set the alwaysCalculateLast property on the xp:pager to true to calculate the last document in the view. There can be a performance hit when this is set to true, though.

XPages - how to show all records in xp:repeat control al once?

On my XPage I have a datasource defined which is a filtered view:
<xp:this.data>
<xp:dominoView var="viewItems" viewName="myTodoList">
<xp:this.categoryFilter><![CDATA[#{javascript:return sessionScope.get("userFilter");}]]></xp:this.categoryFilter>
</xp:dominoView>
</xp:this.data>
I want to display the data via a repeat control. But I want to display ALL the records in the data-set. How much I compute the xp:this.rows property?
<xp:repeat id="repeat1" value="#{viewItems}"
var="obj" indexVar="idx">
<xp:this.rows><![CDATA[#{javascript:getComponent("repeat1").getDataModel().getRowCount()}]]></xp:this.rows>
</xp:repeat>
The rows property in fact just sets "cut-off" when paging starts. Instead of (vastly) computing current size of the view, just set it to "large enough" value. Magic constant "9999" worked for me, but MAX_INT is the limit, I think.
Bear in mind that for huge amount of data it will take a while to render your page, so you definitely WILL call for performance problems.
Also, there is internal limit ~10k back end C API references for Java Notes* classes - when hit, server/client CRASHES. You should be safe with pure XSP components. Once you spice up your pages with extra code that uses Notes* classes (and does not recycle), especially inside loops/repeats, your limit will be just a fraction of that value.
You need to get the item count from your DominoView, not the rowCount from the component’s data model.
You might be careful what you want to do here, a view can potentially be VERY large and user experience be bad.
The extension lib has “infiniScroll” that might be more suitable to what user expect.
Have you tried?
<xp:this.rows><![CDATA[#{javascript:var vw:NotesView = database.getView("myTodoList");
return vw.getAllEntriesByKey(sessionScope.get("userFilter"),true).getCount().toFixed();}]]></xp:this.rows>

How to get a sequential number of all the documents in a view

How to get a sequential number of all the documents in a view. The sequential numbers will appear in a column of a view. I have used #DocNumber but it does not work when I preview my View from xpage page.
See https://www-10.lotus.com/ldd/ddwiki.nsf/dx/List_of_Formula_Not_Supported_In_XPages. #DocNumber is not supported in XPages.
If you use viewPanel, there exists one simple solution.
Set the var property of your viewPanel to some meaningful name you like, e.g.
<xp:viewPanel var="viewEntry" ....etc....>
</xp:viewPanel>
By doing this, you provide yourself an explicit access to every iteration of DominoViewEntry (viewPanel uses it internally).
Then create a view column, don't set columnName property, set the value property. Like this:
<xp:viewColumn value="#{javascript:viewEntry.getPosition('.')}"
id="docNumberColumn">
<xp:viewColumnHeader value="Doc Number"
id="docNumberHeader">
</xp:viewColumnHeader>
</xp:viewColumn>
Sorry, no way to avoid SSJS here, because DominoViewEntry does not expose getPosition() method to its getValue() implementation, so we have to call it directly.
Update: this should work for dataTable and dataView as well, because all of them use UIDataIterator behind the scenes and both have var property.
Use repeat control and display the index number?

Can I prevent embedded view from putting a database on the workspace?

I have two databases, A and B. I want to surface a view from B into A. I can do this using an embedded view in an outline or a form and it works fine.
But I do not want database B put on a user's workspace. If I add it and the user opens a doc or opens the view, then it puts that db on the workspace.
Is there a way around this? What if I embed an Xpage?
That's a built-in behavior of Lotus Notes and unfortunately there's no way to turn that behavior off.
As an alternative you could write an Agent that pulls the data in from Database B into Database A, and then just display that data within a Database A view.
As Ken already said that it is a built-in behavior. You can try to programmatically remove the database icon. This Technote describes it.
#Command([AddDatabase]; "Server Name":"DatabaseB.nsf");
#Command([WindowWorkspace]);
#Command([FileDatabaseRemove]);
I haven't tried it myself, but you can put this code on close of form of embedded view. Also, its not possible to remove a database icon from the Notes client workspace using LotusScript, JavaScript, or Notes API.
It works as Naveen describes it. However, even if you manage to clean up the icon, in Notes there is a built-in fault when using an embedded view from another database.
The problem is -- you cannot use the traditional Notes templates because the link to the source database of the embedded view is hard-coded using the replicaid. So if you pull a template from your design and create a new database for production, the embedded view will still point to your test database.
I have used this configuration, but then each time you deploy a new template you need to modify design, so that it points to the correct database. It can be programmed for example by using DXL export/import but is not a trivial Notes deployment any more.
Multiple options here: computed text to display the contents of the view using HTML, creating an Xpage that displays the view, or some AJAX to get the data and display in HTML.
Computed text to display the view
This is relatively simple. Add computed text, set to use pass-through HTML, that does a DbColumn on a new view in the source database. Either add a hidden column at the end of the existing view or create a new, single column view that has the HTML for a single row in the view.
For the computed text, just a simple formula:
"<table>" + #DbColumn( "Notes" : "NoCache" ; "MyServer/Company" : "SourceDatabase.nsf" ; "HTMLview" ; 1) + "</table>"
Then, for the column formula, use something like this:
"<tr><td>" + PartName + "</td><td>" + PartNumber + "</td><td>" + Price + "</td></tr>"
XPage for view
Just create the XPage with a simple view, like this:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:viewPanel rows="30" id="viewPanel1">
<xp:this.facets>
<xp:pager partialRefresh="true" layout="Previous Group Next" xp:key="headerPager" id="pager1">
</xp:pager>
</xp:this.facets>
<xp:this data>
<xp:dominoView var="view1" viewName="COPApprovals"></xp:dominoView>
</xp:this.data>
<xp:viewColumn columnName="$11" id="viewColumn1" style="font-weight:bold;color:rgb(0,0,160)">
</xp:viewColumn>
<xp:viewColumn columnName="$10" id="viewColumn2" style="font-weight:bold;color:rgb(0,64,0)">
</xp:viewColumn>
<xp:viewcolumn columnName="$12" id="viewColumn3">
</xp:viewColumn>
</xp:viewPanel>
</xp:view>
AJAX
A good intro to using AJAX to display Notes data can be found in Scott Good's AJAX name-picker. I've built a number of views and picklists using that format. The laptop that has the modified designs is on the fritz right now. If I get access again, I will post samples.
Hope you get some ideas there.

How do I change the viewColumnHeader in Xpage?

I want to change the view column header's value in Xpage...
I have used the following code
getComponent("viewColumnHeader1").setValue("Test")
But the above code throws the getComponent() is null error...
Why not just compute the "Label" property for column header to begin with:
<xp:viewColumn columnName="fldTest" id="viewColumn1">
<xp:viewColumnHeader value="testing" id="viewColumnHeader1"></xp:viewColumnHeader>
</xp:viewColumn>
Hope this helps.
Your code is correct but the problem is probably in where you've placed it.
Just performed a quick test and the code works if you place it in the afterPageLoad event of an XPage containing the view/ header.

Resources