How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?
Asked Answered
K

2

50

I am using the Facelet Templating Technology to layout my page in a JSF 2 app that I am working on.

In my header.xhtml, primefaces requires that menubar be enclosed in h:form.

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

So, in my contents pages, I will have another h:form or more.

Will it just work if I just place the h:form in my template.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>

I am actually thinking of a use case where I need multiple h:form in a page.

Thanks

Keel answered 10/9, 2011 at 13:10 Comment(3)
It's not a good idea to put form on the template page like. We need to surround the components with the form and I think the forms should go where the components go.Cupule
Many primefaces components also work without a form in case they dont use any ajax features (Maybe use ajax="false" on childs). Not sure if MenuBar works, but TabView for example does.Softa
I think it's too late. But I had the same problem this morning. I was forced to use a template that contains a single form. If you use Primefaces it offers a good solution to get around this problem : fragmentRelate
M
91

You can safely use multiple forms in a JSF page. It's not different than when using plain HTML.

Nesting <form> elements is invalid in HTML. Since JSF just generates a bunch of HTML, it's not different in JSF. Nesting <h:form> is therefore also invalid in JSF.

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

The browser behavior as to submitting a nested form is unspecified. It may or may not work the way you expect. It may for instance just refresh the page without invoking the bean action method. Even if you move the nested form (or a component that contains it) outside of the parent form with dom manipulation (or by e.g. using the PrimeFaces appendTo="@(body)"), it still won't work and there should be no nested forms at time of loading the page.

As to which forms you need to keep, having a single "god" <h:form> is actually a poor practice. So, you'd best remove the outer <h:form> from the master template and let the header, sidebar, content etc sections each define its own <h:form>. Multiple parallel forms is valid.

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

Each form must have one clear responsibility. E.g. a login form, a search form, the main form, the dialog form, etc. You don't want to unnecessarily process all other forms/inputs, when you submit a certain form.

Note thus that when you submit a certain form, other forms are NOT processed. So, if you intend to process an input of another form anyway, then you've a design problem. Either put it in the same form or throw in some ugly JavaScript hacks to copy the needed information into a hidden field of the form containing the submit button.

Within a certain form, you can however use ajax to limit the processing of the inputs to a smaller subset. E.g. <f:ajax execute="@this"> will process (submit/convert/validate/invoke) only the current component and not others within the same form. This is usually to be used in use cases wherein other inputs within the same form need to be dynamically filled/rendered/toggled, e.g. dependent dropdown menus, autocomplete lists, selection tables, etc.

See also:

Maxma answered 10/9, 2011 at 14:17 Comment(9)
Actually, this will also result in invalid HTML. The JSF frameworks (at least Mojarra) has a hidden input element in each form, with the ID javax.faces.ViewState. Since an ID must be unique in a HTML document, you get invalid HTML. I believe you can turn it off in Mojarra by setting a property, so that it only sets the name attribute to javax.faces.ViewState, but there might be various libraries that look for the ID, so YMMV.Tenancy
@BalusC: Could you also clarify whether all input fields are submitted even when I explicitly specify in p:remoteCommand's process attribute what all fields to process ?Pagoda
@user: Definitely all fields of the form are submitted. The process is a server side thing. You can easily see it yourself by looking at the HTTP traffic.Maxma
@Maxma but is there such a thing of too many forms? Does it have any overhead? (Bloated JSF state?)Cockcrow
Deleted my former comment on validating content also when navigating and moved it into a follow up questionAbrogate
Hi @Maxma : What if I'm in a situation like this (please take a look at this question) stackoverflow.com/questions/19091230Limitless
@Maxma 'You don't want to unnecessarily submit/process/validate/etc all other inputs, when you submit a certain form' is that, the only advantage for multiple forms in one page?Rubbish
On certain primefaces components you can use `appendTo="@(body)"`` for situations of nested forms. The final html is appended at the bottom of the body. Very usefull for dialogs. Maybe it can work surrounding form with a panel.Softa
@Maxma What would you do in cases like when you use primeface wizard? With the wizard, you NEED to have a <h:form>. What if on each of my tabs I want to have another form? What could I do? stackoverflow.com/questions/32468421/…Gauvin
A
-1

I was confounded by this issue for a while. Instead of a series of independent forms, I converted to a template, that is, rather than making a call to a xhtml with listed forms, usually as ui:include, I make a call to those formerly ui:included xhtml pages that ui:content captured in a parent template.

Arron answered 18/11, 2016 at 20:48 Comment(3)
Could you give a code example of what you do here? It could help others.Prothallus
Yes, I will. My scenario was this:Arron
I simply verify that all forms are linear and not embedded. Sort of hard for me to demonstrate. The notion is that certain forms are related by some purpose, my suggestion is that one should use a template to group those forms. Each form retrieved independently, managed by a menu. Many times I have tried in the same xhtml a series of independent forms, and in my case commandLink or commandButton has always failed. Not sure my results are true for all, I am working in Windows 10, Netbeans/GlassFish.Arron

© 2022 - 2024 — McMap. All rights reserved.