Sch*_*els 12 php forms jquery jquery-ui-tabs
我有一个Web应用程序,主要由一个包含信息的大表单组成.表单分为多个选项卡,以使其对用户更具可读性:
<form>
<div id="tabs">
<ul>
<li><a href="#tab1">Tab1</a></li>
<li><a href="#tab2">Tab2</a></li>
</ul>
<div id="tab1">A big table with a lot of input rows</div>
<div id="tab2">A big table with a lot of input rows</div>
</div>
</form>
Run Code Online (Sandbox Code Playgroud)
表单是动态扩展的(额外的行添加到表中).每隔10秒,表单就会被序列化并与服务器同步.
我现在想在其中一个选项卡上添加交互式表单:当用户在字段中输入名称时,此信息将发送到服务器并返回与该名称关联的ID.此id用作某些动态添加的表单字段的标识符.
这样一个页面的快速草图将如下所示:
<form action="bigform.php">
<div id="tabs">
<ul>
<li><a href="#tab1">Tab1</a></li>
<li><a href="#tab2">Tab2</a></li>
</ul>
<div id="tab1">A big table with a lot of input rows</div>
<div id="tab2">
<div class="associatedinfo">
<p>Information for Joe</p>
<ul>
<li><input name="associated[26][]" /></li>
<li><input name="associated[26][]" /></li>
</ul>
</div>
<div class="associatedinfo">
<p>Information for Jill</p>
<ul>
<li><input name="associated[12][]" /></li>
<li><input name="associated[12][]" /></li>
</ul>
</div>
<div id="newperson">
<form action="newform.php">
<p>Add another person:</p>
<input name="extra" /><input type="submit" value="Add" />
</form>
</div>
</div>
</div>
</form>
Run Code Online (Sandbox Code Playgroud)
以上操作无效:HTML中不允许使用嵌套表单.但是,我真的需要在该选项卡上显示该表单:它是该页面功能的一部分.我还想要一个单独表单的行为:当用户在表单字段中返回时,按下"添加"提交按钮并在部分表单上触发提交操作.
解决这个问题的最佳方法是什么?
Dan*_*ien 10
您可以做的一件事是将"Add"输入元素的类型设置为"submit",将其设置为"button"并添加id用于注册click处理程序的属性:
<!-- ... -->
<div id="newperson">
<p>Add another person:</p>
<input id="extra_input" name="extra" /><input id="add_button" type="button" value="Add" />
</div>
<!-- ... -->
Run Code Online (Sandbox Code Playgroud)
输入类型"按钮"的原因是页面上的结果按钮看起来与提交按钮完全相同,但在单击时默认不执行任何操作,允许您自定义其效果.此外,支持HTML 3.2或更高版本(包括HTML 5)的所有浏览器都支持输入类型"按钮" .
在Javascript的某个地方,您可能有一个函数,只要用户单击"添加"按钮,您就可以调用该函数.假设它被调用addAnotherPerson,您只需addAnotherPerson在单击处理程序中调用:
// This is jQuery code, but all JS frameworks that I have seen have a similar feature to register a click handler on a DOM element referenced by ID.
$("#add_button").click(function (event) {
addAnotherPerson();
$("#extra_input").val(""); // reset the value
});
Run Code Online (Sandbox Code Playgroud)
您还需要在"额外"文本输入中添加keydown处理程序,以便在用户按下Enter键时执行相同的操作:
$("#extra_input").keydown(function (event) {
if (event.keyCode == 0xa || event.keyCode == 0xd) {
addAnotherPerson();
$("#extra_input").val(""); // reset the value
}
});
Run Code Online (Sandbox Code Playgroud)
请务必将该属性添加autocomplete="off"到"额外"文本输入中.
该addAnotherPerson函数可以发送包含"额外"文本框中的值的异步POST请求,如果合适,则在之后更新DOM.
编辑:如果您还想支持禁用Javascript的用户,那么通过name为每个提交按钮添加属性,每个提交按钮具有唯一的name属性值,您的服务器端应用程序将能够告诉用户单击了哪个按钮.
例如,从http://www.alanflavell.org.uk/www/trysub.html获取此代码:
<table>
<tr><td align=left><label for="aquavit_button"><input id="aquavit_button" type="submit" name="aquavit" value="[O]"> Aquavit</label></td></tr>
<tr><td align=left><label for="beer_button"><input id="beer_button" type="submit" name="beer" value="[O]"> Beer</label></td></tr>
<tr><td align=left><label for="champagne_button"><input id="champagne_button" type="submit" name="champagne" value="[O]"> Champagne</label></td></tr>
<tr><td align=left><label for="water_button"><input id="water_button" type="submit" name="water" value="[O]"> Dihydrogen monoxide</label></td></tr>
</table>
Run Code Online (Sandbox Code Playgroud)
如果用户点击"Beer"旁边的"[O]"按钮,则浏览器会发送"啤酒"POST变量,但不会发送"aquavit","香槟"或"水"POST变量.请在http://www.alanflavell.org.uk/www/trysub.html上试试.
这种技术的一个棘手问题是用户通过在文本输入中按Enter键来提交表单.Firefox为表单中的第一个提交按钮发送POST变量(在本例中为"aquavit"),而Internet Explorer不为任何提交按钮发送POST变量.您可以通过在表单的最开头添加隐藏的无名提交按钮来修补此差异:
<form action="bigform.php"><input type="submit" style="display:none;" />
<!-- ... -->
Run Code Online (Sandbox Code Playgroud)
编辑2:如果您始终确保在提交大表单之前通过Javascript清除"额外"文本输入中的值,那么您将能够判断用户是否已禁用 Javascript,并且他们按下"确认"中的Enter键.通过检查服务器端的"额外"POST变量是否为空,额外的"文本输入(表示他们希望运行添加人员操作)".如果它不为空,那么您可以假设用户已禁用Javascript并且他们想要添加人员.
添加此代码:
$("#bigform").submit(function (event) {
$("#extra_input").val(""); // reset the value in the "extra" text input
return true;
});
Run Code Online (Sandbox Code Playgroud)
HTML应该是语义的,应该首先考虑它 - 也就是说它应该有一个清晰的结构和意义,而不需要理解javascript的顶部.就像a <ul>应该只包含<li>元素的方式一样,a <form>应该只有一个目的.使用javascript通过检索动态数据来增强表单很好,但是如果使用额外的HTTP POST(修改服务器上的数据的类型),那么这实际上代表了第二个目的,因此应该使用第二个表单.第二种形式具有自己的"动作"属性,表示此处发生了明显的行为,并且不仅在概念上更合理,而且在必要时更容易分析,调试或扩展.
<form id="bigform" action="bigform.php">
<!-- Tabs here -->
</form>
<form id="newperson" action="newform.php">
<input name="extra">
<button type="submit" value="Add">
<!-- Note also the use of <button> instead of <input> -->
</form>
Run Code Online (Sandbox Code Playgroud)
重要的是,您仍然可以在主窗体内实现所需的流程.在主窗体上,使用a而不是使用嵌套窗体<fieldset>.此字段集将充当newperson表单的代理.这里的输入可以有一个ID,但不应该有一个名称,因为它的值不应该与主表单一起提交.正如在其他答案中已经提到的,按钮应该更改为"按钮"类型而不是"提交".
<form id="bigform" action="bigform.php">
<!-- Tabs here -->
<fieldset id="newpersonProxy">
<input id="extra">
<button type="button" value="Add">
</fieldset>
</form>
Run Code Online (Sandbox Code Playgroud)
现在通过Javascript不显眼地添加所需的行为:
#newperson.#newpersonProxy以及按钮的click事件来响应"提交" .对于keyup事件,使用event.which而不是event.keyCodejQuery标准化它.你想要event.which == 13输入密钥.$("#newperson").submit().这有效地将序列化和发送数据的责任委托给第二种形式,允许将任何类型的逻辑附加到第二种形式,并从第一种形式解除耦合.
此外,由于首先考虑功能HTML,一个简单的调整可以允许表单在没有Javascript的情况下完美地工作 - 只需隐藏<fieldset>使用CSS,并使用Javascript显示它.如果Javascript被关闭,标签将分开,嵌套的字段集将被隐藏,第二个表格将被显示(并且完全正常运行,而不是通过AJAX).