Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>A composite component gets indeed rendered as a single component. You want to use a Facelet tag file instead. It gets rendered exactly as whatever its output renders. Here's a kickoff example assuming that you want a 3-column form with a message field in the third column.</p> <p>Create tag file in <code>/WEB-INF/tags/input.xhtml</code> (or in <code>/META-INF</code> when you want to provide tags in a JAR file which is to be included in <code>/WEB-INF/lib</code>).</p> <pre><code>&lt;ui:composition xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets"&gt; &lt;c:set var="id" value="#{not empty id ? id : (not empty property ? property : action)}" /&gt; &lt;c:set var="required" value="#{not empty required and required}" /&gt; &lt;c:choose&gt; &lt;c:when test="#{type != 'submit'}"&gt; &lt;h:outputLabel for="#{id}" value="#{label}&amp;#160;#{required ? '*&amp;#160;' : ''}" /&gt; &lt;/c:when&gt; &lt;c:otherwise&gt; &lt;h:panelGroup /&gt; &lt;/c:otherwise&gt; &lt;/c:choose&gt; &lt;c:choose&gt; &lt;c:when test="#{type == 'text'}"&gt; &lt;h:inputText id="#{id}" value="#{bean[property]}" label="#{label}" required="#{required}"&gt; &lt;f:ajax event="blur" render="#{id}-message" /&gt; &lt;/h:inputText&gt; &lt;h:message id="#{id}-message" for="#{id}" /&gt; &lt;/c:when&gt; &lt;c:when test="#{type == 'password'}"&gt; &lt;h:inputSecret id="#{id}" value="#{bean[property]}" label="#{label}" required="#{required}"&gt; &lt;f:ajax event="blur" render="#{id}-message" /&gt; &lt;/h:inputSecret&gt; &lt;h:message id="#{id}-message" for="#{id}" /&gt; &lt;/c:when&gt; &lt;c:when test="#{type == 'select'}"&gt; &lt;h:selectOneMenu id="#{id}" value="#{bean[property]}" label="#{label}" required="#{required}"&gt; &lt;f:selectItems value="#{options.entrySet()}" var="entry" itemValue="#{entry.key}" itemLabel="#{entry.value}" /&gt; &lt;f:ajax event="change" render="#{id}-message" /&gt; &lt;/h:selectOneMenu&gt; &lt;h:message id="#{id}-message" for="#{id}" /&gt; &lt;/c:when&gt; &lt;c:when test="#{type == 'submit'}"&gt; &lt;h:commandButton id="#{id}" value="#{label}" action="#{bean[action]}" /&gt; &lt;h:message id="#{id}-message" for="#{id}" /&gt; &lt;/c:when&gt; &lt;c:otherwise&gt; &lt;h:panelGroup /&gt; &lt;h:panelGroup /&gt; &lt;/c:otherwise&gt; &lt;/c:choose&gt; &lt;/ui:composition&gt; </code></pre> <p>Define it in <code>/WEB-INF/example.taglib.xml</code> (or in <code>/META-INF</code> when you want to provide tags in a JAR file which is to be included in <code>/WEB-INF/lib</code>):</p> <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd" version="2.0"&gt; &lt;namespace&gt;http://example.com/jsf/facelets&lt;/namespace&gt; &lt;tag&gt; &lt;tag-name&gt;input&lt;/tag-name&gt; &lt;source&gt;tags/input.xhtml&lt;/source&gt; &lt;/tag&gt; &lt;/facelet-taglib&gt; </code></pre> <p>Declare the taglib usage in <code>/WEB-INF/web.xml</code> (this is not needed when the tags are provided by a JAR file which is included in <code>/WEB-INF/lib</code>! JSF will auto-load all <code>*.taglib.xml</code> files from <code>/META-INF</code>).</p> <pre><code>&lt;context-param&gt; &lt;param-name&gt;javax.faces.FACELETS_LIBRARIES&lt;/param-name&gt; &lt;param-value&gt;/WEB-INF/example.taglib.xml&lt;/param-value&gt; &lt;/context-param&gt; </code></pre> <p><em>(multiple taglib files can be separated by semicolon <code>;</code>)</em></p> <p>Finally just declare it in your main page templates.</p> <pre><code>&lt;!DOCTYPE html&gt; &lt;html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:my="http://example.com/jsf/facelets" &gt; &lt;h:head&gt; &lt;title&gt;Facelet tag file demo&lt;/title&gt; &lt;/h:head&gt; &lt;h:body&gt; &lt;h:form&gt; &lt;h:panelGrid columns="3"&gt; &lt;my:input type="text" label="Username" bean="#{bean}" property="username" required="true" /&gt; &lt;my:input type="password" label="Password" bean="#{bean}" property="password" required="true" /&gt; &lt;my:input type="select" label="Country" bean="#{bean}" property="country" options="#{bean.countries}" /&gt; &lt;my:input type="submit" label="Submit" bean="#{bean}" action="submit" /&gt; &lt;/h:panelGrid&gt; &lt;/h:form&gt; &lt;/h:body&gt; &lt;/html&gt; </code></pre> <p><em>(the <code>#{bean.countries}</code> should return a <code>Map&lt;String, String&gt;</code> with country codes as keys and country names as values)</em></p> <p>Screenshot:</p> <p><img src="https://i.stack.imgur.com/Pd9Fw.png" alt="enter image description here"></p> <p>Hope this helps.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload