Using ui:insert to include children

Let’s say you have a custom facelets component that wraps an h:selectOneListbox. As a part of using this component, you read the list of items that should be displayed in the list from a database table. Your bean reads the results of the database query and creates listItems, that are then passed back to the h:selectOneListbox, through your my:customListbox component. For instance:

              items="#{myDatabaseBean.listItems}" />

In this example, the value of the h:selectOne would be set in myBean.setItemValue, and the list of selectItems would be returned from myDatabaseBean.getListItems.

Now, you decide that you want to provide some defaults for the lists that are in your UI, but not in the database. You could modify myDatabaseBean.getListItems to manually add a custom default selectItem. The value of the defaultItem could be null, or empty string, that way, when the list is displayed, if myBean.getItemValue returns null or empty string, the default value would be selected in the UI. Pretty slick, except for you have to write java in EVERY instance where you are creating your listItems from the database. Now, add in internationalization and your database bean now has to use the correct resource bundle to read the default value display string. That’s not real difficult, but it’s just more java code that has to be introduced everywhere you are creating those lists.

So, is there another way? Here’s what I did.

In my customListbox component I included a well placed, anonymous ui:insert. This magically made my composition include the children of my customListbox in place of the unnamed ui:insert. For instance, within customListbox.xhtml my h:selectOneListbox now looks like this:

    <h:selectOneListbox value="#{entity[fieldName]}">
      <ui:insert />
      <f:selectItems value="#{items}" />

Then I can include multiple f:selectItem elements as a child of my:customListbox such as:

    items="#{myDatabaseBean.listItems}" >
    <f:selectItem itemValue="" itemLabel="#{bundle.defaultBlahValue}" />

Now, I’ve been able to add a custom default value to my custom listbox with a single line in xhtml, and a single resource bundle value, and no java.

One thought on “Using ui:insert to include children

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s