Wednesday, January 11, 2012

Easy to print Lotusphere 2012 Pocket Agenda (updated)

IBM provides a PDF with an overview of everything Lotusphere: the Lotusphere Pocket Agenda (for a download link, see Lotusphere 2012 sessions page). It's a really nice reference, but the PDF is a bit of a challenge to print on A4 or Paper.

Last night I had some fun with combining and rotating the pages to get an easily printable PDF and here I share them with you (hoping IBM doesn't mind).

There are two versions (update: now three):
  1. Printed onto A4, with 4 pages combined per page. These require eagle eyes or reading glasses
  2. One that's printed onto A5 with 2 pages combined per page. It will come out nicely readable if you select "fit to printable area" when printing to A4/Paper.
  3. Same as the A5 version with 2 pages combined per page, but on A4 format and rotated for easier viewing on a computer/tablet.
All versions lack the frontpage, that was needed to get all pages to align correctly.

I hope these can be of help to you. Have fun and see you in Orlando!

Update 11-1-2012 12:10 CET:
Added a third version. It's the same as the second, but now in A4 size and rotated for easier viewing.

Friday, December 16, 2011

How to set the correct DOCTYPE

By default Domino prints out the following, half decent DOCTYPE, leaving out the link to the DTD:

<!DOCTYPE HTML PUBLIC 
   "-//W3C//DTD HTML 4.01 Transitional//EN">

This causes browsers to render the page in quirks mode and not care very much about standards. This makes it harder to get pages to render the same in the different browsers (Internet Explorer, Firefox, Chrome).

If you care about a correct layout of the page you would want something like:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd"> 

Or if you're lazy, like I am, and maybe want to pretend to do HTML 5, use:

<!DOCTYPE html>

For Xpages it's simply a setting in the Application Properties, Xpages tab:



For a LotusScript agent as straightforward as printing the content-type, a blank line and then the doctype.

Print "Content-type: text/html"
Print
Print "<!DOCTYPE html>"
Print "<html>"
...

For forms (and views that are captured in a $$ViewTemplate form) it's a bit harder, unless you know how to do it:
  1. Create a computed for display field named "$$HTMLFrontMatter"
  2. Hide it
  3. Set its value to"<!DOCTYPE html>" (or whatever doctype you prefer)
Et voilĂ ! That's it. Happy little doctypes, causing browsers to render the pages in standards compliant mode.

Happy hacking!

Monday, December 12, 2011

Wish list for Xpages development

Just in time for the holiday season, here's my Santa Claus wish list for enhancements in Domino Designer to aid Xpages development.

Building websites, or should I say web applications, in Designer has become an absolute joy with the introduction of Xpages. With each new release the IDE becomes more advanced and the capabilities of the platform are unheard of. Thank you Santa! 

But there are things left to be wished for. Here's my short list. And allow me to leave out the obvious things like a faster Xpages editor or less crashes or hangs. I'm sure Santa is already working on that. 

So here it goes:
  1. A collapsible list for Custom controls. The amount controls for an application easily gets out of hand. This results in lots of scrolling back and forth in the  Database Navigator's list of controls.  I'd like to be able to group controls by subject. Similar to the way Java packages are displayed in the Package Explorer. As far as I'm concerned, there's no need for a different way to name the controls. Just split the names at the underscore and build the tree from there. Make it optional to keep everybody happy.
  2. And while we're at it, do the same for the packages in the new Code/Java section.
  3. Scrollbar for lists in the Controls view. Or at least allow me to use the scroll wheel on my mouse. The up and down arrows are like peeking through a keyhole. 
  4. Add a setting to open Xpages editor in source mode by default. I hardly ever use the visual editor, please stop me from having to switch each time I open a control or Xpage,
  5. Drag custom controls from the Database Navigator or Package Explorer onto an Xpage or Custom Control. It feels natural to do it that way.
That's it. I feel better now.

What are your wishes? Let Santa know by leaving a comment.

Sunday, June 19, 2011

Fix IE9 submit events

In my previous blog on how to fix the default type for buttons in IE I ended with a remark that although the method described fixes the button type, in Internet Explorer 9 the save action still does not work. This seems to be IE9 specific, as IE8 works as expected.

After a bit of reverse engineering I found the cause of the problem and came up with a solution.

Looking at the submitted data there is a difference between Firefox and Internet Explorer 9. In IE9 the field $$xspsubmitid is empty, in Firefox it is filled with the id of the server side event that should be triggered (i.e. "view:_id1:_id2:_id7:event1").

At the bottom of the webpage there's a bit of Javascript code that 'binds' the server side event to the click on the button:

XSP.addOnLoad(function() {
XSP.attachEvent("view:_id1:_id2:_id7:event1", "view:_id1:_id2:_id7:button1", "onclick", null, true, 2);
}); 

The method attachEvent calls XSP.addOnLoad and that's where funny things happen. This is the method, un-minified from /domjs/dojo-1.4.3/ibm/xsp/widget/layout/xspClientDojo.js:

this.addOnLoad=function x_aol(_1b9){
    if(!this._listeningForDojoOnload){
        this._listeningForDojoOnload=true;
        dojo.addOnLoad(this,"_loaded");
    }
    this._onLoadListeners.push(_1b9);
};

On the fourth line the dojo.addOnLoad method is called to add a call to XSP's method _loaded. This method executes the code to add listeners that have been added to the _onLoadListeners array.

Now, what's all this about? It turns out that IE9 calls the _loaded method immediately after it is added on line 4, before the listener events have been added to the onLoadListeners array. These client side events will never be added, and thus the server side event will not be fired on submit.

The solution? Override the addOnLoad with a slightly modified version and add it somewhere in the current page in a scriptBlock (or Javascript client side library). This modified version fills the onLoadListeners array before adding a call to the _loaded method so that the listeners will always be added, even in IE9.

XSP.addOnLoad=function x_aol(_1b9){
    this._onLoadListeners.push(_1b9);
    if(!this._listeningForDojoOnload){
        this._listeningForDojoOnload=true;
        dojo.addOnLoad(this,"_loaded");
    }
};

The cause of the problem is probably in Dojo's addOnLoad. But I expect Dojo's code to be less easy to fix and settled for this solution.

Game on!

Fix default type for submit buttons in IE (updated)

For submit buttons - you know, the new <button>Click me</button> type - to work properly in Internet Explorer you have to explicitly add the type of the button. So the above example becomes <button type="submit">Click me</button>.

With Themes in Xpages it's very easy to fix this on an application wide level.
  1. Open your favorite theme
  2. Add the following tags:
    <control>
      <name>Button.Submit</name>
      <property>
        <name>type</name>
        <value>submit</value>
      </property>
    </control>
Now all the buttons in your application with an Xpages  button of "Button type" "submit" will have the type added to fix IE.

Happy hacking!

Update 19-06-2011 19:50: While this fixed the submit action, in IE9 the form still won't be saved. The problem is that on the client XSP tries to attach an event to the button, but fails to do so. Not so happy right now.

Update 19-06-2011 21:45: The IE9 problem has been solved, please read Fix IE9 submit event.

Wednesday, May 25, 2011

Xpages - Java Bean lessons of the day

This Xpages stuff is still fairly new to me and there are lots of little things I struggle with. Today was spend trying to figure out how to build some of the log-in/log-out logic. For a couple of problems I could not find a direct answer on the internet, so I thought I'd share what I came up with.

Remove a bean from the session

In the application I'm building there's this "User" bean that holds all kinds of user data and provides some application logic. When the user clicks the log out button, it would be neat to cleanup that bean. The following line of SSJS code removes the "User" bean.

facesContext.getExternalContext().getSessionMap().remove("User");

Invalidate the session

Another option for the log-out cleanup function is to invalidate the whole session, which you can do with the following line of SSJS code:

facesContext.getExternalContext().getSession(true).invalidate();

Of course, this cleans up a lot more than just the User bean.

Read property from resource bundle

In the beans, you would of course like to use the resource files. It's easy. Put the following Java method in a Utils class:

public static String getResource(String bundleVar, String name) {
 XSPContext xspContext = XSPContext.getXSPContext(FacesContext
   .getCurrentInstance());

 try {
  // There has to be bundle defined with var name 
  ResourceBundle bundle;
  bundle = xspContext.bundle(bundleVar);
   if (bundle != null) {
   return bundle.getString(name);
  }
 } catch (IOException e) {
  e.printStackTrace();
 }

 return "";
}

And call it as follows:

Utils.getResource("settings", "db_users");

For reference, "settings" is the name of the bundle resource and "db_users" is the name of the setting. From the theme configuration:


 
  /WEB-INF/settings.properties
  settings
 


Get a request variable

The User bean does some auto-login magic. To be able to do that it needs to read the request cookies. No problem! Take this static function, put it in some Utils class:

Utils.getCookies();

public static String getCookies() {
 // System.out.print(XSPContext.getXSPContext(
 // FacesContext.getCurrentInstance()).getUrl());

 HttpServletRequest request = (HttpServletRequest) FacesContext
   .getCurrentInstance().getExternalContext().getRequest();
 return request.getHeader("cookie");
}

You can modify this to read other request parameters, to extend the handling of cookies, etc..

Have fun!

Sunday, May 15, 2011

Bulk cleanup old Working Set databases, part 2

Earlier today I wrote a post describing how you could cleanup the Working Set by editing the XML that stores the Working Sets. I stated that you cannot do this though the Package Explorer view, as a delete from the view would also remove the database. That turns out to be wrong and thanks to Nathan Freeman for pointing it out.

When you delete an entry from the Package Explorer view, it asks for confirmation and displays a checkbox with "Delete project contents on disk". I thought it was about cleaning up the temporary database files in de workspace folder and checked the box. But I was wrong. Checking this will tell Designer to actually remove the database, the .nsf.

Of course, I had to test it before correcting my previous post. During testing I made a couple of screenshots which I will present below. The testing was done on my development server with four blank databases named Test 1 up to 4.

On the left you see the four databases in the Working Set "Test". To the right the contents of the workspace folder (note the four folders with temporary files for the Temp databases) and at the bottom the four databases on the server.

From the Package Explorer the four databases are selected. Note that only one database was actually opened.

After clicking on "Delete", the confirmation dialog is presented. Make sure to not select "Delete project contents on disk".

After clicking OK, you see the database entries have been removed from the Test Working Set (top left), temporary files have been removed (top right), but the .nsf's are still available on the server (bottom right). Alright, that's what we're looking for!

Now a test to see what happens when you do select the "Delete project contents on disk" checkbox. I re-added the four databases to the Test Working Set, selected them in Package Explorer and clicked in the context menu on "Delete". Of course, selecting the checkbox before hitting OK.

After clicking OK, the databases have been removed from the Working Set, temporary files have been removed from the Workspace folder and, most importantly for this test, have been removed from the server

The delete in the Package Explorer turns out to be pretty powerful. You can use it to quickly cleanup your Working Set, but also to remove the corresponding databases. All from without the Domino Designer environment. Pretty cool, thanks Nate for pointing this out!