我知道 XHTML 不支持嵌套表单标签,并且我已经在 Stack Overflow 上阅读了有关此主题的其他答案,但我仍然没有找到解决问题的优雅方法。
有人说你不需要它,他们想不出一个场景是需要它的。好吧,就我个人而言,我想不出我不需要它的 场景 。
让我们看一个非常简单的例子:
您正在制作一个博客应用程序,并且您有一个包含一些用于创建新帖子的字段的表单和一个带有“保存”、“删除”、“取消”等“操作”的工具栏。
<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>
我们的目标是以一种不需要 JavaScript 的方式编写表单,只需要普通的旧 HTML 表单和提交按钮。
由于操作 URL 是在 Form 标签中定义的,而不是在每个单独的提交按钮中,我们唯一的选择是发布到通用 URL,然后启动“if…then…else”来确定按钮的名称已提交。不是很优雅,但我们唯一的选择,因为我们不想依赖 JavaScript。
唯一的问题是按下“删除”,将提交服务器上的所有表单字段,即使此操作唯一需要的是带有 post-id 的隐藏输入。在这个小例子中没什么大不了的,但是我的LOB应用程序中有数百个(可以这么说)字段和选项卡的表单(由于要求)必须一次性提交所有内容,无论如何这似乎非常低效和浪费。如果支持表单嵌套,我至少可以将“删除”提交按钮包装在它自己的表单中,只有 post-id 字段。
您可能会说“只需将“删除”作为链接而不是提交来实现”。这在很多层面上都是错误的,但最重要的是因为像这里的“删除”这样的副作用操作永远不应该是 GET 请求。
所以我的问题(特别是对于那些说他们不需要嵌套的人)是你做什么?有没有我遗漏的优雅解决方案,或者底线真的是“要么需要 JavaScript,要么提交所有内容”?
我将完全按照您的描述实现这一点:将所有内容提交到服务器并执行一个简单的 if/else 来检查单击了哪个按钮。
然后我将实现一个绑定到表单的 onsubmit 事件的 Javascript 调用,该事件将在表单提交之前进行检查,并且仅将相关数据提交到服务器(可能通过页面上的第二个表单,其 ID 需要处理为隐藏的输入,或使用您需要作为 GET 请求传递的数据刷新页面位置,或向服务器执行 Ajax 发布,或…)。
这样,没有 Javascript 的人可以很好地使用表单,但是服务器负载被抵消了,因为有 Javascript 的人只提交了所需的单条数据。让自己专注于只支持一个或另一个确实会不必要地限制您的选择。
或者,如果你在公司防火墙或其他东西后面工作,并且每个人都禁用了 Javascript,你可能想要做两个表单并使用一些 CSS 魔法,让它看起来像删除按钮是第一个表单的一部分。