我通过ajax打开一个表单(使用jquery),我想保存它而不重新加载整个页面。我必须更改代码,获取文本响应(例如“ok!”)而不是重定向到编辑页面?
这是我的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");
}
}
});
}
});
});
我在actions.class.php中更改了processForm操作,如下所示:
...
if ($form->isValid())
{
$Category = $form->save();
if($request->isXmlHttpRequest()) {
return $this->renderText("ok!");
} else {
$this->redirect('category/edit?id='.$Category->getId());
}
}
但它没有改变任何东西。怎么做?
编辑8/1/12:
我根据blowski和sakfa的答案对我的代码进行了更改,但我得到另一个问题:如何捕获表单错误?我将processForm else添加到if并且它按预期工作但我无法获得错误消息/代码/无论如何,只有错误存在的事实。
以下是代码:http://pastebin.com/ppbPM88G 这是服务器答案后发送表单,其中一个必填字段为空:
{ “haserrors”:真, “错误”:[]}
答案 0 :(得分:2)
基于此处的对话:
您已将return $this->renderText("ok!")
方法中的processForm
置于不执行状态(如executeCreate
)。将返回行和条件检查移动到executeXXX方法。
编辑2012-01-08
我删除了旧的代码段,因为它们现在没有任何用处,因为您编辑了原始代码,有效地将我的更改纳入其中。
关于你的新问题:
基本上symfony1 api在处理表单时很糟糕,这就是你遇到这么多问题的原因。
首先,你需要知道这个api不是为了处理AJAX表单提交而设计的 - 这是因为sfForm可以自我验证,可以在内部存储它的错误并且可以将它们呈现为HTML - 但是没有例程(据我所知)以某种可序列化的格式返回错误(比如一个fieldname => errorMessage对的数组,json_encodes很好)。
从您的代码开始,我将在您的位置做的是:
首先:假设您执行POST请求
,仅为ajax提交处理创建单独的操作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格式获取表单错误。为此,我们将为您的表单类添加一个简单的方法(因为这是验证逻辑的'接口')。
一些理论:内部sfForm在一个名为sfValidatorErrorSchema的结构中存储验证错误。 sfValidatorErrorSchema将错误存储在两个列表中 - namedErrors
和globalErrors
。命名错误是为“字段验证器”抛出的错误(即name
字段上需要的字符串验证器。全局错误是整个表单抛出的错误(即全局postValidators)。每个错误都是由违规验证器抛出的sfValidatorError对象。
警告:实际上这个结构是递归的,但是只有在使用嵌入式表单时才会看到它在这种情况下,必须更改以下函数以包含sfValidatorErrorSchema可以包含另一个sfValidatorErrorSchema的情况,而不是sfValidatorError ..我希望你不要使用嵌入式表格,因为这在symfony中比简单的API更糟糕。
但是,如果您只想要代码,那么请将这些方法粘贴到您的表单类中:
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版本上测试了这个,所以如果出现任何问题,可能是旧版本的sf问题(你没告诉我你使用的是哪个版本)
答案 1 :(得分:1)
根据我们的谈话,我可以看到发生了什么。如果我理解了你的评论,它不会重定向整个页面,它只是在对话框中重新渲染原始表单?
用户提交表单后,如果有效,则重定向。但是,由于您绕过重定向,它会转到代码的$this->setTemplate('new')
位,因此会再次显示new
表单,并填充刚刚完成的表单中的数据。
要解决此问题,请在创建操作中使用以下内容:
if($request->isXmlHttpRequest()) {
$this->renderText(json_encode(array('valid' => $form->isValid())));
} else {
$this->setTemplate('new');
}
您还需要更改Ajax请求以指定它期望JSON响应。然后,如果表单有效,请关闭对话框(或保存后要执行的任何操作)。