问题描述
我在 panelGrids 中有很多 outputLabel 和 inputText 对
I have lot's of outputLabel and inputText pairs in panelGrids
<h:panelGrid columns="2">
<h:outputLabel value="label1" for="inputId1"/>
<h:inputText id="inputId1/>
<h:outputLabel value="label2" for="inputId2"/>
<h:inputText id="inputId2/>
...
</h:panelGrid>
我想对所有这些都有一些行为:比如每个 inputText 的相同验证或相同大小.所以我创建了一个复合组件,它只包含一个 outputLabel 和一个 inputText
I want to have some behaviour for all of them: like same validation or same size for every inputText. So I have created a composite component which just includes an outputLabel and and an inputText
<my:editField value="field1"/>
<my:editField value="field2"/>
但是现在当我将它们放入 gridPanel 时,它们不会根据标签文本的长度对齐.我明白为什么,但我不知道如何解决.
But now when I put them in a gridPanel, they do not get aligned depending on the length of the label text. I understand why, but I don't know how to work around.
推荐答案
复合组件确实被渲染为单个组件.您想改用 Facelet 标记文件.它完全按照其输出呈现的方式呈现.下面是一个启动示例,假设您需要一个 3 列表单,第三列中有一个消息字段.
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.
在 /WEB-INF/tags/input.xhtml
(或者在 /META-INF
中创建标签文件,当你想在 JAR 文件中提供标签时包含在 /WEB-INF/lib
中).
Create tag file in /WEB-INF/tags/input.xhtml
(or in /META-INF
when you want to provide tags in a JAR file which is to be included in /WEB-INF/lib
).
<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">
<c:set var="id" value="#{not empty id ? id : (not empty property ? property : action)}" />
<c:set var="required" value="#{not empty required and required}" />
<c:choose>
<c:when test="#{type != 'submit'}">
<h:outputLabel for="#{id}" value="#{label} #{required ? '* ' : ''}" />
</c:when>
<c:otherwise>
<h:panelGroup />
</c:otherwise>
</c:choose>
<c:choose>
<c:when test="#{type == 'text'}">
<h:inputText id="#{id}" value="#{bean[property]}" label="#{label}" required="#{required}">
<f:ajax event="blur" render="#{id}-message" />
</h:inputText>
<h:message id="#{id}-message" for="#{id}" />
</c:when>
<c:when test="#{type == 'password'}">
<h:inputSecret id="#{id}" value="#{bean[property]}" label="#{label}" required="#{required}">
<f:ajax event="blur" render="#{id}-message" />
</h:inputSecret>
<h:message id="#{id}-message" for="#{id}" />
</c:when>
<c:when test="#{type == 'select'}">
<h:selectOneMenu id="#{id}" value="#{bean[property]}" label="#{label}" required="#{required}">
<f:selectItems value="#{options.entrySet()}" var="entry" itemValue="#{entry.key}" itemLabel="#{entry.value}" />
<f:ajax event="change" render="#{id}-message" />
</h:selectOneMenu>
<h:message id="#{id}-message" for="#{id}" />
</c:when>
<c:when test="#{type == 'submit'}">
<h:commandButton id="#{id}" value="#{label}" action="#{bean[action]}" />
<h:message id="#{id}-message" for="#{id}" />
</c:when>
<c:otherwise>
<h:panelGroup />
<h:panelGroup />
</c:otherwise>
</c:choose>
</ui:composition>
在 /WEB-INF/example.taglib.xml
中定义它(或者在 /META-INF
中,当你想在 JAR 文件中提供标签时包含在 /WEB-INF/lib
中):
Define it in /WEB-INF/example.taglib.xml
(or in /META-INF
when you want to provide tags in a JAR file which is to be included in /WEB-INF/lib
):
<?xml version="1.0" encoding="UTF-8"?>
<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">
<namespace>http://example.com/jsf/facelets</namespace>
<tag>
<tag-name>input</tag-name>
<source>tags/input.xhtml</source>
</tag>
</facelet-taglib>
在 /WEB-INF/web.xml
中声明 taglib 的用法(当标签由包含在 /WEB-INF/lib 中的 JAR 文件提供时不需要这
!JSF 将从 /META-INF
自动加载所有 *.taglib.xml
文件.
Declare the taglib usage in /WEB-INF/web.xml
(this is not needed when the tags are provided by a JAR file which is included in /WEB-INF/lib
! JSF will auto-load all *.taglib.xml
files from /META-INF
).
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/example.taglib.xml</param-value>
</context-param>
(多个taglib文件可以用分号;
隔开)
最后只需在主页模板中声明即可.
Finally just declare it in your main page templates.
<!DOCTYPE html>
<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"
>
<h:head>
<title>Facelet tag file demo</title>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="3">
<my:input type="text" label="Username" bean="#{bean}" property="username" required="true" />
<my:input type="password" label="Password" bean="#{bean}" property="password" required="true" />
<my:input type="select" label="Country" bean="#{bean}" property="country" options="#{bean.countries}" />
<my:input type="submit" label="Submit" bean="#{bean}" action="submit" />
</h:panelGrid>
</h:form>
</h:body>
</html>
(#{bean.countries}
应该返回一个 Map
,以国家代码作为键,国家名称作为值)em>
(the #{bean.countries}
should return a Map<String, String>
with country codes as keys and country names as values)
截图:
希望这会有所帮助.
这篇关于如何制作JSF复合组件的网格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!