一、前言
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: ' + 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 + ' responseText: ' + responseText +
- ' The 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: ' + 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 + ' responseText: ' + responseText +
- ' The 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=" 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的淡出特效。如果机器速度太快的话,效果并不明显。
处理文件上传
Since it is not possible to upload files using the browser's XMLHttpRequest object, the Form Plugin uses a hidden iframe element to help with the task. This is a common technique, but it has inherent limitations. The iframe element is used as the target of the form's submit operation which means that the server response is written to the iframe. This is fine if the response type is HTML or XML, but doesn't work as well if the response type is script or JSON, both of which often contain characters that need to be repesented using entity references when found in HTML markup.
To account for the challenges of script and JSON responses, the Form Plugin allows these responses to be embedded in a textarea element and it is recommended that you do so for these response types when used in conjuction with file uploads. Please note, however, that if there is no file input in the form then the request uses normal XHR to submit the form (not an iframe). This puts the burden on your server code to know when to use a textarea and when not to. If you like, you can use the iframe option of the plugin to force it to always use an iframe mode and then your server can always embed the response in a textarea. The following response shows how a script should be returned from the server:
<textarea>
for (var i=0; i < 10; i++) {
// do some processing
}
</textarea>
The form below provides an input element of type "file" along with a select element to specify the dataType of the response. The form is submitted to files.php which uses the dataType to determine what type of response to return.
试译如下:
页面演示了表单插件的文件上传能力。这里没有专门处理文件上传的代码,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)";
- }
- }
- ?>