CakePHP ajax 表单更新复制页面

Posted

技术标签:

【中文标题】CakePHP ajax 表单更新复制页面【英文标题】:CakePHP ajax form update duplicating page 【发布时间】:2012-05-07 18:04:57 【问题描述】:

我的网站上有一个基本的 ajax 表单,它使用 Js 助手,它工作正常,但是当出现验证错误时,更新回调会在我的成功 div 中复制整个页面。

成功 div:

<div id="success"></div>

提交按钮:

echo $this->Js->submit('Send', array(
    'before'=>$this->Js->get('#sending')->effect('fadeIn'),
    'success'=>$this->Js->get('#sending')->effect('fadeOut'),
    'update'=>'#success',
    'class'=>'btn btn-primary'
));

javascript

$(document).ready(function()

    $('#postkey, #gender, #hair, #location, #message').blur(function()
        $.post(
            '/Cake_ajax/Posts/validate_form',
             field: $(this).attr('id'), value: $(this).val() 
            //handleNameValidation
        );
    );

);

在我的控制器中验证表单功能:

public function validate_form()
    if($this->RequestHandler->isAjax())
        $this->request->data['Post'][$this->request['data']['field']] = $this->request['data']['value'];
        $this->Post->set($this->request->data);
        if($this->Post->validates())
            $this->autorender = FALSE; // don't render a view
            $this->set('error','');
        else
          $this->layout ="ajax";
            $this->autoRender = FALSE;
            $error = $this->validateErrors($this->Post);
            $this->set('error',$this->Post->validationErrors[$this->request['data']['field']][0]);  
        
    

我不知道这些信息是否足够继续,如果我需要发布更多代码,请告诉我。

谢谢。

【问题讨论】:

如果这是直接复制粘贴,您是否尝试将行更改为$this-&gt;autoRender = false(带有大写字母R)?另外,默认使用哪种布局? 我认为[Cakephp Form Validation with Ajax Using jQuery][1] 将有助于在 CakePhp [1] 中设置 ajax 验证:jamnite.blogspot.com/2009/05/… 干杯!!我正在寻找相同问题的解决方案,而您接受的答案解决了我的问题。 当您在谷歌上搜索您遇到的问题并且有人遇到相同的问题并且已经解决时,这种感觉真是太棒了:) 祝您的项目好运。 【参考方案1】:

在 Ajax 请求处理中将布局设置为 ajax。所以错误信息将使用 ajax 布局而不是默认布局呈现。

更新

public function validate_form()
if($this->RequestHandler->isAjax())
    $this->request->data['Post'][$this->request['data']['field']] = $this->request['data']['value'];
    $this->Post->set($this->request->data);
    if($this->Post->validates())            
        $this->autoRender = FALSE; // don't render a view
        $this->set('error','');
    else
        $this->layout ="ajax";
        $this->autoRender = FALSE; 
        $error = $this->validateErrors($this->Post);
        $this->set('error',$this->Post->validationErrors[$this->request['data']['field']][0]);  
    

【讨论】:

