PanelGrid XPages Control – for simple table based layouts

I can’t remember the circumstance, but whilst looking around the web I stumbled across a control called ‘panelGrid’ that is available in standard JSF.

I really liked the idea of it so I decided, why can’t we have it in XPages? we can!

What does panelGrid control do?

Basically the panelGrid renders an HTML table, but does so using minimal markup on your xpage. It does this by following a convention.
The panelGrid has a ‘columns’ property which specifies how many columns the ‘grid’ should have.
As each child component is found, it is rendered in a

, when it reaches the number of columns, it will start a new

and carry on.
So basically, it will render children left-to-right top-to-bottom in a grid layout using a

pattern.

For example, here is the same output, rendered 2 different ways

  1. using style, defining tr’s and td’s as necessary. 
  2. using the panel grid

As you can see visually it is the same result.

Now lets have a look at the markup in the xpage

Here is the markup for xp:table method:

Using the xp:table layout method





































and here is the markup for panel grid method:

Using the Panel Grid

















As you can see, the panelGrid is a much cleaner design on the xpage.

Other features

The control also has a header and footer facet, which is rendered as a colspanned td at the top and bottom of the table. The control is styleable and themeable.
If you need to put more than one control in a ‘grid cell’ you can nest them under a span or div.
Here is a 4 minute demo video to see the features in action.

Limitations

It is not for every situation, if you have a complex layout that you want to merge some cells, then the panelGrid might not be a good fit. But if you need a simple grid based layout that looks nice a clean on your xpage markup then give this a go! You will soon learn when it is appropriate.

Implementation details

It wasn’t too hard to create for Xpages, the necessary renderer com.sun.faces.renderkit.html_basic.GridRenderer is already part of the XPages runtime as part of the core JSF that has been extended. It just hasn’t been surfaced for a component.

To enable using the panelGrid I needed to create the UIComponent UIPanelGrid (extending XspTable), define the component tag properties via an .xsp-config file and register the rendered via a faces-config.xml file

How can I use it?

I have started my own ‘extension library’ where I will be putting all the controls that I develop on this blog ( I plan to move emailvalidator there and also finish the phone number control!).
There are 2 other controls in there ‘text differenc’ and mime inspector which I plan to blog about very soon.

I have just created the first release on github

Download the updatesite zip file from the release, extract it and install to Domino Designer as well as your Server
You will need to enable the com.gregorbyte.xsp.library for your NSF in the xsp.properties editor. 

If you don’t want to install the plugins, you can also install the necessary components into an NSF yourself. To Do this:
You need the UIPanelGrid java file in the java section
You need the .xsp-config in your WebContent\WEB-INF folder
You need the entries from the faces-config.xml file (above) in your faces-config.xml file in the NSF
That should do it’ you may need to clean and build a couple of times.

Good luck, Please let me know if you have any questions / problems!

Advertisements
PanelGrid XPages Control – for simple table based layouts

Setting up JRebel for XPages OSGi Plugin Development

When developing plugins for Domino in Eclipse, one of the drawbacks is the constant
‘restart task http’ to pick up any new changes in your class files.

It may only take 30 seconds but it is slow enough that every time it happens, maybe you check your email, news, social media, maybe you distract one of your colleagues.

Previously, the In-built eclipse remote debugging previously to allow hot-code replace for small changes, however I have found that since a few domino versions ago, it will now crash the server! not ideal!

JRebel looks very promising, it is designed to watch your class folders and automatically update the JVM with no restart.

I had seen JRebel a couple of years back and had one failed attempt at getting it to work with domino and then gave up. I have heard others mention a few times ‘maybe it would work with Domino?’

Anyway, thanks to David Leedy’s video on setting up YourKit profiler, it gave me a clue into how to set up JRebel in a similar fashion using the JavaOptionsFile

Today I managed to get JRebel and Domino working, I have only used it for a day but so far it is going pretty good. I thought I would share how I got it set up so that others might give it a try and let me know if it is working for them.

Here is the video demonstrating the set up and use of JRebel

If you have any trouble setting it up let me know and I will see if I can help

Setting up JRebel for XPages OSGi Plugin Development

Using Editor Templates for Repetitive Code

