问题
EDIT-
I have posted the answer below.
The question is that I don't understand how/where ZF2 posts form data when a submit button is pressed. So, when I do if ($this->getRequest()->isPost()){
after the ajax call below, it tells me that no data has been posted.
When I do the above isPost()
if statement it works perfectly when I hit the submit button, telling me the data has been posted and subsequently telling me that the form data
is valid.
Here is the ajax call-
<script>
$.ajax({
url: urlform,
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
async: true,
data: ($("#newThoughtForm").serialize() + '&submit=go'),
success: function () {
console.log('SUBMIT WORKS');
setTimeout(function () { <?php echo $this->invokeIndexAction()->test(); ?> ;
}, 1000);
},
//This keeps getting executed because there is no response, as the controller action is not run on a Post()
error: function () {
console.log('There is error while submit');
setTimeout(function () { <?php echo $this->invokeIndexAction()->test(); ?> ;
}, 1000);
}
//I assume the data won't get pushed to the server if there is no response,
//but I can't figure out how to give a response in ZF2 since the controller is not
//run when the Post() is made.
});
Here's the Form-
use Zend\Form\Form;
class newAlbumForm extends Form
{
public function __construct()
{
parent::__construct('newAlbumForm');
$this->setAttribute('method', 'post');
$this->add(array(
'type' => 'AlbumModule\Form\newAlbumFieldset',
'options' => array(
'use_as_base_fieldset' => true
)
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'go'
),
));
}
}
The request for the ajax call-
Request URL:http://test/newAlbum.html
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:46
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Cookie:PHPSESSID=h46r1fmj35d1vu11nua3r49he4
Host:test
Origin:http://test
Referer:http://test/newAlbum.html
User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
X-Requested-With:XMLHttpRequest
Form Dataview sourceview URL encoded
album[albumText]:hello world
submit:go
Response Headersview source
Connection:Keep-Alive
Content-Length:4139
Content-Type:text/html
Date:Sun, 20 Oct 2013 16:52:15 GMT
Keep-Alive:timeout=5, max=99
Server:Apache/2.4.4 (Win64) PHP/5.4.12
X-Powered-By:PHP/5.4.12
The request for the submit button-
Request URL:http://test/newAlbum.html
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:46
Content-Type:application/x-www-form-urlencoded
Cookie:PHPSESSID=h46r1fmj35d1vu11nua3r49he4
Host:test
Origin:http://test
Referer:http://test/newAlbum.html
User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
Form Dataview sourceview URL encoded
album[albumText]:hello world
submit:go
Response Headersview source
Connection:Keep-Alive
Content-Length:4139
Content-Type:text/html
Date:Sun, 20 Oct 2013 16:52:14 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.4 (Win64) PHP/5.4.12
X-Powered-By:PHP/5.4.12
Here is the indexAction() on the controller for completeness-
public function indexAction()
{
echo 'console.log("Index Action is Called");';
$form = new \AlbumModule\Form\newAlbumForm();
if ($this->getRequest()->isPost()){
echo 'console.log("Data posted");';
$form->setData($this->getRequest()->getPost());
if ($form->isValid()){
echo 'console.log("Form Valid");';
//todo
$this->forward()->dispatch('newAlbum', array('action' => 'submitAlbum'));
return new ViewModel(
array(
'form' => $form
)
);
} else {
echo 'console.log("Form Invalid");';
return new ViewModel(
array(
'form' => $form
)
);
}
} else {
echo 'console.log("No data posted")';
return new ViewModel(
array(
'form' => $form
)
);
}
}
As I stated at the beginning, the isPost()
class will return a value of true when the button submits the form, but it will return a value of false when the form is submitted through Ajax.
EDIT-
I have posted the answer below.
回答1:
Usually when you send data from ajax, you don't need to render your template again, and that's what ViewModel do.
Try to add json strategy to your module.config.php
'view_manager' => array(
//other configuration
'strategies' => array(
'ViewJsonStrategy',
),
),
Then your action should look like this:
public function ajaxAction()
{
$request = $this->getRequest();
if ($request->isXmlHttpRequest()){ // If it's ajax call
$data = $request->getPost('data'));
...
}
return new JsonModel($formData);
}
回答2:
Thanks to SzymonM I was able to figure this out,
Basically, it seems that you HAVE to post to an action as type json, this means that whatever controller/action that you're posting to has to return a 'success' response for the jquery ajax call to also return success.
So, trying to post to the index action creates problems as you would be trying to return viewModel objects or a json response through many if statements.
The best option is to post the json request to a different action which will manage the request and response.
Ajax Action-
public function ajaxAction()
{
$form = new \AlbumModule\Form\newAlbumForm();
$request = $this->getRequest();
$response = $this->getResponse();
if ($request->isPost()) {
//$hello is a test variable used for checking if the form is valid
//by checking the response
$hello = 1;
$form->setData($request->getPost());
if ($form->isValid()){
$hello = 4020;
};
}
$messages = array();
if (!empty($messages)){
$response->setContent(\Zend\Json\Json::encode($messages));
} else {
$response->setContent(\Zend\Json\Json::encode(array('success'=>1,'hello'=>$hello)));
}
return $response;
}
Ajax Call-
var urlform = '<?php echo $this->url('AlbumModule\newAlbum\home', array('controller'=>'newAlbum', 'action'=>'ajax')); ?>';
$.ajax({
url: urlform,
type: 'POST',
dataType: 'json',
async: true,
data: $("#newAlbumForm").serialize(),
success: function (data) {
console.log(data);
}
error: function (data) {
console.log(data);
}
});
回答3:
the best approach is to use the
AcceptableViewModelSelector
controller plugin to switch between different strategies
first in module.config.php
return [
'view_manager'=>[
'Strategies'=> 'ViewJsonStrategy',
]
]
and in the controller example: IndexController.php in the indexAction
class IndexController extends AbstarctActionController{
protected $accptCretiria = [
'Zend\View\Model\ViewModel'=>'text/html',
'Zend\View\Model\JsonModel'=>'application/json, text/json'
];
public function indexAction(){
//here if is ajax call it returns jsonView ,and if is normal call it return ViewModel
$viewModel = $this->acceptableViewModelSelector($this->acceptCretiria);
return $viewModel
}
}
回答4:
There is a module for Zend Framework 2 called WasabiLib. It has almost everything onboard to manage ajax requests and responses in a very convinient way. Take a look at the simple example on its homepage providing a simple form:
//inside the phtml
<form id="simpleForm" class="ajax_element" action="simpleFormExample" method="POST"
data-ajax-loader="myLoader">
<input type="text" name="written_text">
<input type="submit" value="try it">
<i id="myLoader" class="fa fa-spinner fa-pulse fa-lg" style="display: none;"></i>
</form>
//Server-side code
public function simpleFormExampleAction(){
$postArray = $this->getRequest()->getPost();
$input = $postArray['written_text'];
$response = new Response(new InnerHtml("#element_simple_form","Server Response: ".$input));
return $this->getResponse()->setContent($response);
}
来源:https://stackoverflow.com/questions/19480297/posting-form-data-to-zf2-controller-with-ajax