Как использовать <h: form> на странице JSF? Единая форма? Несколько форм? Вложенные формы?

Я использую технологию Facelet Templating для компоновки моей страницы в приложении JSF 2, над которым я работаю.

В моем header.xhtml, для того, что в простых строках требуется, чтобы строка была заключена в h: form.

<h:form>
    <p:menubar autoSubmenuDisplay="true">
        Menu Items here!
    </p:menubar>
</h:form>

Итак, на моих страницах содержания у меня будет другая h: форма или больше.

Будет ли это работать, только если я поместил h: form в свой шаблон .xhtml?

<h:body>
    <h:form>
        <div id="top">
            <ui:insert name="header"><ui:include src="sections/header.xhtml"/></ui:insert>
        </div>
        <div>
            <div id="left">
                <ui:insert name="sidebar"><ui:include src="sections/sidebar.xhtml"/></ui:insert>
            </div>
            <div id="content" class="left_content">
                <ui:insert name="content">Content</ui:insert>
            </div>
        </div>
        <div id="bottom">
            <ui:insert name="footer"><ui:include src="sections/footer.xhtml"/></ui:insert>
        </div>
    <h:form>
</h:body>

Я действительно думаю о прецеденте, когда мне нужно несколько h: form на странице.

Спасибо

Ответ 1

Вы можете безопасно использовать несколько форм на странице JSF. Это не отличается от использования обычного HTML.

Вложенные элементы <form> недействительны в HTML. Поскольку JSF просто генерирует кучу HTML, в JSF он не отличается. Вложение <h:form> поэтому также недействительно в JSF.

<h:form>
    ...
    <h:form> <!-- This is INVALID! -->
        ...
    </h:form>
    ...
</h:form>

Поведение браузера относительно отправки вложенной формы не указывается. Он может работать или не работать так, как вы ожидаете. Он может, например, просто обновить страницу без вызова метода действия компонента. Даже если вы перемещаете вложенную форму (или компонент, который ее содержит) вне родительской формы с манипуляцией dom (или, например, с помощью PrimeFaces appendTo="@(body)"), это все равно не будет работать, и должно быть без вложенных форм при загрузке страницы.

Что касается форм, которые вам нужно сохранить, наличие единственного "бога" <h:form> на самом деле является плохой практикой. Таким образом, вам лучше удалить внешний <h:form> из основного шаблона, и пусть разделы header, sidebar, content т.д. Определяют свой собственный <h:form>. Действует несколько параллельных форм.

<h:form>
    ...
</h:form>
<h:form> <!-- This is valid. -->
    ...
</h:form>

Каждая форма должна иметь четкую ответственность. Например, форма входа, форма поиска, основная форма, форма диалога и т.д. Вы не хотите излишне обрабатывать все другие формы/входы при отправке определенной формы.

Обратите внимание, что при отправке определенной формы другие формы НЕ обрабатываются. Итак, если вы все равно собираетесь обрабатывать ввод другой формы, тогда у вас есть проблема с дизайном. Либо поставьте его в том же виде, либо бросьте некоторые уродливые JavaScript-хаки, чтобы скопировать необходимую информацию в скрытое поле формы, содержащей кнопку отправки.

Однако в определенной форме вы можете использовать ajax, чтобы ограничить обработку входов меньшим подмножеством. Например, <f:ajax execute="@this"> будет обрабатывать (отправлять/конвертировать/проверять/вызывать) только текущий компонент, а не другие в той же форме. Обычно это используется в случаях, когда другие входы в одной и той же форме должны быть динамически заполнены/отображены/переключены, например, зависимые выпадающие меню, списки автозаполнения, таблицы выбора и т.д.

Смотрите также:

Ответ 2

Я некоторое время был замешан в этой проблеме. Вместо целого ряда независимых форм я конвертировал в шаблон, то есть вместо того, чтобы делать вызов xhtml с перечисленными формами, обычно как ui: include, я делаю вызов тем, которые ранее были: включены xhtml-страницы, которые ui: содержимое, записанное в родительском шаблоне.