您将数据提交到表单“action”(表单元素上的属性)。这是表单处理程序。
很久以前我写了一个要点来处理 ajax 表单提交 (https://gist.github.com/dhensby/5057163)。
以下是一个完整示例,说明如何设置一个基本表单,该表单接受 AJAX 和传统默认浏览器行为的提交(这是一种很好的做法):
将表单添加到我们的控制器
首先我们需要定义我们的表单;你的Page_Controller 应该是这样的:
class Page_Controller extends ContentController {
/**
* A list of "actions" (functions) that are allowed to be called from a URL
*
* @var array
* @config
*/
private static $allowed_actions = array(
'Form',
'complete',
);
/**
* A method to return a Form object to display in a template and to accept form submissions
*
* @return Form
*/
public function Form() {
// include our javascript in the page to enable our AJAX behaviour
Requirements::javascript('framework/thirdparty/jquery/jquery.js');
Requirements::javascript('mysite/javascript/ajaxforms.js');
//create the fields we want
$fields = FieldList::create(
TextField::create('Name'),
EmailField::create('Email'),
TextareaField::create('Message')
);
//create the button(s) we want
$buttons = FieldList::create(
FormAction::create('doForm', 'Send')
);
//add a validator to make sure the fields are submitted with values
$validator = RequiredFields::create(array(
'Name',
'Email',
'Message',
));
//construct the Form
$form = Form::create(
$this,
__FUNCTION__,
$fields,
$buttons,
$validator
);
return $form;
}
/**
* The form handler, this runs after a form submission has been successfully validated
*
* @param $data array RAW form submission data - don't use
* @param $form Form The form object, populated with data
* @param $request SS_HTTPRequest The current request object
*/
public function doForm($data, $form, $request) {
// discard the default $data because it is raw submitted data
$data = $form->getData();
// Do something with the data (eg: email it, save it to the DB, etc
// send the user back to the "complete" action
return $this->redirect($this->Link('complete'));
}
/**
* The "complete" action to send users to upon successful submission of the Form.
*
* @param $request SS_HTTPRequest The current request object
* @return string The rendered response
*/
public function complete($request) {
//if the request is an ajax request, then only render the include
if ($request->isAjax()) {
return $this->renderWith('Form_complete');
}
//otherwise, render the full HTML response
return $this->renderWith(array(
'Page_complete',
'Page',
));
}
}
将这些函数添加到Page_Controller 将使它们在所有 页面类型上可用 - 这可能是不希望的,您应该考虑是否更适合创建新的页面类型(例如ContactPage) 以在此表单上显示
在这里,我们定义了以下方法:
- 创建
Form
- 表单处理程序(保存或发送提交的内容,在
Form 成功验证其数据后运行)
-
complete 操作,用户在成功完成表单提交后将被发送到该操作。
自定义模板以轻松替换内容
接下来我们需要设置我们的模板 - 修改您的 Layout/Page.ss 文件:
<% include SideBar %>
<div class="content-container unit size3of4 lastUnit">
<article>
<h1>$Title</h1>
<div class="content">$Content</div>
</article>
<div class="form-holder">
$Form
</div>
$CommentsForm
</div>
这是从默认的简单主题中获取的,并稍加补充,表单现在被包裹在 <div class="form-holder"> 中,以便我们可以轻松地将表单替换为成功消息。
我们还需要创建一个Layout/Page_complete.ss 模板——除了form-holder div 将是:
<div class="form-holder">
<% include Form_complete %>
</div>
接下来创建 Includes/Form_complete 包含 - 使用包含非常重要,这样我们就可以仅呈现页面的此部分以响应 AJAX 请求:
<h2>Thanks, we've received your form submission!</h2>
<p>We'll be in touch as soon as we can.</p>
创建 javascript 表单监听器
最后,我们需要编写 javascript 以通过 AJAX 发送表单,而不是默认浏览器行为(将其放在 mysite/javascript/ajaxform.js 中):
(function($) {
$(window).on('submit', '.js-ajax-form', function(e) {
var $form = $(this);
var formData = $form.serialize();
var formAction = $form.prop('action');
var formMethod = $form.prop('method');
var encType = $form.prop('enctype');
$.ajax({
beforeSend: function(jqXHR,settings) {
if ($form.prop('isSending')) {
return false;
}
$form.prop('isSending',true);
},
complete: function(jqXHR,textStatus) {
$form.prop('isSending',false);
},
contentType: encType,
data: formData,
error: function(jqXHR, textStatus, errorThrown) {
window.location = window.location;
},
success: function(data, textStatus, jqXHR) {
var $holder = $form.parent();
$holder.fadeOut('normal',function() {
$holder.html(data).fadeIn();
});
},
type: formMethod,
url: formAction
});
e.preventDefault();
});
})(jQuery);
此 javascript 将使用 AJAX 提交表单,完成后它将淡出表单并将其替换为响应并淡入。
对于高级用户:
在此示例中,您网站上的所有表单都将被“ajaxified”,这可能是可以接受的,但有时您需要对此进行一些控制(例如,搜索表单不能像这样很好地工作)。相反,您可以稍微修改代码以仅查找具有特定类的表单。
修改Page_Controller 上的Form 方法,如下所示:
public function Form() {
...
$form->addExtraClass('js-ajax-form');
return $form;
}
像这样修改javascript:
$(window).on('submit', '.js-ajax-form', function(e) {
...
})(jQuery);
现在只有类 js-ajax-form 的表单才会以这种方式运行。