一、前言
jQuery From插件是一个优秀的Ajax表单插件,使用它可以让你非常容易地、无侵入地升级HTML表单以支持Ajax。jQuery From有两个主要方法:ajaxForm和ajaxSubmit,它们集合了从控制表单元素到决定如何管理提交进程的功能,这两个方法支持许多充分控制数据提交的参数选项(options)。用Ajax来提交表单,你不可能找到比这个更容易的了。
二、快速入门
1、增加表单代码
<body> <form id="myForm" action="comment.php" method="post"> Name: <input type="text" name="name" /> Comment: <textarea name="comment"></textarea> <input type="submit" value="提交评论" /> </form> </body>
2、引入jQuery和Form插件文件
<html> <head> <script type="text/javascript" src="jquery-1.3.2.js"></script> <script type="text/javascript" src="jquery.form.js"></script> <script type="text/javascript"> // 等待装入DOM $(document).ready(function() { // 绑定'myForm'并提供一个简单的回调函数 $('#myForm').ajaxForm(function() { alert("感谢你的评论!"); }); }); </script> </head> ...
就这样简单,当该表单被提交时,name和comment字段会被提交给comment.php文件进行处理,如果服务器返回成功状态,用户就会看到“感谢”信息。
三、表单插件下载
jQuery From插件的当前最新版本为2.43,支持jQuery 1.3.2。
下载地址:http://github.com/malsup/form/raw/master/jquery.form.js?v2.43
四、表单插件API
英文原文:http://www.malsup.com/jquery/form/#api
表单插件API提供了几个方法,让你轻松管理表单数据和进行表单提交。
ajaxForm
增加所有需要的事件监听器,为AJAX提交表单做好准备。ajaxForm不能提交表单。在document的ready函数中,使用ajaxForm来为AJAX提交表单进行准备。ajaxForm接受0个或1个参数。这个单个的参数既可以是一个回调函数,也可以是一个Options对象。
可链:是。
示例:
$('#myFormId').ajaxForm();
ajaxSubmit
马上由AJAX来提交表单。大多数情况下,都是调用ajaxSubmit来对用户提交表单进行响应。ajaxSubmit接受0个或1个参数。这个单个的参数既可以是一个回调函数,也可以是一个Options对象。
可链:是。
示例:
// 绑定表单提交事件处理器 $('#myFormId').submit(function() { // 提交表单 $(this).ajaxSubmit(); // return false是为了防止普通浏览器进行表单提交和产生页面导航(防止页面刷新?) return false; });
formSerialize
将表单序列化成一个查询字符串。这个方法将返回以下格式的字符串:name1=value1&name2=value2 。
可链:否,这个方法返回一个字符串。
示例:
var queryString = $('#myFormId').formSerialize(); // 现在可以使用$.get、$.post、$.ajax等来提交数据 $.post('myscript.php', queryString);
fieldSerialize
将表单的字段元素序列化成一个查询字符串。当只有部分表单字段需要进行序列化时,这个就方便了。这个方法将返回以下格式的字符串:name1=value1&name2=value2。
可链:否,这个方法返回一个字符串。
示例:
var queryString = $('#myFormId .specialFields').fieldSerialize();
fieldValue
返回匹配插入数组中的表单元素值。从0.91版起,该方法将总是以数组的形式返回数据。如果元素值被判定可能无效,则数组为空,否则它将包含一个或多于一个的元素值。
可链:否,该方法返回数组。
示例:
// 取得密码输入值 var value = $('#myFormId :password').fieldValue(); alert('The password is: ' + value[0]);
resetForm
通过调用表单元素原有的DOM方法,将表单恢复到初始状态。
可链:是。
实例:
$('#myFormId').resetForm();
clearForm
清除表单元素。该方法将所有的文本(text)输入字段、密码(password)输入字段和文本区域(textarea)字段置空,清除任何 select元素中的选定,以及将所有的单选(radio)按钮和多选(checkbox)按钮重置为非选定状态。
可链:是。
$('#myFormId').clearForm();
clearFields
清除字段元素。只有部分表单元素需要清除时才方便使用。
可链:是。
$('#myFormId .specialFields').clearFields();
五、ajaxForm和ajaxSubmit的参数选项Options
ajaxForm和ajaxSubmit都支持众多的选项参数,这些选项参数可以使用一个Options对象来提供。Options只是一个 JavaScript对象,它包含了如下一些属性与值的集合:
target
指明页面中由服务器响应进行更新的元素。元素的值可能被指定为一个jQuery选择器字符串,一个jQuery对象,或者一个DOM元素。
默认值:null。
replaceTarget
target
选项一起使用。如果想将目标元素一起替换掉,请设为
true,如果只想替换目标元素的内容 ,则设为
false。
默认值:false
在v2.43后增加
url
指定提交表单数据的URL。
默认值:表单的action属性值
type
指定提交表单数据的方法(method):“GET”或“POST”。
默认值:表单的method属性值(如果没有找到默认为“GET”)。
beforeSubmit
表单提交前被调用的回调函数。“beforeSubmit”回调函数作为一个钩子(hook),被提供来运行预提交逻辑或者校验表单数据。如果 “beforeSubmit”回调函数返回false,那么表单将不被提交。“beforeSubmit”回调函数带三个调用参数:数组形式的表单数据,jQuery表单对象,以及传入ajaxForm/ajaxSubmit中的Options对象。表单数组接受以下方式的数据:
[ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
默认值:null
success
表单成功提交后调用的回调函数。如果提供“success”回调函数,当从服务器返回响应后它被调用。然后由dataType选项值决定传回 responseText还是responseXML的值。
默认值:null
dataType
期望返回的数据类型。null、“xml”、“script”或者“json”其中之一。dataType提供一种方法,它规定了怎样处理服务器的响应。这个被直接地反映到jQuery.httpData方法中去。下面的值被支持:
'xml':如果dataType == 'xml',将把服务器响应作为XML来对待。同时,如果“success”回调方法被指定, 将传回responseXML值。
'json':如果dataType == 'json', 服务器响应将被求值,并传递到“success”回调方法,如果它被指定的话。
'script':如果dataType == 'script', 服务器响应将求值成纯文本。
默认值:null(服务器返回responseText值)
semantic
布尔值,表示数据是否必须严格按照语义顺序(slower?)来进行提交。注意:一般来说,表单已经按照语义顺序来进行了序列化,除了 type="image"的input元素。如果你的服务器有严格的语义要求,以及表单中包含有一个type="image"的input元素,就应该将 semantic设置为true。
默认值:false
resetForm
布尔值,表示如果表单提交成功是否进行重置。
默认值: null
clearForm
布尔值,表示如果表单提交成功是否清除表单数据。
默认值:null
iframe
布尔值,指明表单是否总以iframe作为服务器响应的目标,它与文件上传一起使用。欲了解更多信息,参看代码实例页面的文件上传文档。
默认值:false
iframeSrc
字符串值,当/如果使用iframe时作为iframe的src属性。
默认值:about:blank
网页使用https协议时默认值为:javascript:false
forceSync
布尔值,当上传文件(或使用iframe选项)时,提交表单前为了消除短延迟,设置为true。延迟的使用是为了让浏览器渲染DOM更新前执行原有的表单submit。这时显示一条信息告知用户,如:“请稍等...”,会改善可用性。
默认值:false
在v2.38后增加
示例:
// 准备好Options对象 var options = { target: '#divToUpdate', url: 'comment.php', success: function() { alert('Thanks for your comment!'); } }; // 将options传给ajaxForm $('#myForm').ajaxForm(options);
注意:Options对象还可以用来将值传递给 jQuery的$.ajax方法。如果你熟悉$.ajax所支持的options,你可以利用它们来将Options对象传递给ajaxForm和ajaxSubmit。
六、代码实例及演示
地址:http://www.malsup.com/jquery/form/#ajaxForm
ajaxForm
// prepare the form when the DOM is ready $(document).ready(function() { var options = { target: '#output1', // target element(s) to be updated with server response beforeSubmit: showRequest, // pre-submit callback success: showResponse // post-submit callback // other available options: //url: url // override for form's 'action' attribute //type: type // 'get' or 'post', override for form's 'method' attribute //dataType: null // 'xml', 'script', or 'json' (expected server response type) //clearForm: true // clear all form fields after successful submit //resetForm: true // reset the form after successful submit // $.ajax options can be used here too, for example: //timeout: 3000 }; // bind form using 'ajaxForm' $('#myForm1').ajaxForm(options); }); // pre-submit callback function showRequest(formData, jqForm, options) { // formData is an array; here we use $.param to convert it to a string to display it // but the form plugin does this for you automatically when it submits the data var queryString = $.param(formData); // jqForm is a jQuery object encapsulating the form element. To access the // DOM element for the form do this: // var formElement = jqForm[0]; alert('About to submit: \n\n' + queryString); // here we could return false to prevent the form from being submitted; // returning anything other than false will allow the form submit to continue return true; } // post-submit callback function showResponse(responseText, statusText, xhr, $form) { // for normal html responses, the first argument to the success callback // is the XMLHttpRequest object's responseText property // if the ajaxForm method was passed an Options Object with the dataType // property set to 'xml' then the first argument to the success callback // is the XMLHttpRequest object's responseXML property // if the ajaxForm method was passed an Options Object with the dataType // property set to 'json' then the first argument to the success callback // is the json data object returned by the server alert('status: ' + statusText + '\n\nresponseText: \n' + responseText + '\n\nThe output div should have already been updated with the responseText.'); }
ajaxSubmit
// prepare the form when the DOM is ready $(document).ready(function() { var options = { target: '#output2', // target element(s) to be updated with server response beforeSubmit: showRequest, // pre-submit callback success: showResponse // post-submit callback // other available options: //url: url // override for form's 'action' attribute //type: type // 'get' or 'post', override for form's 'method' attribute //dataType: null // 'xml', 'script', or 'json' (expected server response type) //clearForm: true // clear all form fields after successful submit //resetForm: true // reset the form after successful submit // $.ajax options can be used here too, for example: //timeout: 3000 }; // bind to the form's submit event $('#myForm2').submit(function() { // inside event callbacks 'this' is the DOM element so we first // wrap it in a jQuery object and then invoke ajaxSubmit $(this).ajaxSubmit(options); // !!! Important !!! // always return false to prevent standard browser submit and page navigation return false; }); }); // pre-submit callback function showRequest(formData, jqForm, options) { // formData is an array; here we use $.param to convert it to a string to display it // but the form plugin does this for you automatically when it submits the data var queryString = $.param(formData); // jqForm is a jQuery object encapsulating the form element. To access the // DOM element for the form do this: // var formElement = jqForm[0]; alert('About to submit: \n\n' + queryString); // here we could return false to prevent the form from being submitted; // returning anything other than false will allow the form submit to continue return true; } // post-submit callback function showResponse(responseText, statusText, xhr, $form) { // for normal html responses, the first argument to the success callback // is the XMLHttpRequest object's responseText property // if the ajaxSubmit method was passed an Options Object with the dataType // property set to 'xml' then the first argument to the success callback // is the XMLHttpRequest object's responseXML property // if the ajaxSubmit method was passed an Options Object with the dataType // property set to 'json' then the first argument to the success callback // is the json data object returned by the server alert('status: ' + statusText + '\n\nresponseText: \n' + responseText + '\n\nThe output div should have already been updated with the responseText.'); }
表单校验
1、HTML代码:
<form id="validationForm" action="dummy.php" method="post"> Username: <input type="text" name="username" /> Password: <input type="password" name="password" /> <input type="submit" value="Submit" /> </form>
2、JavaSCript代码:
// prepare the form when the DOM is ready $(document).ready(function() { // bind form using ajaxForm $('#myForm2').ajaxForm( { beforeSubmit: validate } ); });
注意其中的$('#myForm2').ajaxForm( { beforeSubmit: validate } );一句,这是指明进行Ajax提交前先进行表单输入校验。validate为校验回调函数。如果返回false,则终止Ajax提交。
3、验证方法一:利用formData 参数进行校验
function validate(formData, jqForm, options) { // formData is an array of objects representing the name and value of each field // that will be sent to the server; it takes the following form: // // [ // { name: username, value: valueOfUsernameInput }, // { name: password, value: valueOfPasswordInput } // ] // // To validate, we can examine the contents of this array to see if the // username and password fields have values. If either value evaluates // to false then we return false from this method. for (var i=0; i < formData.length; i++) { if (!formData[i].value) { alert('Please enter a value for both Username and Password'); return false; } } alert('Both fields contain values.'); }
4、验证方法二:利用jqForm参数来进行校验
function validate(formData, jqForm, options) { // jqForm is a jQuery object which wraps the form DOM element // // To validate, we can access the DOM elements directly and return true // only if the values of both the username and password fields evaluate // to true var form = jqForm[0]; if (!form.username.value || !form.password.value) { alert('Please enter a value for both Username and Password'); return false; } alert('Both fields contain values.'); }
5、验证方法三:利用fieldValue方法来进行校验
function validate(formData, jqForm, options) { // fieldValue is a Form Plugin method that can be invoked to find the // current value of a field // // To validate, we can capture the values of both the username and password // fields and return true only if both evaluate to true var usernameValue = $('input[name=username]').fieldValue(); var passwordValue = $('input[name=password]').fieldValue(); // usernameValue and passwordValue are arrays but we can do simple // "not" tests to see if the arrays are empty if (!usernameValue[0] || !passwordValue[0]) { alert('Please enter a value for both Username and Password'); return false; } alert('Both fields contain values.'); }
处理JSON数据
1、HTML代码:
<form id="jsonForm" action="json-echo.php" method="post"> Message: <input type="text" name="message" value="Hello JSON" /> <input type="submit" value="Echo as JSON" /> </form>
2、服务器端代码(json- echo.php):
<?php echo '{ message: "' . $_POST['message'] . '" }'; ?>
3、JavaScript代码(客户端):
// prepare the form when the DOM is ready $(document).ready(function() { // bind form using ajaxForm $('#jsonForm').ajaxForm({ // dataType identifies the expected content type of the server response dataType: 'json', // success identifies the function to invoke when the server response // has been received success: processJson }); });
4、回调函数processJson
function processJson(data) { // 'data' is the json object returned from the server alert(data.message); }
处理responseXML数据
1、HTML代码:
<form id="xmlForm" action="xml-echo.php" method="post"> Message: <input type="text" name="message" value="Hello XML" /> <input type="submit" value="Echo as XML" /> </form>
2、服务器端PHP代码:
<?php // !!! IMPORTANT !!! - the server must set the content type to XML header('Content-type: text/xml'); echo '<root><message>' . $_POST['message'] . '</message></root>'; ?>
3、 JavaScript代码:
// prepare the form when the DOM is ready $(document).ready(function() { // bind form using ajaxForm $('#xmlForm').ajaxForm({ // dataType identifies the expected content type of the server response dataType: 'xml', // success identifies the function to invoke when the server response // has been received success: processXml }); });
4、回调函数(处理返回的XML数据):
function processXml(responseXML) { // 'responseXML' is the XML document returned by the server; we use // jQuery to extract the content of the message node from the XML doc var message = $('message', responseXML).text(); alert(message); }
注意$().text()的用法,由于JQuery支持xpath,因此处理XML DOM文档非常简单方便。
处理responseTEXT数据
1、HTML代码:
<form id="htmlForm" action="html-echo.php" method="post"> Message: <input type="text" name="message" value="Hello HTML" /> <input type="submit" value="Echo as HTML" /> </form>
2、服务器端PHP代码:
<?php echo '<div style="background-color:#ffa; padding:20px">' . $_POST['message'] . '</div>'; ?>
注意:返回的TEXT数据为HTML代码。
3、JavaScript代码:
// prepare the form when the DOM is ready $(document).ready(function() { // bind form using ajaxForm $('#htmlForm').ajaxForm({ // target identifies the element(s) to update with the server response target: '#htmlExampleTarget', // success identifies the function to invoke when the server response // has been received; here we apply a fade-in effect to the new content success: function() { $('#htmlExampleTarget').fadeIn('slow'); } }); });
注意:回调函数为一诺名函数,其对数据的显示加了一个JQuery的淡出特效。如果机器速度太快的话,效果并不明显。
处理文件上传
试译如下:
页面演示了表单插件的文件上传能力。这里没有专门处理文件上传的代码,file input元素会自动检测和处理。
文件上传无法使用浏览器的XMLHttpRequest对象,所以表单插件使用了隐藏的iframe元素来帮助处理上传任务。这种技术使用得比较普遍,但也存在固有局限性。iframe元素被用作表单提交操作的目标,意味着服务端的响应是发送到iframe的。如果返回类型是HTML或者XML的时候,它表现得很好,但如果返回类型是script或者JSON的话就无法工作。script和JSON经常含有一些在HTML标识中找到使用实参、需要呈现的字符。
为了解决返回script和JSON数据的难题,表单插件允许返回的这些数据植入到一个textarea元素中,当这些返回类型与文件上传一起使用时推存使用这一技术。请注意,如果在表单中没有file input元素,那么请求使用普通的XHR来提交表单(不是iframe)。张贴在这里的服务端代码可了解什么时候使用textarea,什么时候不使用。如果你愿意,可以使用插件的iframe参数选项来强迫使用iframe模式,然后服务器可以将返回数据植入到一个textarea中。下面的响应表明script是如何从服务器返回给表单的:
<textarea>
for (var i=0; i < 10; i++) {
// do some processing
}
</textarea>
下面的表单提供了一个“file”类型的input元素和指定响应dataType的select元素。表单提交给files.php文件,该文件利用dataType来决定返回的响应类型。
<form id="uploadForm" action="files.php" method="POST" enctype="multipart/form-data"> <input name="MAX_FILE_SIZE" value="100000" type="hidden"> File: <input name="file" type="file"> Return Type: <select id="uploadResponseType" name="mimetype"> <option value="html">html</option> <option value="json">json</option> <option value="script">script</option> <option value="xml">xml</option> </select> <input value="Submit" type="submit"> </form> <p> <label>Output:</label> </p> <div id="uploadOutput"></div>
$('#uploadForm').ajaxForm({ beforeSubmit: function(a,f,o) { o.dataType = $('#uploadResponseType')[0].value; $('#uploadOutput').html('Submitting...'); }, success: function(data) { var $out = $('#uploadOutput'); $out.html('Form success handler received: <strong>' + typeof data + '</strong>'); if (typeof data == 'object' && data.nodeType) data = elementToString(data.documentElement, true); else if (typeof data == 'object') data = objToString(data); $out.append('<div><pre>'+ data +'</pre></div>'); } });
<? $type = $_POST['mimetype']; $xhr = $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'; if ($type == 'xml') { header('Content-type: text/xml'); ?> <address attr1="value1" attr2="value2"> <street attr="value">A & B</street> <city>Palmyra</city> </address> <? } else if ($type == 'json') { // 如果请求不是从XHR来的,用一个textarea包裹json if (!$xhr) echo '<textarea>'; ?> { "library": "jQuery", "plugin": "form", "hello": "goodbye", "tomato": "tomoto" } <? if (!$xhr) echo '</textarea>'; } else if ($type == 'script') { // 如果请求不是从XHR来的,用一个textarea包裹script if (!$xhr) echo '<textarea>'; ?> for (var i=0; i < 2; i++) alert('Script evaluated!'); <? if (!$xhr) echo '</textarea>'; } else { // 为html请求返回文本var_dump echo "VAR DUMP:<p />"; var_dump($_POST); foreach($_FILES as $file) { $n = $file['name']; $s = $file['size']; if (!$n) continue; echo "File: $n ($s bytes)"; } } ?>
论坛贴:http://qeephp.com/bbs/viewthread.php?tid=201&extra=&highlight=jquery%2Bform&page=1