I have a datatables with some inputs in certain columns that are editable. I want to save the edited values in db.
This is my datatables:
The serialized datatables from values looks like this (if you print_r($_POST) for debugging):
javascript - I post the datatables form via ajax request to my laravel api controller method like this:
// Serialize the datatable table into post string
var poDetailUpdates = create_po_details_table.$('input').serialize();
// Call po api to save changes
$.ajax({
type: "POST",
data: poDetailUpdates,
url: '/api/po/update-create-lines/',
complete: function(response) {
if (response.status === 200) {
alert(response.responseText); // success
} else {
alert(response.responseText); // error
}
}
});
php - this is how I handle my form post in laravel:
public function postUpdateCreateLines() {
DB::beginTransaction();
try {
foreach ($_POST as $column_name => $values) {
foreach ($values as $line_id => $new_value) {
DB::table('purchase_order_details')
->where('id', '=', $line_id)
->update(array($column_name => $new_value));
}
}
DB::commit();
Response::make('Purchase order details updated', 200);
} catch (Exception $ex) {
DB::rollback();
Response::make('Purchase order details not updated - '. $ex->getMessage(), 500);
}
}
When the code runs, I get an empty alert() in javascript once the ajax request completes.
I thought the issue might be with the DB transaction related code, so I tried commenting out the following:
// DB::beginTransaction();
// DB::commit();
// DB::rollback();
But this also yields the same result (empty alert). Any idea what might be wrong? how to debug this? Something must be going wrong somewhere...
Your postUpdateCreateLines() method is not actually returning anything; you are making a response, but you need to return it:
return Response::make('Purchase order details updated', 200);
However, there are some other improvements you could make. It is best to return a JSON response to your $.ajax call, and then rely on jQuery's ajax .done and .fail handlers to deal with the response appropriately (rather than using complete):
return Response::json(
['status' => 'success',
'msg' => 'Purchase order details updated']
, 200)
...and add the response dataType to your ajax call:
dataType: "json"
Related
Guys m working on my first live project and i am stuck at a point, where i need help with ajax jquery. i can do this with PHP but i wanna do this with ajax.
Here if user enter a product code ,so i want to compare this product code value into my database and show product name in my other form ,which will open after user input value:
Here in first field i want product name:
Here in my table you can see product code and product name:
ok so here is my html code in last option when user enter product code
Here is jquery i am sending user data to 8transectiondata.php to compare
And this is php file and i want $data['product_name']; to show
Here's a generic answer.
JS FILE:
$(document).ready(function () {
$('#myButtonId').on('click', function () {
var code = $('#myCodeInputId').val();
if (code !== '') { // checking if input is not empty
$.ajax({
url: './my/php/file.php', // php file that communicate with your DB
method: 'GET', // it could be 'POST' too
data: {code: code},
// code that will be used to find your product name
// you can call it in your php file by "$_GET['code']" if you specified GET method
dataType: 'json' // it could be 'text' too in this case
})
.done(function (response) { // on success
$('#myProductNameInput').val(response.product_name);
})
.fail(function (response) { // on error
// Handle error
});
}
});
});
PHP FILE:
// I assumed you use pdo method to communicate with your DB
try {
$dbh = new PDO('mysql:dbname=myDbName;host=myHost;charset=utf8', 'myLogin', 'myPassword');
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
exit('ERROR: ' . $e->getMessage());
}
$sql = "SELECT `product_name` FROM `products` WHERE `product_code` = :code";
$result = $dbh->prepare($sql);
$result->bindValue('code', $_GET['code'], PDO::PARAM_INT);
$result->execute();
if($result->rowCount()) { // if you got a row from your DB
$row = $result->fetchObject();
echo json_encode($row, JSON_UNESCAPED_UNICODE); // as we use json method in ajax you've got to output your data this way
// if we use text method in ajax, we simply echo $row
}
else {
// handle no result case
}
I know what you want to do, but without specific code the best I can do is give you a generalized answer.
When a user fills out a field, you want to post that field to the server, look up a product and return some stuff.
The basics are going to look like this.
$(document).ready( function(){
//rolling timeout
var timeout;
$('#field').on('keyup', function(e){
if(timeout) clearTimeout(timeout);
timeout = setTimeout( function(){
var data = {
"field" : $('#field').val()
};
$.post( '{url}', data, function(response){
if(response.debug) console.log(response.debug);
if(response.success){
//open other form
$('{otherFormProductField}').val(response.product);
}
}); //end post
},450); //end timeout
});//end onKeyup
}); //end onReady
Then in PHP, you have to process the request. Pull the field from the $_POST array, look it up in the Database. Then build a response array and send it back to the client as JSON. I like to build responses in a structure something like this.
{
success : "message", //or error : "message"
debug : "",
item : ""
}
Then in PHP I will do this.
ob_start();
..code..
$response['debug'] = ob_get_clean();
header("Content-type:application/json");
echo json_encode($response);
This way, you can still print out debug info (in side the output buffer calls ) when developing it and don't have to worry about it messing up the Json or the header call.
-note- Use a timeout, that you reset on each key press (a rolling timeout). What it does is reset the previous timeout each time the key is released. That way it only sends the request once the user quits typing (instead of sending request on every keypress). I have found 450 milliseconds to be about the perfect value for this. Not too long not too short. Basically once they stop typing for 450ms it will trigger the $.post
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.
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()
I'm having trouble figuring out how to display some return JSON objects.
My script works like this:
I'm making an ajax call, sending some params to a CodeIgniter Controller where I'm processing it with a model, making some queries towards an database and then returning the json_encoded rows to the ajax callback function. This works great btw.
Here is what I want to do now and here its where I'm stuck. I want the new JSON objects (contains database rows) to "replace" the old rows in a html table. So I want it to update the table depending on the params I'm passing but only in the tbody mind.
I'm new at jquery so I've tried i few things. I've tried iterate trough the json data and use the $.html(string) function but i guess this replace everything and it will eventually just display the last object(Am i right?).
So I wonder how in a general sense I would do this?
$.ajax({
type: 'GET',
url: 'someSite.com/someEndpoint'
data: xyz.
success: function( response ) {
//lets say you have an object like this: object = { data: { ... } }
var html = '';
for(var i = 0; i<response.data.length; i++) {
html += '<tr><td>'+response.data[i].title+'</td></tr>';
}
$('#someTable tbody').html(html);
}
});
You don't have to return JSON objects in an AJAX request. Try setting the data_type config setting for the $.ajax call to "html" (or leave it blank--jQuery is really good about figuring it out from the response data).
I usually factor out the <tbody>...</tbody> portion of a view to its own view partial. Then, the "original" page load can use it, and so can an updating AJAX call.
The only asterisk to this is if you need some sort of object-oriented response along with the HTML. I would usually do something like this:
{
"stat": "ok",
"payload": "<tr><td>row1</td></tr><tr><td>row2</td></tr>"
}
And then in the ajax success function:
$.post('/controller/action', { some: 'data' }, function(response) {
$('#my_table tbody').append(response.payload);
}, 'json');
What are the params your passing in?
for example you might use a select or input field to trigger an ajax call and pass its value as the param.
var tableObj = {
var init : function(){
//check that your selectors id exists, then call it
this.foo();
},
foo : function(){
var requestAjax = function(param){
var data = {param : param}
$.ajax({
data : data,
success : function(callback){
console.log(callback);//debug it
$("tbody").empty();//remove existing data
for(var i =0; i < callback.data.length; i++){}//run a loop on the data an build tbody contents
$("tbody").append(someElements);//append new data
}
});
}
//trigger event for bar
$("#bar").keyup(function(){
requestAjax($(this).val());
});
}
}
$(function(){
tableObj.init();
})
Your php method
public function my_method(){
if($this->input->is_ajax_request())
{
//change the output, no view
$json = array(
'status' => 'ok',
'data' => $object
);
$this->output
->set_content_type('application/json')
->set_output(json_encode($json));
}
else
{
show_404();
}
}
I have read a few posts on fail parameters for a JQuery Ajax call, but none that have directly answered my question. If you want to read up on my jumping off point here, this post would be a good start:
jquery: is there a fail handler for $.post in Jquery?
My problem is that there are a handful of things that may cause my application to fail - if my script returns false the above method would work just fine for me (if I understand it correctly), but most of the time my script will fail by kicking out an exception that I handle using the Zend Framework. I would prefer to return the exception so that I can provide the user with a more detailed message. Is it possible to have my PHP script return a value while still letting the Ajax call know that it was a failure?
Sure you can. First of all you need to categorize you errors, for example:
Fatals
Exceptions
false / error status
I would advise you to take as a return value for correct and with no errors processing - 0. In all other case that would be an error.
Another useful advise would be to use JSON as a client-server conversation.
In PHP it would be:
function prepareJSONResponse($code, $message, array $extra = array())
{
return json_encode(array_merge(
$extra, array(
'code' => (int) $code,
'message' => $message)));
}
In this case you could pass error code and message, and additional params in $extra, for example, for this call:
prepareJSONResponse(1, 'Not enough data passed', array('debug' => true));
Response from server side would be:
{code:1,message:'Not enough data passed','debug': true}
For the client side you need a wrapper function for $.ajax:
// calback(result, error);
function call(url, params, callback)
{
if (typeof params == 'undefined') {
params = {};
}
$.ajax({
'type' : "POST",
'url' : url,
'async' : true,
'data' : params,
'complete' : function(xhr) {
if (xhr.status != 200) {
if (typeof callback == 'function') {
callback(xhr.responseText, true);
}
} else {
if (typeof callback == 'function') {
callback(xhr.responseText, false);
}
}
}
});
}
and function to validate JSON, in order if the corrupted format comes.
function toJSON(data){
try {
data = JSON.parse(data);
} catch (err) {
data = { 'code' : -999, 'message' : 'Error while processing response' };
}
if (typeof data.debug != 'undefined') {
console.log(data.debug);
}
return data;
}
Wrap in try-catch you code, and in catch statement do something like:
try {
...
} catch (Exception $e) {
exit(prepareJSONResponse(1, $e->getMessage(), array(
'debug' => 'There was an error while I were processing your request')));
}
The result would be that you receive debug information in browser console, and could handle errors / exception (prepareJSONResponse()) and fatals (by reading HTTP-status header, if it's not 200, then there was error).
Hope thats what you asked about.