XPages Pager with Last and lots of pages - xpages

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.

Related

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?

How var in view works - 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>

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.

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.

Setting "title" attribute on <xp:selectItem> in a Combo Box

I have a combo box with descriptions that are long in length. I'm trying to find the best way to show the full description. One thing I came across was the title attribute which causes a popup to show on hover. I tried to use the "attrs" property in XPages to add a title property, but xp:selectItem and xp:selectItems "attrs" do not appear in the HTML output.
Anyone have any ideas or a different method to try? Thanks for any thoughts.
EDIT: I ended up changing the combo box into a dialog pick list. This satisfied my requirements.
Did you consider using xe:djComboBox from Extension Library?
See http://www-10.lotus.com/ldd/ddwiki.nsf/dx/djComboBox_Dojo_Combo_Box_ddxl853
<xe:djComboBox id="djComboBox1" value="#{sessionScope.djComboBox1}"
tooltipPosition="auto">
<xe:this.dojoAttributes>
<xp:dojoAttribute name="autoComplete" value="false">
</xp:dojoAttribute>
<xp:dojoAttribute name="labelType" value="html">
</xp:dojoAttribute>
</xe:this.dojoAttributes>
<xp:selectItems>
<xp:this.value>
<![CDATA[#{javascript:return new Array("<b>Apples</b>|apples", "Oranges|oranges")}]]>
</xp:this.value>
</xp:selectItems>
</xe:djComboBox>
Each element in array should have following format "label|value|description|disabled", where only label is mandatory. See: http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/index.jsp?topic=%2Fcom.ibm.designer.domino.ui.doc%2Fwpd_controls_cref_selectitems.html
If the description of your items is so long that they dont fit in a combobox you could either:
Change the length of the combobox using css.
Retrieve the description and only display a portion of it (lets say first 100 chars ).
Descriptions in comboboxes should be 'descriptive' ( hence the word description ). I would go for the second approach and add something in front of the description so the description is still usefull for the users.
For instance when have a list of projects. These titles are 100+ characters long. Instead of displaying the full description. Cut them of and use the project code as a prefix so that it will display
ProjectCode - {first 100 chars of description}.
This way users still know what they select because of the project code.

Resources