How to use Js->submit() in CakePHP?

2020-03-25 09:34发布

问题:

Im trying to create a simple Ajax form for a message board in a CakePHP application, but I can't for the life of me figure out how to properly use the Js->submit() function to submit a form via Ajax.

Heres the form code within my view:

<?php

 echo $this->Form->create('Message',array(
  'type' => 'post', 
  'action' => 'add',
  'onSubmit' => 'return false;'
 ));

 echo $this->Form->input('name', array('label' => 'From:'));
 echo $this->Form->input('text', array('label' => 'Message:'));

 echo $this->Js->submit('Post Your Message', array(
  'action' => 'add',
  'update' => '#message_board'
 ));

 echo $this->Form->end();

?>

<div id="message_board">
    ...
</div>

And here is the controller action:

function add() {
 $this->autoRender = false; 
 if($this->RequestHandler->isAjax()) {
     $this->layout = 'ajax'; //THIS LINE NEWLY ADDED
     if(!empty($this->data)) {
         if($this->Message->save($this->data)) {
             $this->Session->setFlash('Your Message has been posted');
         }
     }
 }
}

Oddly, what happens when I submit the form is an exact copy of the form and its containing div is duplicated INSIDE the message_board div. Weird.

Obviously I'm missing something (or several things). If anyone has any idea, or else knows a good source of information on how to use it, it would be much appreciated.

Thanks.

UPDATE: I tried adding the new line $this->layout = 'ajax'; to the controller (see above), but it had no effect. Here is the jquery output by CakePHP, incase that might tell somebody whats going on.

$(document).ready(function () {
    $("#submit-707957402").bind("click", function (event) {
        $.ajax({
            action:"add", 
            data:$("#submit-707957402").closest("form").serialize(), 
            dataType:"html", 
            success:function (data, textStatus) {
                $("#message_board").html(data);
            }, 
            type:"post", 
            url:"\/messages"
        });
        return false;
    });
});

回答1:

What happens is that it loads the default layout. You'll have to change the layout to ajax with the following line:

$this->layout = 'ajax';

You insert that line inside your isAjax() condition.

Also your options array has the wrong format. The action key should be inside the url key.

$this->Js->submit('Post Your Message', array(
        'url' => array(
            'action' => 'add'
        ),
        'update' => '#message_board'
    )
);


回答2:

I am very late to the party! But a while back, about 3months ago I faced this problem. And what it turned out to be was that I was not giving permission to the user to access that action. The solution was to add some code in the AppController beforeFilter(), something like :

function beforeFilter(){
    $this->Auth->allow('my_actions_name');
}

However I am not really sure why it re-renders the parent div, or sometimes the whole page, but my guess is, that cake is set so that whenever the action is not accessible/allowed, some routing takes place and perhaps index or other default actions, are executed, which causes that to be rendered within your ajax view.

If you inspect the request response inside the browser's network tab( in chrome), it becomes very clear that the response returned is the same content that is being rendered. However, I am a complete newbie and the is answer is based on speculation.

If anyone can give a better explanation(please teach us), I will be the first to upvote :)

Till then, Happy coding