Showing posts with label xpages. Show all posts
Showing posts with label xpages. Show all posts

Tuesday, 18 September 2012

First Xpages & beer session

After some discussions between a couple of xpages developers, Martin Meijer, Mark Leusink and the guys from Clear IT Consulting organised the first Xpages & beer session in Hengelo (ov), the Netherlands on wednesday 12 september 2012.

The format is simple have a couple of presentations and discussions and finish with a beer.
The presentations for this first edition were by

The idea is continue this initiative every quarter and the second edition is planned for wednesday 12 december 2012 at the e-Office location in Houten (NL).
So if you missed the first edition, put the next one on your calendar. See you there.

I really enjoyed watching the presentation and talking about xpages development and will definitely be there for the next edition.
A big thank you to Martin, Mark and Wim  for organising the first Xpages & Beer

Photo courtesy of Clear IT Consulting

Tuesday, 22 November 2011

XSnippets - do not reinvent the wheel


A gem for code sharing was launched about a month ago on OpenNTF, XSnippets
. It contains small re-usable chunks of code related to Xpages.
The UI is very simple and userfriendly and finding that codefragment you need in your next project should not be a problem. The code snippets are even colour coded.

Hopefully all those great contributors of code to the Notes Domino community will gradually copy their pieces of code to this site. That would make XSnippets the place to look first and avoid reinventing the wheel.

Monday, 10 October 2011

Xpages Internationalisation

Working in Europe for a multinational, providing a multi-lingual website is not an option, it is a must. So the option for internationalisation in Xpages is very welcome.
The standard xpages localisation option (in the application properties) creates a properties file per specified language per custom control/xpage. Works great, but it does create a lot of maintenance work if things needs changing afterwards or when you add a language.
There is another option available which is not as automated like the xpages localization, but in the long run will probably turn out to be more flexible when doing maintenance or adding an extra language.
Here is how it works:

- For every language create a properties file, a flat text file with the extension .properties and make them available to the application through the "file resources". For ease of use name these files something like english.properties, dutch.properties, etc. In the properties files add name-value pairs separated by the equals sign (=) for labels, buttons etc. in your applocation that you want translated.
     login_text=Login
     logout_text=Logout
     menu_text=Menu
     ....

- In a custom control that loads on every page in the application, e.g. an initialisation custom control, in the resources properties add a resource bundle, name it something like "lang" and compute the location to the desired language properties file, e.g. using the browser language setting or for testing as simple as below..
     return "/dutch.properties";

- Next go through all the xpages and custom controls and change the fixed text of labels, buttons, etc. by a value from the properties file set in the resources.
     lang.login_text

- After setting all the necessary entries in the properties file for the default language, create the file resources (copy) for the other languages. To spot not translated labels in the application, you can prefix them with the target language.
     login_text=[EN]Login
     logout_text=[EN]Logout
     menu_text=[EN]Menu
     ....

This process is best done at the end of the development phase of a project and work with a default language until than.

Used sources:
xpages101.net

LND Application dvlp wiki

Wednesday, 28 September 2011

Keep view position between (x)pages

By default xpages doesnot keep the position of the view (pageno.) when going to another page. So when you go back to the view page from another page, the view will display from the first entry (and page) again. Not very userfriendly if you had just left it from page 3.
You will have to make the view page remember its position by storing the number of the first row on the page in a scoped variable.
In the "beforeRenderResponse" event add the following code:

   var c = getComponent("viewPanel");
   if (c) {
       sessionScope.put("viewFirst"+view.getPageName()
, c.first);
   }
"viewPanel" is the id of your view control of course.
And in the view control's All properties - first - add the code:

   var vwFirst = sessionScope.get("viewFirst"+view.getPageName());
   if (vwFirst) return vwFirst;

This will also work when displaying data tables through a repeat control.

Used sources:
xpageswiki.com 

 

Tuesday, 13 September 2011

Final version of DbLookupArray & DbColumnArray

