Glen Urban's Notes/Domino/XPages Blog

 
alt

Glen Urban

 
Glen Urban is a XPages / Lotus Notes/Domino developer/system admin located in the North East of England. He works for Axiom Engineering.

Row Selection in Repeats using a Checkbox Bound to a Bean

Glen Urban  August 22 2013 03:39:24 PM
If you have been developing "view" like controls with repeats you will at some point have to find a method to select rows/documents within your repeat.

A common method seems to be the one described in this Notesin9 video. I have used a variant of this widely, using SSJS in the onclick event of a check box to store selected document IDs in a scoped variable. This has worked well but I have experienced performance problems for large sets of data: check boxes became unresponsive and did not keep up with users when selecting multiple rows.

So I wanted to explore an alternative solution. This alternative method uses a check box bound to a java map in a bean. This means that selecting/de-selecting the check box does not fire an event that sends data to the server.  The check box is in a custom control and bound to the bean like this:
Image:Row Selection in Repeats using a Checkbox Bound to a Bean
This allows you to store selected Note IDs, or your own unique IDs. They can be retrieved using a call to the bean like this: SelectedDocs.getSelectedIDs()

A demo DB is attached for those who wish to explore the code further. Please note I have only tested this with Release 9.0

How to Implement in another database

1) Add the package uk.co.norstrong.rowselect to your DB

2) Update faces-config.xml

Image:Row Selection in Repeats using a Checkbox Bound to a Bean
If you set the scope of the bean to request then it will behave like a standard view control and lose row/document selections when paging in your repeat. If you set the bean scope to view then selections can persist between different pages but you must set the partialExecute property of the pager to false...
Image:Row Selection in Repeats using a Checkbox Bound to a Bean

3) Add the custom control ccRowSelectCheckBox to your repeat.

It has the following properties:
docID It makes sense to use the NoteID but it could be any unique identifier.
containerID Optional. The ID of the container e.g. a table row or a div. The selectedClass will be applied to this ID.
selectedClass Optional. The CSS class to apply to the containerID when it is selected. Client side JavaScript is used to change this.

To get a vector of selected document IDs in SSJS use: SelectedDocs.getSelectedIDs()
To set an individual check box state use: SelectedDocs.setSelectedState(id,boolean);


So far I haven't used this method widely so I wondered if others have used a similar method? And if so have you experienced any issues with it? Any feedback would be gratefully appreciated.

Quick Tip: Creating type ahead help in your Java Classes

Glen Urban  December 23 2012 12:08:28 PM

Want to create type ahead help like this?...

Image:Quick Tip: Creating type ahead help in your Java Classes

You need to add comments to your code like this...

Image:Quick Tip: Creating type ahead help in your Java Classes


Things to remember
  • You start the comments with /** and end with */
  • Comments should appear immediately before the Class or Method you are documenting.
  • You can link to the comments in other classes or methods by using the tag @link e.g. {@link makeUnFriendlyNoise} in the screen print above.
  • There are various tags you can use e.g. @author, @param and @return, see here for more.
  • Comments are HTML so you can include p li tags etc.

Making enableModifiedFlag Work Across Tabs in a Tabbed Panel

Glen Urban  February 16 2012 12:58:53 PM
Problem
Setting the enableModifedFlag on an XPage...

Image:Making enableModifiedFlag Work Across Tabs in a Tabbed Panel

will warn the user if they try to navigate away from the XPage without saving data.

However in a Tabbed Panel this doesn't always work. For example:
1) Update some data on the first tab (your page is now dirty)
2) Move to the second tab but don't update any data on that tab
3) Navigate away from the page
4) The page is dirty but the Confirm Navigation prompt doesn't show


Solution

For version 8.5.3 then simply set partialRefesh for the Tabbed Panel to true
Image:Making enableModifiedFlag Work Across Tabs in a Tabbed Panel


For version 8.5.2 (or earlier?). Partial Refresh on a Tabbed Panel was introduced in 8.5.3 so the work around is...

For each Tab in your Tabbed Panel add the following Server Side JavaScript to the onclick event

You need to change mainTabbedPanel to the ID of your Tabbed Panel and tab1 to the ID of the current tab.
Image:Making enableModifiedFlag Work Across Tabs in a Tabbed Panel

Use a Partial Update and select a div that wraps around theTabbed Panel as the target.
Image:Making enableModifiedFlag Work Across Tabs in a Tabbed Panel

Notes Doclinks going to the wrong server?

Glen Urban  May 19 2011 03:02:02 PM
When you generate emails with doclinks are users complaining it takes them to a server on the other side of the world? If so, take a look at the Catalog on the server specified as the "Catalog/domain search server" in your Location Document. Look at the "Applications by Title" view. Are there multiple servers listed for the application (database) where the doclinks came from? This could be a problem...

What Should Happen With DocLinks?

This technote from IBM lists the steps Notes takes to determine which server to use:

1) Use the icon for the replica on the user's workspace if one exists.

Assuming the user hasn't opened the application before then they won't have an icon on their workspace so the search goes to step 2.

2) If using Catalog/Domain Search, this will be used to locate* a replica.

This is further qualified by the statement: The search will open the catalog and find the "best" server choice containing a replica, searching by server name alphabetically. The best choice considers server availability.


A Potential Problem

When the search gets to step 2 you may be using, for example, server "USA1" but if the first server under your application in the "Applications by Title" view is called "AUSTRALIA1" then the doclink will be opened on AUSTRALIA1. I've also seen this cause embedded views to open on the wrong server and @DBlookups, where the database was specified using a replica ID, to lookup to the wrong server.

