Sending jQuery.serialize form via POST, expecting JSON response from controller - php

I would like to ask you how could I send ajax request with serialized by jQuery form and recieve JSON response from controller? I have been trying many solutions but none of them worked for me. I have a little experience in that matter.
Can you provide any good example? Thank You!
Send post with serialized form (POST) by AJAX
Process action in controller function and obtain JSON response in ajax -> success
I'm using CakePHP 2.4.1
My ajax request
$.ajax({
type: "post",
url: location.pathname + "/edit",
data: data,
success: function(response) {
$("#content").html(response); // i would like to recieve JSON response
alert(response); // here ;C
},
error: function(){
alert("error");
}
});
Part of my function in controller
public function admin_edit(){
//................ some logic passed
if($this->request->is('ajax')){
$this->layout = 'ajax';
$this->autoRender = false;
$this->set(compact('user'));
$this->disableCache();
foreach($this->request->data['User'] as $key => $value){
if(empty($value)){
unset($this->request->data['User'][$key]);
}
}
$this->User->id = $this->request->data['User']['id'];
if($this->User->save($this->request->data)){
$this->Session->setFlash('Użytkownik został zmodyfikowany');
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash('Nie zmodyfikowano użytkownika');
}
}
What i would like to recieve is JSON response from the controller.
example
[{"id":"1", "username":"test", ... }]

Ok, I think what confuse you are little stuff, but mixed together can be a bit hard to debug for someone with little experience. I'll post a basic example of what should work for you, and you iterate over that. Tell us if there's another error (it's easier to check for specific errors rather than the view/controller possible error).
First, in the ajax call, change for console.log(response); to debug better
//alert(response);
console.log(response);
},
error: function(){
alert("error");
console.log(response);
}
});
And in the controller
public function admin_edit(){
//................ some logic passed
if($this->request->is('ajax')){
/* layout not necessary if you have autoRender = false */
//$this->layout = 'ajax';
/* actually, no need for this either with _serialize, but add it if you have unwanted html rendering problems */
//$this->autoRender = false;
$this->set(compact('user'));
/* other code that doesn't really matter for the example ... */
$this->User->id = $this->request->data['User']['id'];
if($this->User->save($this->request->data)){
/* NO!! */
//$this->Session->setFlash('Użytkownik został zmodyfikowany');
//return $this->redirect(array('action' => 'index'));
$status = 'OK';
$message = 'Użytkownik został zmodyfikowany';
$this->set(compact('message', 'status'));
}
/* NO EITHER!! */
//$this->Session->setFlash('Nie zmodyfikowano użytkownika');
$status = 'NOT-OK';
$message = 'Not sure what your flash says but let\'s assume it an error alert';
$this->set(compact('message', 'status'));
//serialize variables you have set for the "ghost" view
$this->set('_serialize', array('user', 'message', 'status'));
}
}
I think your major flaw here is to return a redirect. That's a no no for json. What you are doing with that is giving the ajax call the html for the index action. That makes no sense. If you want the action to return JSON, then all cases must return json, no html whatsoever. So, no setFlash, no redirect. What I normally do here is to return the JSON data with a status and a message (like in the code above). Then, in the ajax call, on success, you parse the JSON data, read the status, if ok you redirect (via js), and if not, show the error message you got.
Hope it clear things for you.
[tiny edit]: json_encode will also work, but when in CakePHP, do what CakePHP(ians?) do (serialize) (because you don't need to echo the variables).

There's an example at JQuery.com
Example: Post to the test.php page and get content which has been returned in json format
<?php echo json_encode(array("name"=>"John","time"=>"2pm")); ?>
.
$.post( location.pathname + "/edit", data, function( data ) {
console.log( data.name ); // John
console.log( data.time ); // 2pm
}, "json");
So plugging in your ajax call is something like:
$.post( "test.php", data, function(response) {
$("#content").html(response);
alert(response);
}, "json");
Edit: If you're not getting the correct response, please show the php code that echos or returns the json..it's not anywhere in that function you provided.

Related

Sending json to symfony controller

I need to pass json data to my Symfony Controller. My ajax function looks like this:
var data = '{"firstname":"John"}';
$.ajax({
type: "POST",
url: save_url, //path to controller action
data: {json:data},
success: function(response) {
// Do something
}
});
In my controller, I try to get my data through:
public function createAction(Request $request) {
$data = $this->getRequest()->get('firstname');
return $this->render('MyBundle:Counter:test.html.twig', array(
'data' => $data
));
Just to see if this works, I send $data to be echoed in a template. In Firebug I can see the data being sent and everything seems to work, but $data is empty and nothing is echoed. Where am I doing this wrong?
EDIT: When I check the response in Fireburg console, I see my data there, in place, but it never appears in the template. var_dump($data) tells that $data is null. So, it seems data is being sent but the controller ignores it.
As Marek noticed:
$this->getRequest()
already returns the request object, you're accessing the request property of the request, that doesn't add up. Either try:
$data = $this->request->get('json');
Or use:
$data = $this->getRequest()->get('json');
You can, of course assign the return value of $this->getRequest() to a variable, and call the get method on that var from there on end... anyway, here's my initial answer, it does contain some more tips, and considerations you may find useful:
You should be able to get the data this way, though AJAX requests + echoing in a template? That does sound a bit strange. I don't see you passing the $data variable to a $this->render call anywhere.
This is a copy-paste bit from a controller action in one of my projects. It works just fine there:
public function indexAction()
{
if (!$this->getRequest()->isXmlHttpRequest())
{//check if request is AJAX request, if not redirect
return $this->redirect(
$this->generateUrl('foo_bar_homepage')//changed this, of course
);
}
$id = $this->getRequest()->get('id',false);//works fine
However, I can't begin to grasp why you're doing this:
var data = '{"firstname":"John"}';
Why not simply go for:
$.ajax({
type: "POST",
url: url,//post how you get this URL please...
data: {firstname: 'John'},//jQ will sort this out for you
success: function(response)
{
console.log(response);
}
error: function()
{
console.log('an error occured');
console.log(arguments);//get debugging!
}
});
Then, in your controller you're able to:
$this->getRequest()->get('firstname');//it should be John
You could even pass {json:{firstname: 'john'}} as the data param to $.ajax, the only difference in your controller will be, that you have to do this:
$data = $this->getRequest()->get('json');
$firstName = $data['firstname'];
That should work just fine, unless there's somthing you're not telling us :)
RECAP:
This is what I'd write:
public function createAction()
{//no Request param in controller
if (!$this->getRequest()->isXmlHttpRequest())
{//no ajax request, no play...
$this->redirect(
$this->generateUrl('homepage_route')
);
}
$data = $this->getRequest()->get('firstname');
//return json response:
return new Response(json_encode(array('dataReceived' => $data));
//return rendered HTML page:
return $this->render('MyBundle:Counter:test.html.twig', array(
'data' => $data
));
}
Of course, then the JS code should read:
$.ajax({
type: "POST",
url: 'route/to/create'
data: {firstname:'John'},
success: function(response)
{
console.log(response);
}
});
I have tested this, and I see no reason why this shouldn't work. It works just fine for me...
Please note this was #EliasVanOotegem original example but there are some obvious steps missing
in the controller i'm reading a few replies as in "I cannot see how this works as i'm getting null" this is because your not correctly keying your object.
i.e.
var data = { name : 'john' };
$.ajax({
type: "POST",
url: url,//post how you get this URL please...
data: {json : data},//jQ will sort this out for you
success: function(response)
{
console.log(response);
}
error: function()
{
console.log('an error occured');
console.log(arguments);//get debugging!
}
});
as you can now see accessing the requerst object like
$request->get('json');
refers to the post key for the json data
Is the content what you're trying to retrieve, neither params nor headers.
Try:
$request->getContent();
In your case $request->request->get('json') should do.

jQuery AJAX response object logs keys on console as undefined

Accepted answer by Rohan Kumar:
Changed $.post() into
$.post("monitor/loadEVents", function(data){
if(data && data.response){ // (didn't even have to change this for it to work, but I like this condition more than my own one)
console.log('Wow, it works.');
} else {
console.log(data);
}
},'json'); // put the third parameter as json
Original question below:
I'm trying jQuery AJAX for the first time in Zend Framework 2 (I've never worked with AJAX before at all). That being said, I don't have very extensive experience in working with JSON yet either, so please forgive me for rookie mistakes ;)
In my js file I'm calling a function in my controller to return a JSON object. My problem is that when I log 'data' to the console, it logs the structure of it just fine, but when I try to do something with the keys of 'data', their values come back as undefined.
This is where I call the function:
$('#loadmore').on('click', function(event){
$.post("monitor/loadEVents", function(data){
if(data.response == true){
console.log('Wow, it works.'); // Want this condition met, but it never is.
} else {
console.log(data); // so it logs data
}
})
});
Here's the function inside my controller:
public function loadEventsAction(){
$request = $this->getRequest();
$response = $this->getResponse();
if($request->isPost()){
$events = array('a bunch' => 'of stuff');
$response->setContent(\Zend\Json\Json::encode(array('response' => true, 'events' => $events)));
}
return $response;
}
This is how it logs data:
{"response":true,"events":{"a bunch":"of stuff"}}
What do I do so I can get to the response and events keys in 'data' properly?
Try this,
$.post("monitor/loadEVents", function(data){
if(data && data.response){
console.log('Wow, it works.'); // Want this condition met, but it never is.
} else {
console.log(data); // so it logs data
}
},'json');// put the third parameter as json
Read post()

Sending data with AJAX to a PHP file and using that data to run a PHP script

I'm currently trying to make live form validation with PHP and AJAX. So basically - I need to send the value of a field through AJAX to a PHP script(I can do that) and then I need to run a function inside that PHP file with the data I sent. How can I do that?
JQuery:
$.ajax({
type: 'POST',
url: 'validate.php',
data: 'user=' + t.value, //(t.value = this.value),
cache: false,
success: function(data) {
someId.html(data);
}
});
Validate.php:
// Now I need to use the "user" value I sent in this function, how can I do this?
function check_user($user) {
//process the data
}
If I don't use functions and just raw php in validate.php the data gets sent and the code inside it executed and everything works as I like, but if I add every feature I want things get very messy so I prefer using separate functions.
I removed a lot of code that was not relevant to make it short.
1) This doesn't look nice
data: 'user=' + t.value, //(t.value = this.value),
This is nice
data: {user: t.value},
2) Use $_POST
function check_user($user) {
//process the data
}
check_user($_POST['user'])
You just have to call the function inside your file.
if(isset($_REQUEST['user'])){
check_user($_REQUEST['user']);
}
In your validate.php you will receive classic POST request. You can easily call the function depending on which variable you are testing, like this:
<?php
if (isset($_POST['user'])) {
$result = check_user($_POST['user']);
}
elseif (isset($_POST['email'])) {
$result = check_email($_POST['email']);
}
elseif (...) {
// ...
}
// returning validation result as JSON
echo json_encode(array("result" => $result));
exit();
function check_user($user) {
//process the data
return true; // or flase
}
function check_email($email) {
//process the data
return true; // or false
}
// ...
?>
The data is send in the $_POST global variable. You can access it when calling the check_user function:
check_user($_POST['user']);
If you do this however remember to check the field value, whether no mallicious content has been sent inside it.
Here's how I do it
Jquery Request
$.ajax({
type: 'POST',
url: "ajax/transferstation-lookup.php",
data: {
'supplier': $("select#usedsupplier").val(),
'csl': $("#csl").val()
},
success: function(data){
if (data["queryresult"]==true) {
//add returned html to page
$("#destinationtd").html(data["returnedhtml"]);
} else {
jAlert('No waste destinations found for this supplier please select a different supplier', 'NO WASTE DESTINATIONS FOR SUPPLIER', function(result){ return false; });
}
},
dataType: 'json'
});
PHP Page
Just takes the 2 input
$supplier = mysqli_real_escape_string($db->mysqli,$_POST["supplier"]);
$clientservicelevel = mysqli_real_escape_string($db->mysqli,$_POST["csl"]);
Runs them through a query. Now in my case I just return raw html stored inside a json array with a check flag saying query has been successful or failed like this
$messages = array("queryresult"=>true,"returnedhtml"=>$html);
echo json_encode($messages); //encode and send message back to javascript
If you look back at my initial javascript you'll see I have conditionals on queryresult and then just spit out the raw html back into a div you can do whatever you need with it though.