Time to post the final version (I think) of the DbLookupArray and DbColumnArray functions, which I started blogging about a couple of months ago.
To date these functions only worked on the current database. So now I have added the option to also execute on another database on another server (beware that proper authorisation is in place).
The server will only be used when a database name is provided. In both cases, if omitted, the current server/database is used.
And the final added option is to be able to request the results back in a sorted order.

DbLookup
 /**  
  * Returns @DbLookup results as array and allows for cache  
  * @param server -name of the server the database is on (only used if dbname not empty, if omitted, the server of the current database is used)  
  * @param dbname -name of the database (if omitted the current database is used)  
  * @param cache -"cache" for using cache, empty or anything for nocache  
  * @param unique -"unique" for returning only unique values, empty or anything for all results  
  * @param sortit -"sort" for returning the values sorted alphabetically  
  * @param viewname -name of the view  
  * @param keyname -key value to use in lookup  
  * @param field -field name in the document or column number to retrieve  
  * @return array with requested results  
  */  
 function DbLookupArray(server, dbname, cache, unique, sortit, viewname, keyname, field) {  
      var cachekey = "dblookup_"+dbname+"_"+@ReplaceSubstring(viewname," ","_")+"_"+@ReplaceSubstring(keyname," ","_")+"-"+@ReplaceSubstring(field," ","_");  
      // if cache is specified, try to retrieve the cache from the sessionscope  
      if (cache.equalsIgnoreCase('cache')) {   
           var result = sessionScope.get(cachekey);  
      }  
      // if the result is empty, no cache was available or not requested,  
      //  do the dblookup, convert to array if not, cache it when requested  
      if (!result) {  
           // determine database to run against  
           var db = "";  
           if (!dbname.equals("")) { // if a database name is passed, build server, dbname array  
                if (server.equals("")){  
                     db = new Array(@DbName()[0],dbname); // no server specified, use server of current database  
                } else {  
                     db = new Array(server, dbname)  
                }   
           }  
           var result = @DbLookup(db, viewname, keyname, field);  
           if (result && unique.equalsIgnoreCase("unique")) result = @Unique(result);  
           if (result && typeof result == "string") result = new Array(result);  
           if (result && sortit.equalsIgnoreCase("sort")) result.sort();  
           if (result && cache.equalsIgnoreCase('cache')) sessionScope.put(cachekey,result);  
      }  
      return result;  
 }  
DbColumn
 /**  
  * Returns @DbColumn results as array and allows for cache  
  * @param server -name of the server the database is on (only used if dbname not empty, if omitted, the server of the current database is used)  
  * @param dbname -name of the database (if omitted the current database is used)  
  * @param cache -"cache" for using cache, empty or anything for nocache  
  * @param unique -"unique" for returning only unique values, empty or anything for all results  
  * @param sortit -"sort" for returning the values sorted alphabetically  
  * @param viewname -name of the view   
  * @param column -column number to retrieve  
  * @return array with requested results  
  */  
 function DbColumnArray(server, dbname, cache, unique, sortit, viewname, column) {  
      var cachekey = "dbcolumn_"+dbname+"_"+@ReplaceSubstring(viewname," ","_")+"_"+@ReplaceSubstring(column," ","_");  
      // if cache is specified, try to retrieve the cache from the sessionscope  
      if (cache.equalsIgnoreCase('cache')) {   
           var result = sessionScope.get(cachekey);  
      }  
      // if the result is empty, no cache was available or not requested,  
      //  do the dbcolumn, convert to array if not, cache it when requested  
      if (!result) {  
           // determine database to run against  
           var db = "";  
           if (!dbname.equals("")) { // if a database name is passed, build server, dbname array  
                if (server.equals("")){  
                     db = new Array(@DbName()[0],dbname); // no server specified, use server of current database  
                } else {  
                     db = new Array(server, dbname)  
                }   
           }  
           var result = @DbColumn(db, viewname, column);  
           if (result && unique.equalsIgnoreCase("unique")) result = @Unique(result);  
           if (result && typeof result == "string") result = new Array(result);  
           if (result && sortit.equalsIgnoreCase("sort")) result.sort();  
           if (result && cache.equalsIgnoreCase('cache')) sessionScope.put(cachekey,result);  
      }       
      return result;  
 }  

