如何在JSF页面中使用<h:form>?单一形式?多种形式?嵌套表单?

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

提问人:Mark Estrada 提问时间:9/10/2011 最后编辑:BalusCMark Estrada 更新时间:10/18/2017 访问量:58731

问:

我正在使用 Facelet 模板技术在我正在开发的 JSF 2 应用程序中布局我的页面。

在我的标题.xhtml中,primefaces要求菜单栏用h:form括起来。

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

因此,在我的内容页面中,我将有另一个或更多 h:form。

如果我只是将 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。

谢谢

嵌套表单 JSF JSF-2

评论

0赞 Bhesh Gurung 9/10/2011
将表单放在模板页面上并不是一个好主意。我们需要用表单包围组件,我认为表单应该放在组件去的地方。
0赞 djmj 4/2/2015
许多素面组件也可以在没有表单的情况下工作,以防它们不使用任何 ajax 功能(可能在子项上使用)。不确定是否有效,但例如有效。ajax="false"MenuBarTabView
0赞 reda la 4/2/2015
我认为为时已晚。但是我今天早上遇到了同样的问题。我被迫使用包含单个表单的模板。如果你使用Primefaces,它提供了一个很好的解决方案来解决这个问题:片段

答:

91赞 BalusC 9/10/2011 #1

您可以在 JSF 页面中安全地使用多个窗体。这与使用纯 HTML 时没有什么不同。

嵌套元素在 HTML无效。由于 JSF 只生成一堆 HTML,因此在 JSF 中没有什么不同。因此,嵌套在 JSF 中也是无效的。<form><h:form>

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

未指定提交嵌套表单的浏览器行为。它可能会也可能不会按照您预期的方式工作。例如,它可能只是刷新页面而不调用 Bean 操作方法。即使您使用 dom 操作(或例如使用 PrimeFaces)将嵌套表单(或包含它的组件)移动到父表单之外,它仍然不起作用,并且在加载页面时不应嵌套表单。appendTo="@(body)"

至于你需要保留哪些形式,只有一个“神”实际上是一种不好的做法。因此,您最好从主模板中删除外部部分,并让 、 等 部分各自定义自己的 .多个并行形式有效。<h:form><h:form>headersidebarcontent<h:form>

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

每个表格必须有一个明确的责任。例如,登录表单、搜索表单、主表单、对话框表单等。当您提交某个表单时,您不希望不必要地处理所有其他表单/输入。

请注意,当您提交某个表格时,不会处理其他表格。因此,如果您打算处理另一个表单的输入,那么您就遇到了设计问题。要么把它放在同一个表格中,要么加入一些丑陋的 JavaScript hack,将所需的信息复制到包含提交按钮的表格的隐藏字段中。

但是,在某种形式中,您可以使用 ajax 将输入的处理限制为较小的子集。例如 将仅处理(提交/转换/验证/调用)当前组件,而不处理同一表单中的其他组件。这通常用于需要动态填充/呈现/切换同一表单中的其他输入的用例,例如依赖下拉菜单、自动完成列表、选择表等。<f:ajax execute="@this">

另请参阅:

评论

0赞 Vetle 4/2/2012
实际上,这也会导致无效的HTML。JSF 框架(至少是 Mojarra)在每个表单中都有一个隐藏的输入元素,其 ID 为 .由于 ID 在 HTML 文档中必须是唯一的,因此您将获得无效的 HTML。我相信你可以通过设置一个属性在 Mojarra 中关闭它,这样它只将 name 属性设置为 ,但可能有各种库会查找 ID,所以 YMMV。javax.faces.ViewStatejavax.faces.ViewState
1赞 Rajat Gupta 11/15/2012
@BalusC:您能否澄清一下,即使我在 的属性中明确指定了要处理的所有字段,是否也提交了所有输入字段?p:remoteCommandprocess
2赞 BalusC 11/15/2012
@user:当然,表格的所有字段都已提交。这是服务器端的东西。通过查看 HTTP 流量,您可以轻松地自己查看它。process
1赞 djmj 4/2/2015
在某些素面组件上,您可以使用 'appendTo=“@(body)”'' 来表示嵌套形式的情况。最终的 html 附加在正文底部。对对话非常有用。也许它可以用面板来工作周围的形式。
1赞 Erick 9/11/2015
@BalusC 当您使用 primeface 向导时,您会怎么做?使用向导,您需要有一个 <h:form>。如果我想在我的每个选项卡上都有另一个表单怎么办?我能做些什么?stackoverflow.com/questions/32468421/......
-1赞 emm 11/19/2016 #2

我被这个问题迷惑了一段时间。我没有将一系列独立的表单转换为模板,也就是说,我不是调用具有列出的表单的 xhtml(通常为 ui:include),而是调用那些以前 ui:included 的 xhtml 页面,这些页面是 ui:content 捕获在父模板中的。

评论

0赞 Guillaume Racicot 11/19/2016
你能举一个代码示例来说明你在这里做什么吗?它可以帮助其他人。
0赞 emm 11/21/2016
是的,我会的。我的场景是这样的:
0赞 emm 12/31/2016
我只是验证所有形式都是线性的而不是嵌入的。对我来说有点难以证明。这个概念是某些形式因某种目的而相关,我的建议是应该使用模板对这些形式进行分组。每个表单都独立检索,由菜单管理。很多时候,我在同一个 xhtml 中尝试了一系列独立的表单,在我的情况下,commandLink 或 commandButton 总是失败。不确定我的结果是否适用于所有人,我正在 Windows 10、Netbeans/GlassFish 中工作。