What about the statement The best choice considers server availability ? The technote doesn't elaborate on how Notes evaluates "availability". I suspect it chooses the first server in the same Notes Network. In the organisations that I've come across this problem all the servers we're in the same Notes Network (which is probably not recommended).

How Can I Fix It?

I resolved this by re-configuring the catalog to show only applications that have replicas on that server. For example, on server USA1 the catalog would only list replicas found on USA1. So when the Notes client looks for the location of an application in the catalog (step 2 above) it will always return a replica on USA1. In a typical Hub and Spoke topology this can be achieved using the ACL of the catalog. On the spoke servers, e.g. USA1, I ensured the Hub server is restricted to reader access and USA1 had manager access. This prevented the Hub server from adding entries to USA1's catalog but allowed it to read them and compile a full list of all applications, and their servers, on the Hub.

This solution resolved the issue for new users, or existing users opening applications they hadn't used before. But it didn't resolve the problem where users already had icons on their workspace that point to the wrong server. In this instance you can write code to re-stack the workspace icons, for example, something like this from Tommy Valand.

A Word of Warning About Testing

If you delete all the workspace icons for an application and then change the catalog server specified in your Location Document then you may think that Notes should start looking in the new catalog. But it doesn't! Even if you delete desktop8.ndk and bookmark.nsf Notes will still remember where it's been before. If you look at the document properties for your Location Document then you'll find several fields that are used for caching e.g. $LastFileNames and $StackFileNames. There's all sorts of caching going on in there. So it's best to delete desktop8.ndk, bookmark.nsf and create a new Location Document. This does make testing a pain!

Image:Notes Doclinks going to the wrong server?

XSP.isViewPanelRowSelected: How to confirm if documents are selected in your XPage view control

Glen Urban  May 16 2011 12:47:45 PM
How do you make your XPage buttons work like the standard "Simple Action" Delete button and prompt you if you haven't selected any documents?

If you look at the HTML source of an XPage with a delete button you will see a call to XSP.isViewPanelRowSelected. This accepts two parameters, the first being the name of your view control. If you don't change the default this will be "viewPanel1". The second parameter, I believe, is referring to the actual tick boxes in the view control. So far I haven't needed to change this from "_colcbox".

So here's an example for an "Approve" button...
Image: XSP.isViewPanelRowSelected: How to confirm if documents are selected in your XPage view control

Any server side JavaScript won't get executed unless there a documents selected and you have confirmed you wish to continue.

You can find out more about the XSP JavaScript Library here

XPage: Unresolved compilation problem: The code for the static initializer is exceeding the 65535 bytes limit

Glen Urban  February 3 2011 03:27:18 PM
When adding an XPage front-end to an existing Notes client application I came across the following error message previewing the XPage:
"Unresolved compilation problem: The code for the static initializer is exceeding the 65535 bytes limit".

The original Notes form had lots of fields on. My new XPage worked at first but I hit the error as I added more fields. It looks as though I hit a Java limitation. Splitting the XPage fields onto separate Custom Controls resolved the problem.

Shared Actions Not Replicating?

Glen Urban  February 3 2011 03:02:11 PM
I came across a strange problem where modifications to existing Shared Actions, and new Shared Actions, did not replicate from local replica to server, or from server to server. After a lot of head scratching a view of design elements helped me track down the problem. Kevin Petit first made me aware of how to create such a view on his blog here.

All the Shared Actions in a database are stored in one Note. But if you look at the screen print of the design elements view below you can see two "Notes" (documents) for Shared Actions. Some how a replication or save conflict had occurred. Notes seemed to pick at random which set of Shared Actions to use in separate databases.

Image:Shared Actions Not Replicating?

Deleting one of the Shared Action documents resolved the problem.

IsArrayInitialised()

Glen Urban  August 4 2010 12:56:42 PM
Surprisingly LotusScript doesn't provide this but here's a function to test if a dynamic array is initialised.

Function IsArrayInitialised(a As Variant) As Boolean
 'returns True if an array is initialised
  On Error Resume Next
  IsArrayInitialised = False
  IsArrayInitialised = (Ubound(a) >= Lbound(a)) ' will generate error if not initialised    
End Function

NotesDatabase.Server Inconsistency

Glen Urban  April 13 2010 03:42:32 PM
Consider the following LotusScript code
Dim session As New NotesSession
Print session.CurrentDatabase.Server


Would you expect the server name to be in an Abbreviated (e.g. SERVER/GB/ACME) or Canonical format (e.g.CN=SERVER/OU=GB/O¬ME )?

The answer is "it could be either": I experienced a problem in some code that depended upon this property, on one Notes client it evaluated to an Abbreviated name and on another to a Canonical name. Both clients were 8.5.1. Both running on the same server. The only obvious difference was that the designer client was installed on one client machine but not the other.

I resolved the problem by forcing a conversion to a canonical format so that the code worked regardless of how database.server decided to return the name.

Has anyone else experienced this problem?

notesUIWorkspace.RepaintScreen()

Glen Urban  March 11 2010 04:21:34 PM
Ever wished you had a method to repaint the screen?

Recently I was working on some automation with Microsoft Word and wanted to display a message to the user warning them that the processing may take a while. I used a hide-when formula to display a message on my form but I found that the screen did not repaint correctly. Some controls on the form that should have been hidden were still displayed.

As far as I know there is no way in LotusScript to repaint the screen. To resolve this we can make a call to Windows to do the refresh for us.

Declare Function GetActiveWindow Lib "user32" Alias "GetActiveWindow" () As Integer
Declare Function UpdateWindow Lib "user32" (Byval hWnd As Integer) As Integer

Sub RepaintScreen
On Error Resume Next
Call UpdateWindow(GetActiveWindow())

End Sub