Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditionally render element's attribute in a composite component

I have the following composite component:

<?xml version="1.0" encoding="UTF-8"?>
<ui:component xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    xmlns:fn="http://java.sun.com/jsp/jstl/functions"
    xmlns:composite="http://java.sun.com/jsf/composite">

    <composite:interface>
        <composite:attribute required="true" name="field" />
        <composite:attribute required="true" name="value" />
        <composite:attribute required="false" name="size"/>
    </composite:interface>

    <composite:implementation>
    ...
            <div class="wrapper">
                <h:inputText value="#{cc.attrs.value}"
                    id="#{field.id}" 
                    rendered="#{field.rendered}" 
                    size="#{cc.attrs.size}">
                </h:inputText>
                <h:messages for="#{field.id}" styleClass="errorMessage"/>
            </div>
    ...
    </composite:implementation>
</ui:component>

The problem is that when I'm using this component without setting its size attribute, it still gets rendered as size=0 in the html input element.

What I want is to render the nested h:inputText's attribute only if it has a valid value (eg. not empty). Alternatively, I'd like to expose all attributes of the nested element if they are not overridden explicitly.

How would it be possible?

like image 796
Balázs Németh Avatar asked Oct 15 '12 13:10

Balázs Németh


2 Answers

You can use JSTL <c:if> to build the view conditionally and <f:attribute> to specify an attribute separately:

<h:inputText ...>
    <c:if test="#{not empty cc.attrs.size}">
        <f:attribute name="size" value="#{cc.attrs.size}" />
    </c:if>
</h:inputText>

An alternative is to specify a default for the composite component attribute:

<cc:attribute name="size" required="false" default="10" />
like image 140
BalusC Avatar answered Nov 04 '22 22:11

BalusC


Additional to BalusC's post:

You must use

type="int" in the cc:attribute-tag :

cc:attribute name="maxlength" type="int"

like image 2
Jens Bernert Avatar answered Nov 04 '22 23:11

Jens Bernert