你如何克服html表单嵌套限制?

gCo*_*der 196 html forms nested

我知道xhtml不支持嵌套的表单标签,我已经
在stackoverflow中读到了关于这个主题的其他答案,但我仍然没有想出一个优雅的问题解决方案.

有人说你不需要它,他们想不到这种情况是需要的.好吧,我个人无法想到一个我不需要它的场景.

让我们看一个非常简单的例子:

您正在创建一个博客应用程序,并且您有一个表单,其中包含一些字段,用于创建新帖子和工具栏,其中包含"保存","删除","取消"等"操作".

<form
 action="/post/dispatch/too_bad_the_action_url_is_in_the_form_tag_even_though_conceptually_every_submit_button_inside_it_may_need_to_post_to_a_diffent_distinct_url"
method="post">

    <input type="text" name="foo" /> <!-- several of those here -->
    <div id="toolbar">
        <input type="submit" name="save" value="Save" />
        <input type="submit" name="delete" value="Delete" />
        <a href="/home/index">Cancel</a>
    </div>
</form>
Run Code Online (Sandbox Code Playgroud)

我们的目标是以不需要javascript的方式编写表单,只需要简单的旧HTML表单和提交按钮.

由于动作URL是在Form标签中定义的,而不是在每个单独的提交按钮中定义,我们唯一的选择是发布到通用URL,然后启动"if ... then ... else"来确定按钮的名称提交.不是很优雅,但我们唯一的选择,因为我们不想依赖javascript.

唯一的问题是,按"删除",将提交服务器上的所有表单字段,即使此操作所需的唯一内容是带有post-id的隐藏输入.在这个小例子中并没有什么大不了的,但我的表格中有数百个(可以这么说)我的LOB应用程序中的字段和标签(由于要求)必须一次性提交所有内容,无论如何这看起来效率很低而浪费.如果支持表单嵌套,我至少可以在其自己的表单中包含"删除"提交按钮,只包含post-id字段.

您可以说"只需实施"删除"作为链接而不是提交".这在许多层面都是错误的,但最重要的是因为像这里的"删除"这样的副作用动作永远不应该是GET请求.

所以我的问题(特别是那些说他们不需要形成嵌套的人)是你做什么的?是否有任何优雅的解决方案,我缺少或底线真的"要么需要javascript或提交一切"?

sho*_*nik 175

我知道这是一个老问题,但HTML5提供了几个新选项.

第一种是将表单与标记中的工具栏分开,为删除操作添加另一种形式,并使用该form属性将工具栏中的按钮与其各自的表单相关联.

<form id="saveForm" action="/post/dispatch/save" method="post">
    <input type="text" name="foo" /> <!-- several of those here -->  
</form>
<form id="deleteForm" action="/post/dispatch/delete" method="post">
    <input type="hidden" value="some_id" />
</form>
<div id="toolbar">
    <input type="submit" name="save" value="Save" form="saveForm" />
    <input type="submit" name="delete" value="Delete" form="deleteForm" />
    <a href="/home/index">Cancel</a>
</div>
Run Code Online (Sandbox Code Playgroud)

此选项非常灵活,但原始帖子还提到可能需要使用单个表单执行不同的操作.HTML5再次受到拯救.您可以formaction在提交按钮上使用该属性,因此同一表单中的不同按钮可以提交到不同的URL.这个例子只是将一个克隆方法添加到表单外部的工具栏,但它在表单中嵌套的方式相同.

<div id="toolbar">
    <input type="submit" name="clone" value="Clone" form="saveForm"
           formaction="/post/dispatch/clone" />
</div>
Run Code Online (Sandbox Code Playgroud)

http://www.whatwg.org/specs/web-apps/current-work/#attributes-for-form-submission

这些新功能的优点是,它们在没有JavaScript的情况下以声明方式完成所有这些操作.缺点是旧浏览器不支持它们,因此您必须为旧版浏览器进行一些填充.

  • 你的观点毫无疑问是有争议的,与OP的问题无关.OP在不使用JavaScript的情况下询问了表单嵌套限制,答案提供了解决方案.无论你使用`<input>`还是`<button>`元素是无关紧要的,虽然按钮通常更适合工具栏,正如你所说.顺便说一句,15年来,所有浏览器都不支持按钮元素. (27认同)
  • @AKX虽然是旧陈述,但您可以在此处查看对此功能的支持:http://html5test.com/compare/feature/form-association-form.html.IE是一种注销,大多数其他桌面浏览器似乎是可以容忍的. (6认同)
  • +1 - 但是知道浏览器对`form =`的支持是多么可爱 - CanIUse并没有真正说出来.http://www.caniuse.com/#feat=forms (4认同)
  • 使用`<input>`来声明按钮是不好的做法.为了这个目的,15年前推出了`<button>`元素.真的是人. (3认同)