Used sources:
xpageswiki.com

Tuesday, 17 May 2011

Typo in code - dbcolumn !!

Had a sametime chat yesterday via BleedYellow started by Ed x Sanford with a question about a post from end of march on dblookup and dbcolumn in Xpages. The cache setting is not working on the dbcolumn code, why?
A glance at the code quickly learned that indeed the dbcolumn code would never cache.
The problem was in the second (actual) line of code. The "not" ! should not be there.
Thanks Ed for contacting me. The code snippets on the original blog entries have been changed accordingly.

Monday, 28 March 2011

Getting unique results from Xpages DbLookup and DbColumn functions

After using the DbColumn and DbLookup code I posted a while back I found another thing that needed solving.
Frequently I want these functions to only return unique values. But placing @Unique around the function calls gives the empty result as before for a repeat control if the result of the function is a single value, a string in effect.
So I added a line of code and a parameter to the functions to be able to request unique values (see the code below).

DbLookup
The code has been moved and can be found here: http://notesnl.blogspot.com/2011/09/final-version-of-dblookuparray.html


DbColumn
The code has been moved and can be found here: http://notesnl.blogspot.com/2011/09/final-version-of-dblookuparray.html

Wednesday, 23 February 2011

Improved caching for Xpages DbLookup and DbColumn

A while back I blogged about a failing repeat control in Xpages when passing it a single value returned from a @DbLookup or @DbColumn. In the comments to this entry it was already mentioned by some that it needs an array as input.
The other week I received a reply from IBM on my PMR (87011,211,788) stating exactly that, "The repeat control works as designed, it needs an array as input.".
From the earlier comments on that blogpost I had already started using the suggested solution from the xpages wiki by Julian Buss.
But like in the Notes client not every situation calls for cached results, so I amended this code to allow for cache or not. And instead of requestScope I used sessionScope as I want the cache to last until the session is ended (browser closed/session times out).
If you want to use it, put the code below in a server side JavaScript library and you are ready to use it.

DbLookup
The code has been moved and can be found here: http://notesnl.blogspot.com/2011/09/final-version-of-dblookuparray.html

DbColumn
The code has been moved and can be found here: http://notesnl.blogspot.com/2011/09/final-version-of-dblookuparray.html

Wednesday, 19 January 2011

Xpages - Combobox - set first choice to blank

In Xpages the combobox works different from what you are used to in the Notes form equivalent, the dialog list field.
In Notes if you get the choices using an @DbColumn or @DbLookup, assign no default value and the user does not consciously pick a value, no value is assigned to the field.
But when you do that with a combobox in Xpages, the first value in the list of choices will be assigned to the field.
Usually that is not what I want, I want the user to make a conscious choice. And assigning a default value of a space does not help if that value is not in the list of choices. So you will have to add a blank value as the first option in the list of choices.
I found 2 ways to solve this and it eliminates the need to set a default value.

1. The simplest way is to add a space as the first label-value pair and for the second add the rest of the choices using @DbColumn/@DbLookup.

2. Insert a blank value in the javascript code that retrieves the list of choices using @DbColumn/@DbLookup. This is probably the better method if you also want to include code to do some form of cache. See the code sample below.

 // get the cached result if used before 
var list = sessionScope.<cachename>;
// if no cached values found, create it
if (!list) {
// create an array with 1 blank entry as first entry
var arr = new Array(" ");
var res = @DbLookup("", "<a view>", "<a key>", 2);
// append the retrieved values to the array
var list = arr.concat(res);
sessionScope.<cachename> = list;
}
return list;

Thursday, 6 January 2011

Xpages and the failing Repeat control

I am converting an application to Xpages and use the repeat control to build several levels of dynamic menu structures.
They are based on simple @DbColumn and @DbLookup. But when the result array is only one entry the repeat control fails. The code below shows the failing repeat control (xp:link simplified to keep the code clean).
[Note: single results from @DbColumn or @DbLookup are returned as string and not an array.]
 <xp:repeat id="repeat1" rows="30" var="rowData" indexVar="rowIndex"> 
