Symfony:添加记录后更改响应
通过ajax打开表单(使用jquery),我想保存它,而无需重新加载整个页面。在哪里我必须更改代码,以获得文本响应(例如“ok!”)而不是重定向来编辑页面?Symfony:添加记录后更改响应
这是我的JS:
$("#newcatlink").click(function() {
$.ajax({
'url': "category/new",
'success': function(data, textStatus, jqXHR) {
$("#mdialog").html(data);
$("#_form_jqhide").hide();
$("#mdialog").dialog({
modal: true,
width: 500,
resizable: false,
buttons: {
Save: function() {
$.ajax({
'type': 'POST',
'url': 'category/create',
'data': $("#categoryform").serialize(),
'success': function(data, textStatus, jqXHR) {
alert(data);
}
});
},
Cancel: function() {
$(this).dialog("close");
}
}
});
}
});
});
我改变processForm行动的actions.class.php这样的:
...
if ($form->isValid())
{
$Category = $form->save();
if($request->isXmlHttpRequest()) {
return $this->renderText("ok!");
} else {
$this->redirect('category/edit?id='.$Category->getId());
}
}
,但它并没有改变任何东西。这个怎么做?
编辑12年8月1日:
我根据blowski和sakfa答案修改了自己的代码,但我得到的另一个问题:如何捕捉形式的错误?我添加到processForm其他如果和它按预期工作,但我不能得到错误消息/代码/无论回来,只有一个事实,即错误存在。
这里是代码:http://pastebin.com/ppbPM88G ,这是服务器回答发送形式与一个所需的字段为空后:
{ “haserrors”:真, “错误”:[]}
根据我们的谈话,我可以看到发生了什么。如果我理解了你的评论,它不会重定向整个页面,它只是在对话框中重新渲染原始表单?
用户提交表单后,如果有效,则重定向。但是,由于您绕过重定向,因此它会到达$this->setTemplate('new')
位代码,因此会再次显示new
表单,并使用来自刚完成表单的数据填充。
要解决它,请在创建操作是这样的:
if($request->isXmlHttpRequest()) {
$this->renderText(json_encode(array('valid' => $form->isValid())));
} else {
$this->setTemplate('new');
}
你还需要改变你的Ajax请求指定它期待一个JSON响应。然后,如果表单有效,请关闭对话框(或保存后要执行的任何操作)。
感谢您的答案,我花了一点我的问题。 – WombaT 2012-01-08 11:57:22
基于对话的位置:
你已经在行动把return $this->renderText("ok!")
在processForm
方法不是(像executeCreate
)。将返回行和条件检查移至执行XXX方法。
编辑2012-01-08
我已删除了我的代码片段老,因为他们现在不用于任何用途,因为你编辑你的原代码有效结合我改变那里。
为您的新的问题:处理表单时
基本上symfony1 API很烂,这就是为什么你有这么多的问题。
首先,您需要知道,此api不是用来处理AJAX表单提交的验证 - 这是因为sfForm可以验证自己,可以在内部存储错误并可以将它们呈现为HTML - 但在那里并不是常规的(据我所知)以某种可序列化的格式返回错误(如fieldname => errorMessage对,json_encodes很好)。
与您的代码开始,我会替你做的是:
第一:创建独立的行动只是为了AJAX提交处理,假设你做POST请求
public function exucuteAjaxFormSubmission(sfWebRequest $request)
{
//this action handles ONLY ajax so we can safely set appropriate headers
$this->getResponse()->setContentType('text/json');
$form = new form();
$form->bind($request->getPostParameters());
if ($form->isValid()) {
//do your logic for positive form submission, i.e. create or update record in db
return json_encode('ok'); //notify client that everything went ok
} else {
return $this->doSomeMagicToGetFormErrorsAsAnJsonEncodedArray();
}
}
我们的doSomeMagicToGetFormErrorsAsAnJsonEncodedArray
部分:你想以json格式获取表单错误。为此,我们将为您的表单类添加一个简单的方法(因为这是验证逻辑的“接口”)。
一些理论:在一个名为sfValidatorErrorSchema结构内部sfForm商店验证错误。 sfValidatorErrorSchema将错误存储在两个列表中 - namedErrors
和globalErrors
。命名的一个错误是抛出“字段验证”上name
场(即必需的字符串,验证,全球错误的抛出整个形式(即全球postValidators)。每个错误是得罪验证抛出sfValidatorError对象。
警告:其实这种结构是递归的,但你会看到它只有在您使用在这种情况下下面的函数嵌入表单必须改变,以包括情况sfValidatorErrorSchema可以包含另一个sfValidatorErrorSchema,不sfValidatorError ..我希望你不要使用嵌入形式,因为这在symfony中吸除普通形式的API,甚至更多。
但足够说话,如果你只是想代码,然后复制粘贴这些甲基ODS到你的窗体类:
class myForm extends sfForm {
(...)
/** a helper method to convert error schema to an array */
public function getSerializableErrors()
{
$result = array();
foreach ($this->getErrorSchema()->getNamedErrors() as $fieldName => $error) {
$result[$fieldName] = $error->getMessage();
}
foreach ($this->getErrorSchema()->getGlobalErrors() as $error) {
$result['_globals'][] = $error->getMessage();
}
return $result;
}
/** screw array, just give me ready to send json! */
public function getJsonEncodedErrors()
{
return json_encode($this->getSerializableErrors());
}
}
现在只是改变doSomeMagicToGetFormErrorsAsAnJsonEncodedArray
到getJsonEncodedErros
,你就与验证基础Ajax表单张贴做 - 你应该有足够的知识,现在正确地实现你的逻辑。我对目前的symfony的1.4版本测试了这个,所以如果有什么差错,可能是老体协版中的问题(你没有告诉我你使用的版本)
它仍然重定向到类别/编辑页面?在你返回'$ this-> renderText('ok!')'之前,放一个'die('here')'语句来检查它是否进入该分支。 – 2012-01-07 14:02:49
与死亡,它显示“在这里”如预期。不死,重定向到编辑页面。 – WombaT 2012-01-07 14:40:55
我想不出为什么它会继续运行重定向。动作类中的其他地方肯定没有重定向?通常为此,我使用'if(!$ request-> isXmlHttpRequest()){$ this-> redirect()}',并将文本渲染放在公共方法中。 – 2012-01-07 14:46:03