Thursday, 3 December 2015

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 <td>, when it reaches the number of columns, it will start a new <tr> and carry on.
So basically, it will render children left-to-right top-to-bottom in a grid layout using a <table><tr><td> pattern.

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

  1. using <xp:table> 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:

<h3>Using the xp:table layout method</h3>

<xp:table>
 <xp:tr>
  <xp:td>
   <xp:label value="Label" id="label1"></xp:label>
  </xp:td>
  <xp:td>
   <xp:inputText id="inputText1"></xp:inputText>
  </xp:td>
 </xp:tr>
 <xp:tr>
  <xp:td>
   <xp:label value="Label" id="label2"></xp:label>
  </xp:td>
  <xp:td>
   <xp:inputText id="inputText2"></xp:inputText>
  </xp:td>
 </xp:tr>
 <xp:tr>
  <xp:td>
   <xp:label value="Label" id="label3"></xp:label>
  </xp:td>
  <xp:td>
   <xp:inputText id="inputText3"></xp:inputText>
  </xp:td>
 </xp:tr>
 <xp:tr>
  <xp:td>
   <xp:label value="Label" id="label4"></xp:label>
  </xp:td>
  <xp:td>
   <xp:inputText id="inputText4"></xp:inputText>
  </xp:td>
 </xp:tr>
</xp:table>

and here is the markup for panel grid method:

<h3>Using the Panel Grid</h3>
<gb:panelGrid id="panelGrid1">

 <xp:label value="Label" id="label5"></xp:label>
 <xp:inputText id="inputText5"></xp:inputText>

 <xp:label value="Label" id="label6"></xp:label>
 <xp:inputText id="inputText6"></xp:inputText>

 <xp:label value="Label" id="label7"></xp:label>
 <xp:inputText id="inputText7"></xp:inputText>

 <xp:label value="Label" id="label8"></xp:label>
 <xp:inputText id="inputText8"></xp:inputText>

</gb:panelGrid>

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!

No comments:

Post a Comment