Часто исходной отправной точкой с шаблонами форм является добавление некоторого объемного пространства котельной плиты к каждому входу. Часто вам нужны дополнительные теги <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 Филиппа Уэбба в блоге Фила Уэбба .