I’ve been doing a little bit of XPages control development lately, and if you ever dabble in the dark art of this you will realise there is a lot of repeating yourself when it comes to writing the getters and setters for Control properties.
If your control properties are going to support value binding, then you will do the same pattern over and over.

For the getter:
If property is set explicitly Then return property,
Otherwise, If there is value binding, compute and return the value.
Otherwise, return the default.

For the setter:
normal setter!

Eclipse (and therefore Domino Designer) supports the idea of Templates, there are many default templates available, but you can also craft your own, so if you do a lot of repetitive code, it might be worth having a look into creating your own templates to use.

So I made myself a nice little Editor Template (this one in Domino Designer as I do the prototyping in there before moving completed files out to an OSGi plugin in normal Eclipse).

I have submitted the template as an XSnippet To use, copy the xml to an XML file then go to
Domino Designer Preferences -> Java -> Editor ->Templates
Click Import, select the xml file and you will have a new template ‘vbgettersetter’ which means ValueBinding Getter and setter.

Here is a 2 Minute video of it in action.

Using Editor Templates for Repetitive Code

Using the Eclipse Copyright Tool to prepare for OpenNTF Submission

I’m in the middle of Preparing my ‘Swiper’ project for OpenNTF, and in the submission guidelines it states that source files such as .java, plugin.xml, feature.xml .properties must include the Copyright notice at the top.

I thought, what a pain, I’m going to have to update each file, and then I thought, surely Eclipes has something that does this?
By default eclipse can include a copyright notice for each new Source file that you create, however I already have created my source files, and want to update the existing source with a new Copyright message.

A quick google and I found the following article which explains how to install and use the Eclipse Copyright Tool

After installing I simply went to the Preferences and updated the Copyright template.

Then Right-clicked on the plugin Project and selected ‘Fix Copyrights’

My Java files all had the copyright notice

plugin.xml

build.properties

Running it on the feature project it updated feature.xml too!

So if you are looking to convert an existing project to be submitted to openntf, give the Eclipse Copyright Tool a try.

Using the Eclipse Copyright Tool to prepare for OpenNTF Submission

Uploading Plugins Headlessly to Open Eclipse Update Site

This is a very rough blog post! I am responding to a question on twitter about how to upload plugins to an Update Site NSF automatically (e.g. from a build server) So I thought I would put it in a blog post so it would be available for all.
Any questions / corrections please just comment, there will probably be a mistake or two

Domino comes with a standard ‘Eclipse Update Site’ NSF which you can load your plugins into, and then configure notes.ini so the server will load plugins from that NSF. It has the advantage that it will replicate to other servers and you don’t need to touch the filesystem.

Using the standard update site, you can only upload manually, there are UI Dialog’s involved etc.

IBM open sourced the template, and Karsten Lehmann made a modified version available on OpenNTF which is exactly the same but has an agent ‘(API)’ that can be called ‘headlessly’ to upload plugins from a build server.

It also allows deleting Features one-by-one however it won’t delete disabled features I have found.

I have made 3 minor modifications to it for our version

  • I made the icons blue instead of purple so I can instantly tell if it is a modified template version
  • I added a Form ‘HeadlessImport’. When you run the agent, you pass it a document, I decided to allocate this document to a form so I could inspect it after it had run.
  • I added a View ‘HeadlessImports’ to view the HeadlessImport documents.

Importing from Build Server 

On the build server, you can run a java program (using jars from jvm/lib/ext) to Create a notes session, get the updatesite database, and then call the (API) agent.
You pass a NotesDocument to the agent, and the notesdocument has necessary instructions to either delete all plugins or to import from the  site.xml
 I have a project on github which has some utilities related to building Xpages and plugins camac/BuildXPages 
Within it I have some custom ant tasks, one of which (as of this week!) is the ImportPluginsTask which does all this for me

Now you don’t need to be using ant, you can simply take the same algorithm from the source code (in the execute function) and put it in your own java program. Just make sure you have the Notes jars on your classpath. and maybe you need notes prog dir on your system PATH. I am running it on a server with an id that has no password, so you may need to modify it if your have a password on your id file
The task takes the parameters for server, database and location of site.xml file, creates the notesdocument, runs the agent and then checks the document afterwards to see if there was an error.