CodeIgniter + jQuery Ajax runs successfully but error callback is called

I have a pretty simple CodeIgniter project that does some simple database work. Currently I have a controller method that deletes an item in the database. In my view, the code uses the jQuery ajax object to reference that controller, then displays either success or failure through its callbacks.
The problem is, although the controller works fine (deletes the item in the DB as expected), the ajax "error" callback is being called, instead of "success".
I'm sure I'm missing something super basic here...
Here is my controller method:
public function delete_note()
{
$this->load->helper('url');
$this->load->model('auth/user', 'User');
$this->load->database();
$note_id = $this->input->post('id');
$this->db->delete('admin_notes', array('id' => $note_id));
$this->db->query();
$this->output->set_status_header('200'); // Attempting to force the issue
}
And here is the code within the view:
$('.delete_note').each(function(){
var current = this;
this.onclick = function(event)
{
var note_id = this.title;
$.ajax({
type: "POST",
url: "/admin/delete_note",
data: { id: note_id },
success: function(data) { alert('I never see this!');},
error: function () { alert('I *always* see this!');}
});
}
});
Any answer attempts are appreciated. Any correct answers are doubly appreciated ;)
Thanks!
Just because the database logic is working, you may be receiving issues related to something else (cross-browser perhaps?). To see the error, change your error function to be like this:
error: function (jqXHR, textStatus, errorThrown) {
alert(textStatus);
alert(errorThrown);
}
I'd like to thank WojtekT for reminding me to check my responses in Firebug. I was actually receiving back a 500 status code for PHP errors. My extraneous $this->db->query(); call needed to be removed.
Everything works great now.
Thanks!