One*_*yon 53

我将完全按照您的描述实现这一点:将所有内容提交到服务器并执行简单的if/else检查单击了哪个按钮.

然后我将实现一个Javascript调用绑定到表单的onsubmit事件,该事件将在表单提交之前进行检查,并且仅将相关数据提交给服务器(可能通过页面上的第二个表单以及处理该事物所需的ID隐藏的输入,或者使用您需要作为GET请求传递的数据刷新页面位置,或者向服务器发送Ajax帖子,或者......).

这样没有Javascript的人就可以正常使用表单,但服务器负载是偏移的,因为拥有Javascript的人只提交所需的单个数据.让自己专注于只支持一个或另一个真正限制你的选择不必要.

或者,如果您在公司防火墙后面工作,并且每个人都禁用了Javascript,您可能需要执行两个表单并使用一些CSS魔术使其看起来像删除按钮是第一个表单的一部分.

  • 这种方法的问题在于它不是RESTful的.保存和删除对应于资源上的不同操作:"保存" - > POST/my_resource(创建新资源)"保存" - > PUT/my_resource(修改现有资源)"删除" - > DELETE/my_resource(销毁)从资源上说,问题是POST应该创建一个新资源.当然它永远不应该删除现有资源. (25认同)
  • OP原始声明没有javascript (14认同)

Jas*_*son 16

你可以在页面上并排显示表单,但不能嵌套.然后使用CSS使所有按钮排列漂亮?

<form method="post" action="delete_processing_page">
   <input type="hidden" name="id" value="foo" />
   <input type="submit" value="delete" class="css_makes_me_pretty" />
</form>

<form method="post" action="add_edit_processing_page">
   <input type="text" name="foo1"  />
   <input type="text" name="foo2"  />
   <input type="text" name="foo3"  />
   ...
   <input type="submit" value="post/edit" class="css_makes_me_pretty" />
</form>
Run Code Online (Sandbox Code Playgroud)

  • 是的,感觉太过于苛刻.此外,在一个非常大的页面中(想象标签和子标签以及几个范围级别中的嵌套提交按钮),几乎不可能将元素的屏幕位置与它们在文档中的位置完全分开. (4认同)
  • 好吧,它总是在你想做什么和你能做什么之间取得平衡.它看起来像是选项 - 在服务器上处理的一种形式,或者一种难以维护的多种形式 - 明智地选择:) (3认同)
  • 是的,不幸的是,在html中有所有这些限制,我只会坚持支持的内容并将整个表单发送到服务器,然后使用javascript不引人注意地为支持它的客户端截取表单子目录并仅发送真正需要的内容.这是最好的折衷方案. (3认同)

Nis*_*shi 13

HTML5具有"表单所有者"的概念 - 输入元素的"表单"属性.它允许模拟嵌套表单并解决问题.


B.D*_*Joe 11

一些古老的话题,但这个可能对某人有用:

正如上面提到的那样 - 你可以使用虚拟表格.我不得不在不久前克服这个问题.起初我完全忘记了这个HTML限制,只是添加了嵌套表单.结果很有趣 - 我从嵌套中丢失了我的第一个表单.然后事实证明,在实际的嵌套表单之前简单地添加一个虚拟表单(将从浏览器中删除)是一种"技巧".

就我而言,它看起来像这样:

<form id="Main">
  <form></form> <!--this is the dummy one-->
  <input...><form id="Nested 1> ... </form>
  <input...><form id="Nested 1> ... </form>
  <input...><form id="Nested 1> ... </form>
  <input...><form id="Nested 1> ... </form>
  ......
</form>
Run Code Online (Sandbox Code Playgroud)

适用于Chrome,FireFox和Safari.IE最多9(不确定大约10)并且Opera不检测主窗体中的参数.无论输入如何,$ _REQUEST全局都是空的.内在形式似乎无处不在.

尚未测试此处描述的其他建议 - 围绕嵌套表单的字段集.

编辑:框架集不起作用!我只是在其他人之后添加了Main表单(没有更多的嵌套表单),并使用jQuery的"clone"在按钮单击时复制表单中的输入.为每个克隆的输入添加.hide()以保持布局不变,现在它就像一个魅力.