<xp:this.value><![CDATA[#{javascript:
@Unique(@DbLookup("", "xpSectionList", sessionScope.regionFilter, 2))
}]]></xp:this.value>
<li>
<xp:link escape="true" id="linkSubSection" title="#{javascript:rowData}">
<xp:this.text><![CDATA[#{javascript:rowData}]]></xp:this.text>
</xp:link>
</li>
</xp:repeat>
After some searching I found a solution in the LDD by Bob Cross, "Hint for Repeating a single value".
Repeat controls are great - but they MUST return an array, even if it is just one entry.

In my example, I used a repeat control to display entries from a dblookup. However, some of my lookups only returned one entry, so the result was a string, not an array. Since the result of my dblookup was a string, the repeat control would not display the one returned result.

The solution is to convert the result to a string first by using valueOf(). This returns a string delimited by commas. Then split the result by the commas to get an array. If split fails, then the result was an array to start with.

var tmpstr = result.valueOf();
try {
var newarr = tmpstr.split(",");
return(newarr)
}
catch(err){
return(tmpstr);
}
The proposed solution works fine and does solve the problem, but I consider it a workaround for a bug. The repeat control should also work when a single value is returned.
I have filed a service request (PMR) with IBM. Please do the same if you think this should be solved!
[Note: IBM have responded to the PMR: The repeat control works as designed and expects an array as input.]
The solution workaround is implemented in the code below.
 <xp:repeat id="repeat1" rows="30" var="rowData"  indexVar="rowIndex">
<xp:this.value><![CDATA[#{javascript:
var result = @Unique(@DbLookup("", "xpSectionList", sessionScope.regionFilter, 2));
var tmpstr = result.valueOf();
try {
var newarr = tmpstr.split(",");
return(newarr)
}
catch(err){
return(tmpstr);
}
}]]></xp:this.value>
<li>
<xp:link escape="true" id="linkSection" title="#{javascript:rowData}">
<xp:this.text><![CDATA[#{javascript:rowData}]]></xp:this.text>
</xp:link>
</li>
</xp:repeat>

Monday, 1 February 2010

Workaround for Xpages file download control bug

Last week I posted about a bug in the Xpages File Download Control.
See the post from 27 januari for details.

We have reported the problem through a PMR with IBM, but that unfortunately only resulted in a response that the problem is resolved in 8.5.1. and it will not be fixed in the 8.5.0 release.

In the PMR response IBM did mention a possible workaround could be found in John Mackey's blogpost and a response to last weeks post from Irina Kojevnikova also pointed to John Mackey's post. And as it turns out John based his code on Irina's initial solution.
In that post the solution to the problem is overriding the file download code with custom code to build the old style url for downloading attachments.
On 8.5.0 Domino the subdirectory is omitted in the file download control, so another work around would be to place replica of the database in the domino data root directory (nightmare for admins).

But John and Irina's solution is cleaner.

Tuesday, 22 September 2009

Interesting reading/tutorials about Xpages on the web

For me working with Xpages is not near what I am used to in the Domino Designer. It is a bit like starting from scratch again using a couple of sources on the web to learn.
As I am probably not alone in that, I thought it might be nice to share the list of sites I have been using so far. This list will be far from complete (only 4), but so far I have been reading (part, whole or just started to) the following sources on the Xpages subject on the web.
And maybe you can add your additional favorite sites on Xpages in a comment and build a full list of usefull Xpages sites (which I will repost at a later date).

- Learning Xpages by Declan Sciolla-Lynch
- The Xpages Blog by various authors
- Domino Designer Wiki: "Introduction to XPages" by Stephan H Wissel, Tim Clark (and others)
- XPages Drag and Drop Tutorial by Jake Ochs

- and of course the Xpages Tutorial in the Lotus Domino Designer /Info Center help is a good starting point.