Some ajax help?

I have a php script that takes some user form input and packs some files into a zip based on that input. The problem is that sometimes the server errors, so all the form data is lost. I was told I could use ajax instead so that the user never even has to change the page. I've never used ajax, and looking at http://api.jquery.com/jQuery.ajax/ without any experience in ajax is quite difficult.
The page says that you can accept returns from an ajax call. How do you set up returns in the PHP file for an ajax call? If the server errors with the ajax call, how will I know?
edit: Also, is there a way to send an ajax request with javascript and jquery as if it were a submitted form?
How do you set up returns in the PHP file
just echo it in ajax page that will return as response
Simple Tutorial
client.php
$.post('server.php',({parm:"1"}) function(data) {
$('.result').html(data);
});
server.php
<?php
echo $_POST['parm'];
?>
result will be 1
edit on OP comments
Is there a way to use ajax as if you were submitting a form
Yes, there is
You can use plugins like jQuery form
Using submit
If you using jquery validation plugin, you can use submit handler option
using sumit
$('#form').submit(function() {
//your ajax call
return false;
});
every ajax function has a function param to deal with server returns.and most of them has the param msg,that is the message from server.
server pages for example php pages you can just use echo something to return the infomation to the ajax funciton . below is an example
$.ajax({
url:yoururl,
type:post,
data:yourdata,
success:function(msg){
//here is the function dealing with infomation form server.
}
});
The easiest way to get information from PHP to JavaScript via AJAX is to encode any PHP data as JSON using json_encode().
Here's a brief example, assuming your server errors are catchable
<?php
try {
// process $_POST data
// zip files, etc
echo json_encode(array('status' => true));
} catch (Exception $e) {
$data = array(
'status' => false,
'message' => $e->getMessage()
);
echo json_encode($data);
}
Then, your jQuery code might look something like this
$('form').submit(function() {
var data = $(this).serialize();
$.ajax(this.action, {
data: data,
type: 'POST',
dataType: 'json',
success: function(data, textStatus, jqXHR) {
if (!data.status) {
alert(data.message);
return;
}
// otherwise, everything worked ok
},
error: error(jqXHR, textStatus, errorThrown) {
// handle HTTP errors here
}
});
return false;
});

Categories