Часто исходной отправной точкой с шаблонами форм является добавление некоторого объемного пространства котельной плиты к каждому входу. Часто вам нужны дополнительные теги <div> или <span> для использования css. Вот типичный пример:
|
01
02
03
04
05
06
07
08
09
10
11
12
|
<!-- /WEB-INF/pages/entername.xhtml --><ui:decoreate template="/WEB-INF/layout/form.xhtml"> <h:inputText id="firstName" label="First Name" value="#{bean.firstName}"/> <ui:param name="label" value="First Name"/> <ui:param name="for" value="firstName"/></ui:decorate><ui:decoreate template="/WEB-INF/layout/form.xhtml"> <h:inputText id="lastName" label="Last Name" value="#{bean.lastName}"/> <ui:param name="label" value="Last Name"/> <ui:param name="for" value="lastName"/></ui:decorate><!-- Many additional form elements --> |
|
1
2
3
4
5
6
7
8
9
|
<!-- /WEB-INF/layout/form.xhtml --><ui:composition> <div class="formElement"> <span class="formLabel"> <h:outputLabel for="#{for}" label="#{label}"> </span> <ui:insert/> </div></ui:composition> |
Здесь мы видим, что каждый элемент в форме содержится в <div>, а метки формы заключены в дополнительный <span> . В разметке уже есть некоторое повторение с параметром «for», отражающим идентификатор компонента. Я также дал каждому элементу <h: inputText> атрибут label
для лучшей проверки сообщений об ошибках это повторяется в «метке» <ui: param>. Ситуация начинает ухудшаться, если мы хотим пометить обязательные поля звездочкой:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
<!-- /WEB-INF/pages/entername.xhtml --><ui:decoreate template="/WEB-INF/layout/form.xhtml"> <h:inputText id="firstName" label="First Name" value="#{bean.firstName}" required="false"/> <ui:param name="label" value="First Name"/> <ui:param name="for" value="firstName"/> <ui:param name="showAsterisk" value="false"/></ui:decorate><ui:decoreate template="/WEB-INF/layout/form.xhtml"> <h:inputText id="lastName" label="Last Name" value="#{bean.lastName}" required="true"/> <ui:param name="label" value="Last Name"/> <ui:param name="for" value="lastName"/> <ui:param name="showAsterisk" value="true"/></ui:decorate><!-- Many additional form elements --> |
|
1
2
3
4
5
6
7
8
9
|
<!-- /WEB-INF/layout/form.xhtml --><ui:composition> <div class="formElement"> <span class="formLabel"> <h:outputLabel for="#{for}" label="#{label}#{showAsterisk ? ' *' : ''}"> </span> <ui:insert/> </div></ui:composition> |
Довольно неприятно, что нам нужно передавать элементы <ui: param> , которые дублируют атрибуты, уже указанные в <h: inputText> . Легко видеть, как даже при относительно небольших формах мы получим много дублирования в нашей разметке. Нам нужен способ получить информацию о вставленном компоненте внутри шаблона, даже если мы не знаем, какой это будет компонент. Нам нужно <s: componentInfo> .
Компонент <s: componentInfo> предоставляет переменную, содержащую информацию о вставленном компоненте. Эта информация включает метку , идентификатор клиента компонента и, если компонент требуется . Осмотрев вставленный элемент, мы можем удалить много дубликатов:
|
1
2
3
4
5
6
7
8
|
<!-- /WEB-INF/pages/entername.xhtml --><ui:decoreate template="/WEB-INF/layout/form.xhtml"> <h:inputText id="firstName" label="First Name" value="#{bean.firstName}" required="false"/></ui:decorate><ui:decoreate template="/WEB-INF/layout/form.xhtml"> <h:inputText id="lastName" label="Last Name" value="#{bean.lastName}" required="true"/></ui:decorate><!-- Many additional form elements --> |
|
01
02
03
04
05
06
07
08
09
10
11
|
<!-- /WEB-INF/layout/form.xhtml --><ui:composition> <s:componentInfo var="info"> <div class="formElement"> <span class="#{info.valid ? 'formLabel' : 'formErrorLabel'}"> <h:outputLabel for="#{info.for}" label="#{info.label}#{info.required ? ' *' : ''}"> </span> <ui:insert/> </div> </s:componentInfo></ui:composition> |
Что-то еще, что мы можем теперь сделать, это сказать, если вставленный компонент не прошел проверку. Обратите внимание, что в приведенном выше примере будет выбран CSS-класс formErrorLabel для недопустимых компонентов.
Одна интересная особенность нового компонента <s: componentInfo> заключается в том, что все теги <ui: decorate> становятся идентичными. Мы удалили все повторения внутри тега, но сам тег все еще повторяется много раз. Здесь у нас есть еще один трюк, который может помочь, введя новый тег <s: decorateAll> . Использование <s: decorateAll> позволяет использовать шаблон один раз для каждого дочернего компонента. Вот обновленная разметка формы:
|
1
2
3
4
5
6
|
<!-- /WEB-INF/pages/entername.xhtml --><s:decoreateAll template="/WEB-INF/layout/form.xhtml"> <h:inputText id="firstName" label="First Name" value="#{bean.firstName}" required="false"/> <h:inputText id="lastName" label="Last Name" value="#{bean.lastName}" required="true"/> <!-- Many additional form elements --></s:decorateAll> |
|
01
02
03
04
05
06
07
08
09
10
11
|
<!-- /WEB-INF/layout/form.xhtml --><ui:composition> <s:componentInfo var="info"> <div class="formElement"> <span class="#{info.valid ? 'formLabel' : 'formErrorLabel'}"> <h:outputLabel for="#{info.for}" label="#{info.label}#{info.required ? ' *' : ''}"> </span> <ui:insert/> </div> </s:componentInfo></ui:composition> |
Если вы хотите взглянуть на исходный код этих компонентов, посмотрите пакет org.springframework.springfaces.template.ui в проекте Springfaces GitHub .
Ссылка: Интеграция Spring & JavaServer Faces: Улучшенные шаблоны от нашего партнера JCG Филиппа Уэбба в блоге Фила Уэбба .