47

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

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
Mark Estrada
  • 8,275
  • 34
  • 107
  • 173
  • 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. – Bhesh Gurung Sep 10 '11 at 13:46
  • 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. – djmj Apr 02 '15 at 00:35
  • 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 : [fragment](http://www.primefaces.org/showcase/ui/ajax/fragment.xhtml) – reda la Apr 02 '15 at 00:57

2 Answers2

90

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:

Kukeltje
  • 11,924
  • 4
  • 19
  • 44
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • 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. – Vetle Apr 01 '12 at 19:55
  • 1
    @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 ? – Rajat Gupta Nov 15 '12 at 12:41
  • 2
    @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. – BalusC Nov 15 '12 at 14:12
  • @BalusC but is there such a thing of too many forms? Does it have any overhead? (Bloated JSF state?) – Ben Feb 18 '13 at 09:51
  • Deleted my former comment on validating content also when navigating and moved it into a [follow up question](http://stackoverflow.com/q/18146878/840977) – Louise Aug 09 '13 at 12:42
  • Hi @BalusC : What if I'm in a situation like this (please take a look at this question) http://stackoverflow.com/questions/19091230/ – Kishor Prakash Sep 30 '13 at 10:10
  • @BalusC '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? – alexander Feb 18 '15 at 09:53
  • 1
    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. – djmj Apr 02 '15 at 00:32
  • 1
    @BalusC What would you do in cases like when you use primeface wizard? With the wizard, you NEED to have a . What if on each of my tabs I want to have another form? What could I do? http://stackoverflow.com/questions/32468421/how-to-prevent-primeface-wizard-next-button-activate-client-validations/32486192?noredirect=1#comment52883149_32486192 – Erick Sep 10 '15 at 21:51
-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.

emm
  • 19
  • 1
  • 6
  • Could you give a code example of what you do here? It could help others. – Guillaume Racicot Nov 18 '16 at 21:07
  • Yes, I will. My scenario was this: – emm Nov 21 '16 at 15:38
  • 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. – emm Dec 30 '16 at 18:04