您好,谢谢您的回复。不幸的是,这并没有解决问题。真的开始磨我的齿轮了,哈哈。 @Drawrdesign :有一个错误我应该在其他部分添加布局设置。立即更新代码,请立即尝试。 还是不行 :(我可以把整个应用压缩起来让你看一下吗?或者粘贴它,或者别的什么? 谢谢,这是 .zip 文件的链接:drawrdesign.com/wp-content/uploads/2012/04/Cake_ajax.zip【参考方案2】:

确保您是:

使用 RequestHandler 组件(首选):

class AppController 

    var $compontents = array('RequestHandler');


或在您的操作中手动将布局设置为“ajax”:

$this->layout = "ajax"

请求处理程序会在检测到 Ajax 请求时自动将布局设置为 ajax。

ajax 布局只返回渲染视图。

【讨论】:

我的控制器中已经有了请求处理程序,并尝试了 ajax 布局,但没有骰子。【参考方案3】:

我刚刚使用您的 zip 文件测试了您的应用程序。

我观察到这不是放在#success div 中的整个页面,而只是Posts/add.ctp 视图的内容。 所以基本上这意味着 RequestHandler 正确地完成了它的工作,这意味着使用的布局 'ajax' 布局。 为了摆脱表单之外的任何其他内容,add.ctp 页面不应包含表单之外的任何其他内容。在您的情况下,Posts/add.ctp 包含导航链接,这就是它们被重复的原因。

也就是说,提交按钮当前所做的是获取Posts/add.ctp 视图的内容并将其插入到您的空#success div 中。但是您永远不会删除页面上已经存在的表单。 您可以做的是更新包含您的第一个表单的 div 的内容,甚至是整个 Posts/add.ctp 视图的内容。

在您的情况下,只需更新 #content 而不是 #success div 可能会满足您的需求:

echo $this->Js->submit('Send', array(
  'before'=>$this->Js->get('#sending')->effect('fadeIn'),
  'success'=>$this->Js->get('#sending')->effect('fadeOut'),
  'update'=>'#content',
  'class'=>'btn btn-primary',
  'controller'=>'posts',
  'action'=>'add'
));

【讨论】:

效果很好,谢谢。刚才我如何才能呈现成功消息而不用success.ctp替换整个add.ctp页面? 我自己不使用 JsHelper,但更喜欢编写自己的 jQuery 脚本来更好地控制脚本的作用。但在你的情况下,我认为像你一样从控制器渲染一个不同的视图是要做的事情。如果问题是要弄清楚如何使菜单不消失,那么您可以仅更新表单(而不是#content),但仅在视图中呈现您需要的部分(如果您有错误,则为表单,或成功消息)。但是在这种情况下,如果请求是 Ajax 调用,则不要呈现菜单。 请注意,如果您确实需要在 add.ctp 中包含操作菜单或其他内容,您还可以通过将 Ajax 请求发送到另一个操作来实现此目的,该操作将在出现错误或成功消息。 你从来没有接受我的回答。这不是您要找的东西? @nIcO:谢谢伙计。你是救生员。【参考方案4】:

您好,首先,您似乎正在使用 cake 2 lib 并使用 1.3 代码,这可能会起作用,但部分已弃用,可能正在检查 migration guide 。控制台工具还可以将您的代码升级到 2.0/2.1。

其次,您确定要渲染视图和空布局吗? $errors 在 Views/Posts/validate_form.ctp 中定义。您正在设置 $errors 然后不渲染视图。删除将自动渲染设置为 false 并放置在控制器操作的顶部。

$this->layout = 'ajax';
Configure::write("debug",0);

有什么好处吗?

【讨论】:

【参考方案5】:

我遇到了同样的问题。尽管 nIcO 似乎提供了解决方案,但在我的情况下它并没有帮助,因为 Drawrdesign 想要的成功消息仍未呈现。

所以,我查看了您的 zip 文件并找到了解决方案。定义了两个 ajax 调用:1) .blur 和 2) .bind。 1) 用于字段的验证,并通过 AJAX 向 PostsController 的 validate_form() 函数提交数据。并且2)用于观察提交按钮的点击事件,并将数据发送到PostsController的add()函数中。

此问题发生在 2),因为您单击了提交按钮。因此,您应该查看 PostsController 的 add() 函数。在 1) 的 validate_form() 函数中,您添加了以下行:

$this->autoRender = FALSE; 

这就是解决方案。因为在 CakePHP 自动呈现视图的地方,您不希望它发生,因为 AJAX。因此,在情况 1) 完成时,应将其添加到情况 2) 中的 add() 函数中,如下所示:

public function add() 
// Ajax post
if(!empty($this->request->data)) 
    // ...
    $this->autoRender = FALSE; // ** NEW LINE **
        if($this->Post->save($this->request->data)) 
            // ...     
         
        // ...
     
    // ...
 

所以,它停止(自动)渲染 div="#success" 中的 add.ctp,并且您的“sending..”和“succes.ctp”的其他消息仍然开始显示。

PS。 @Drawrdesign,你有没有看过 andrewperk 的指导视频?

【讨论】:

【参考方案6】:
public function admin_edit_comment() 
    $this->layout = 'ajax';
    $this->autoRender = false;
    if ($this->request->is('ajax')) 
        if ($this->FaComment->save($this->request->data, false)) 
            $response['status'] = 'success';
            $response['action'] = 'edit_comment';
            $response['data'] = $this->request->data['FaComment'];
            $response['message'] = __d('vanderdeals', 'Comment saved successfully');


     else 
            $response['status'] = 'error';
            $response['model'] = 'FaComment';
            $response['message'] = __d('vanderdeals', 'Internal server error occurred. Please try again later.');
        

        echo json_encode($response);
    

【讨论】:

以上是关于CakePHP ajax 表单更新复制页面的主要内容,如果未能解决你的问题,请参考以下文章

CakePHP 2.2:预填充 AJAX“更新”div?

Cake 1.3 中有任何好的/简单的 Ajax 示例而不使用已弃用的助手?

CakePHP 3 中表单字段的加密/解密

CakePHP Master/Detail 表单 - 简单问题

调用未定义的方法 Cake\ORM\Entity::query() CakePhp

php [cakephp:MediaController]用文件二进制文件返回cake的响应对象。 #cakephp