1

我通过 jQuery 插件 AjaxForm 将表单提交到服务器。

这是我的简化视图:

<div id="output1">...here goes my CakePHP PHP form code...</div>

<script type="text/javascript">
    $(document).ready(function() { 
        var options = { 
            target:'#output1',
            beforeSubmit: onBeforeSubmit,
            success: onSuccess,
            error: onError
        }; 
        $('#CommentEditForm').ajaxForm(options); 
    });
</script>    

在我的控制器功能中,当我收到未经模型验证的表单数据时,我更改了 ajax 布局的布局并返回没有默认布局的 html 内容的视图,并将其附加到我视图中的 div#output1 中。

似乎没问题,但现在除了 div#output1 和 javascript 代码之外,我还可以查看表单。我知道我的问题在哪里 - 我需要解决方案如何返回表单数据而不是 javascript 代码和 div#output1 的东西。这个逻辑将在我的所有应用程序中使用,所以我想避免在我的所有视图中硬编码 {if...else} 条件。

4

2 回答 2

4

thaJezath 的回答很好,但还有其他一些事情:

  1. 将 CakePHP Js 助手用于所有 ajax 内容更容易、更 DRY:

    <div id="output">
    <?php
        echo $this->Form->create();
        echo $this->Form->input('input1');
        echo $this->Form->input('input2');
        echo $this->Js->submit('submit',array('update' => '#output');
    ?>
    </div>
    

这将自动添加将为您处理 ajax 提交的缓冲脚本。但是你需要在标签echo $this->Js->writeBuffer();之前的布局中使用 line 。</body>但这仍然会返回<div id="output">...- 如果您更改为'update' => '#content',它将重新加载整个内容 div。

  1. 如果你真的需要更新只是形式而不是其他东西:

在您的视图文件中:

     <div id="output">
     <?php $this->start('ajax-content'); // this line starts new block ?>
     <?php
        echo $this->Form->create();
        echo $this->Form->input('input1');
        echo $this->Form->input('input2');
        echo $this->Js->submit('submit',array('update' => '#output');
    ?>
    <?php
        $this->end(); // this line ends block
        echo $this->fetch('ajax-content'); // this line print contents of block
    ?>
    </div>

在您的 /View/Layouts/ajax.ctp 中:

    <?php
        // next 2 lines only ensure that ajax-content block exists
        // if not it will be just empty string
        $this->startIfEmpty('ajax-content'); 
        $this->end();
        echo $this->fetch('ajax-content'); // this line outputs ajax-content block (the form)
    ?>

因此,总而言之,此方法将您想要返回的内容包含在视图块内的 ajax 内容中。然后 ajax 布局而不是打印整个视图 ( $this->fetch('content');),它只打印 ajax-content 块 ( $this->fetch('ajax-content');) 的内容。这样,您可以在每个视图中标记您想要在 ajax 请求期间返回的所有内容。

这些行:

        $this->end(); // this line ends block
        echo $this->fetch('ajax-content'); // this line print contents of block

可能不太方便 - 将所有块记录代码放在您自己的助手中以简单地使用它是个好主意:

    <div id=...
    $this->AjaxContent->start();
    your form here
    $this->AjaxContent->stop();
    </div>

正如 thaJezath 在评论中所写,JsHelper 将在未来的版本中被弃用,因此如他所说,使用视图块会更安全。HtmlHelper 有这样做的方便的方式:

    <?php $this->Html->scriptStart(array('inline' => false)); ?>
        $(document).ready(function(){ 
            // your code here
        });
    <?php $this->Html->scriptStart(array('inline' => false)); ?>

这会将您的脚本添加到"script"以默认布局打印的 viewBlock 中$this->fetch('script');

于 2013-02-02T21:19:06.257 回答
3

You should use the JavaScript buffer or a 'view block' to output your JavaScript, this way you can output the javascript inside your Layout, not in your view. As you're already switching to a different layout (or no layout) for your AJAX requests, the script will not be included when retrieving via AJAX.

Change your view to this:

Modify the content of your view to this:

<div id="output1">...here goes my CakePHP PHP form code...</div>

<?php

/**
 * I'm using 'heredoc' notation so that you don't have to escape quotes and '$'
 * @link http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc
 */
$script = <<< JS
    $('#CommentEditForm').ajaxForm({ 
        target:'#output1',
        beforeSubmit: onBeforeSubmit,
        success: onSuccess,
        error: onError
    }); 
JS;

/**
 * Append the JavaScript to the JavaScript-buffer
 * using the JS helper
 * 
 * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html
 */
$this->Js->buffer($script);

Output the JavaScript in your layout (e.g. Layouts/default.ctp)

<!-- rest of your layout here -->

<?php
// Output the JavaScript and wrap it in a 'onDomready()' wrapper
echo $this->Js->writeBuffer();
?>
</body>
</html>

NOTE: You DONT have to add the 'onDomready()' to your scripts when using the JS-buffer, CakePHP will add them automatically when outputing the buffer with $this->Js->writeBuffer()

NOTE2: Using the output-buffer allows you to add JavaScript to the buffer multiple times. For example, if you're using 'elements', you are able to add javascript to the buffer as well. This allows you to add script 'as-you-go' and output them all at once at the end of your body

于 2013-02-02T20:36:43.923 回答