Note: when I run the agent I see 4 ‘Object Variable not set’ in the output, I don’t think this is impacting upon the success of the plugins, I am still to investigate the cause.

Generating a Site.xml

You need to have a site.xml file, I also have a task to generate one from a list of features and plugins.


Let me know any comments questions!

 

Uploading Plugins Headlessly to Open Eclipse Update Site

Build Automation for XPages Presentation Slides – AUSLUG/Inform 2015

I just finished a presentation today at AUSLUG / INFORM 2015 in Melbourne, Australia.

Thank you to the organisers and sponsors for putting on the event, and thanks to all the attendees as my session!

The slides from my session have been uploaded to the Auslug connections community, I have also uploaded them to slideshare, and they should appear below.
Please note there is an Appendix at the end which explains the build.properties that we use for building XPages OSGi plugins.

Please leave a comment or message me on twitter @gregorbyte if you have any questions I will be happy to answer them!

Build Automation for XPages Presentation Slides – AUSLUG/Inform 2015

Extending the Messages Control: Multiple Messages for a Single Component

As you probably know, XPages has a built in mechanism for displaying Messages to the user. The options available to the developer are almost complete, but I believe there is one scenario not covered by the default ‘Messages’ controls. There is no way to show multiple messages for a single component. In this blog post I will show how this option can be made available by extending the default classes and modifying their behaviour.

The most common scenario you see these Messages used is when an Input Control fails conversion or validation.
These messages are part of JSF and are called ‘FacesMessages’. A FacesMessage can either be ‘Global’, which means it has no relation to any component in the component tree, or it can be a ‘Component’ message which is linked to a specific component.

You can create these messages yourself, either from Java using the FacesMessages class as such.

FacesMessage fm = new FacesMessage();

fm.setSeverity(FacesMessage.SEVERITY_ERROR);
fm.setSummary("Invalid TPS Report Format");
fm.setDetail("We're putting cover sheets on all TPS reports from now on");

FacesContext.getCurrentInstance().addMessage("someClientId", fm);

or from SSJS using some @ functions that are provided with the XPages Extension Library.

@ErrorMessage('A Global Error Message',null); 
@ErrorMessage('An Error Message for a Component', 'yourComponentId');
@InfoMessage('A Global Info Message',null);
@InfoMessage('An Info Message for a Component', 'yourComponentId');
@WarningMessage('A Global Warning Message',null);
@WarningMessage('A Warning Message for a Component', 'yourComponentId');

To display these on an XPage we can use the   or control on an XPage.

The options available to the developer for displaying messages using the standard XPages controls are:
  • Use an control, which only allows you to show a single ‘Component’ message.
  • Use an control with the property globalOnly=false, which will show all the messages (Component and Global). 
  • Use an control with the property globalOnly=true, this will show all the Global Messages.
Sometimes though I want the following option which is not available!
  • Use an control that will show all the Component Messages for a single component.
There is currently no way to do this, the only messages control that is linked to a component is the control, and it only will show 1 message. Even if you have created more than one Component message for that control, it will still only show the first.

What is the plan?

My plan is to take the current messages control, and make it render multiple messages exactly as it does so already, however I want to control the list of messages that it renders. Instead of the list being ‘All Messages’ or ‘Global Messages’, I am going to add a new ‘for’ property in which I can specify which component id the messages should be for. If this ‘for’ property is blank, then the id of the messages control itself will be used instead.

How can we make this option

It turns out that doing it does not take too much work, but knowing what steps to take is the hard part.
Here are the steps will we take
  1. Create our own Messages Component which extends the existing one
    1. Set the renderer type to our new rendered (to be created) in the constructor of the component
    2. Add the ‘for’ property to the component.
    3. Implement State saving behaviour so that the ‘for’ property value is kept between requests
    4. Create the xsp-config file which describes the Component, extending the existing xsp-config for the built-in messages component and adding the for property
  2. Create our own renderer that extends the existing MessagesRenderer
    1. Override the getMessageIter function
    2. Register our new Renderer through FacesConfig
  3. Test our new component!

If you just want to see the end result, check out the project on GitHub.
camac/XPagesMessagesControl

Otherwise have a look at the following Code Walkthrough / Demonstration Video

Extending the Messages Control: Multiple Messages for a Single Component