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.

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

To display these on an XPage we can use the  <xp:message> or <xp:messages> control on an XPage.

The options available to the developer for displaying messages using the standard XPages controls are:
  • Use an <xp:message> control, which only allows you to show a single ‘Component’ message.
  • Use an <xp:messages> control with the property globalOnly=false, which will show all the messages (Component and Global).
  • Use an <xp:messages> 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 <xp:messages> 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 <xp:message> 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

You may also like...

3 Responses

  1. You must not have gotten the memo about the new TPS Report cover sheets

  2. 🙂
    or I could have used
    @ErrorMessage("PC LOAD LETTER",null);

  1. July 12, 2016

    […] while ago I shared an Extended version of the messages control which allows for multiple messages to be displayed for a single control at the same […]

Leave a Reply

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