Creating custom renderers for XPages controls

One of the things that really annoys me about XPages is the way it renders controls in read only mode. So if you have a combo box in read only mode it would be displayed in a table like this:

Same goes for check box group and radio group. That’s a lot of code to display just three characters and plus it completely destroys my CSS! This is where I believe custom renderers can be helpful.

What is a Renderer?

A renderer is used to output some HTML markup corresponding to a control to be displayed in a web browser or in the Notes client. Every control renderer must extend from the JSF renderer base class javax.faces.render.Renderer or one of it’s subclasses. More information available here.

Creating a Renderer

To create a Renderer you need to extend the javax.faces.render.Renderer class and override its methods decode, encodeBegin, encodeChildren and encodeEnd as per your requirement. We would only use the encodeEnd method as we just need to output the selected value.

In the above class, in encodeEnd method we cast the component object to javax.faces.component.UISelectOne as it is the class for combo box. We then get the value of combo box and write it to the writer object.

Registering the renderer class

Now you need to register your custom renderer so that it can be used by your control. For that you need to modify faces-config.xml. Open your database in Package Explorer and go to “WebContent > WEB-INF > faces-config.xml”. While registering your renderer make sure the component-family is same as the one to which the control (i.e. combo box) belongs to.

To find out the component family for your control you can use the code: getComponent(“comboBox1”).getFamily(). In case of combo box it is javax.faces.SelectOne.

So now your faces-config.xml file will look something like this:

Setting your custom renderer to control

To set the custom renderer in your control you can use the value defined in renderer-type from the faces-config.xml. But again we want this renderer to be activated only if the control is in read only mode.

In the above code we check if the combo box is in read only mode. If yes then we set the rendererType property to uk.co.pipalia.type.ReadOnlyRenderer, else we use the renderer type of combo box. Now if you view your XPage then only the value of the combo box would be shown without any tables.

This is very simple example which does not take into consideration if the document is in read only or edit mode. For that you would have to additionally check document mode before setting the renderer type. But I would leave that for you to explore!

Share:

Copyright © 2013 Pipalia Software House. All Rights Reserved.

6 thoughts on “Creating custom renderers for XPages controls

  1. jjtb somhorst

    Hi,

    this is a great post! I’ve been playing around with the way how controls are being rendered as well and this is a great deal on how to customize that behaviour.

    Reply
    1. Naveen Maurya Post author

      Thanks! Would love to hear if you have any other use cases where you can use the custom renderers in XPages.

      Reply
  2. Daniel Boston

    Thanks for this great intro!

    For the uninitiated, I’d recommend looking in to FacesUtil.isComponentReadOnly() — this was the “missing link” in getting my own custom renderer for read-only content to work correctly when switching between document modes.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *