The JS doesn't work with the PHP script. I get no response.
Here's the PHP script:
<?php
$a = array('data' => 'Hello');
echo json_encode($a);
?>
Here is the JQuery Script:
function getCityAndState(data, location)
{
var jsonString = {"zipCode": data};
var outR = outputResults
alert("JSON String:" + jsonString.zipCode);
if (location === "living")
{
$("#livingCityField").val("");
$("#livingStateField").val("");
alert("Inside getCityAndState: " + location);
//$.get("testfile.php",
// {zipCode: data},
// outR,
// 'text'
// );
$.getJSON("testfile.php",function(d) {
alert("JSON Data: " + d.data);
});
}
What am I doing wrong?
alert("Inside getCityAndState: " + location); does execute as expected but otherwise nothing happens. There is no exception thrown, no error message, nothing. It doesn't return any data at all.
I'm using Aptana 2 as an IDE, in case that makes a difference.
Your PHP script is missing the Header, it should be something like:
<?php
header('Content-type: text/json'); //added line
$a = array('data' => 'Hello');
echo json_encode($a);
?>
The second parameter of jQuery's $.getJSON() function isn't the callback that returns the data, it is supposed to be a map or string containing additional data to be sent to the server. The callback function is the third parameter.
I didn't test this, but it should be something along these lines:
$.getJSON('ajax/test.json', "", function(data, textStatus, jqXHR){
//In here you should have access to the data return by the server thourgh the "data" variable.
});
EDIT: As very well pointed out by #Rocket and #Tadeck, optional arguments can be omitted and "rearranged" since jQuery checks the argument's type. This is the case with the second and third arguments of the getJSON() function.
Given that, and although this shouldn't be the source of the problem, it makes sure the function receives all the arguments in the expected order, and it should yield the same result as omitting the second parameter.
Documentation: http://api.jquery.com/jQuery.getJSON/
Related
I would like to use an autocompletion in my application. I'm trying to use the jquery UI completion but nothing happens. I made an ajax to get all columns with a specific variable written by the user. The query is working, I have my array with all my columns back from the server. With this query reponse, I tried to do the jquery autocompletion in the success ajax but as I said nothing is happening.
Do you have an idea?
function autoCompleteRegate(){
$("#code_regate").keyup(function() {
// AJAX de l'auto-complete
var source = '/gestion/gestDepot/ajaxautocompleteregate';
var codeRegate = $("#code_regate").val();
$.ajax({
type : "POST",
url : source,
async : false,
dataType : 'json',
data : {
'codeRegate' : codeRegate
},
success : function(response) {
var availableTags = response;
$("#code_regate").autocomplete({
source: availableTags
});
}
});
});
public function ajaxautocompleteregateAction()
{
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$params = $this->_getAllParams();
$codeRegate = $params['codeRegate'];
$oDepotService = new Services_Depot();
$response = $oDepotService->searchCodeRegate($codeRegate);
echo json_encode($response);
}
Network query - form
Exemple of nothing happening
The answer from the server
You have to directly pass the cd_regate array instead of a multidimensional array. One workaround is you could process the json output on the backend side :
public function ajaxautocompleteregateAction()
{
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$params = $this->_getAllParams();
$codeRegate = $params['codeRegate'];
$oDepotService = new Services_Depot();
$response = $oDepotService->searchCodeRegate($codeRegate);
$json = [];
foreach ($response as $key => $value) {
array_push($json, $value->cd_regate); // the output will be "[774970, 774690, 774700,... ]"
}
echo json_encode($json);
}
I would suggest the following for your JavaScript:
$("#code_regate").autocomplete({
source: function(request, response){
$.ajax({
type : "POST",
url : '/gestion/gestDepot/ajaxautocompleteregate',
async : false,
dataType : 'json',
data : {
'codeRegate' : request.term
},
success : function(data) {
response(data);
}
});
}
});
This uses a function as a Source. From the API:
Function: The third variation, a callback, provides the most flexibility and can be used to connect any data source to Autocomplete, including JSONP. The callback gets two arguments:
A request object, with a single term property, which refers to the value currently in the text input. For example, if the user enters "new yo" in a city field, the Autocomplete term will equal "new yo".
A response callback, which expects a single argument: the data to suggest to the user. This data should be filtered based on the provided term, and can be in any of the formats described above for simple local data. It's important when providing a custom source callback to handle errors during the request. You must always call the response callback even if you encounter an error. This ensures that the widget always has the correct state.
When filtering data locally, you can make use of the built-in $.ui.autocomplete.escapeRegex function. It'll take a single string argument and escape all regex characters, making the result safe to pass to new RegExp().
When 1 or more letters are entered into the text field, this will be passed to the function under request.term and you can POST that to your script via AJAX. When you get the result data, it must be in an Array or an Object with the right format.
I have an Ajax request that runs fine for the most part, it expects a json return and processes it accordingly. However if my PHP server throws an Notice (or warning or error for that matter), it triggers the ajax fail function automatically, EVEN if the response contains the Json array as part of it (usually after the PHP notice)
For development purposes, I don't want to turn of these PHP notices, I was wondering if the ajax could still handle the PHP notice and actually realize that the json return array was also included as part of the return, and somehow trigger the "done" function instead.
Not that it really matters but here a cut down version of the my ajax code, where having a PHP Notice being output by the server automatically triggers the "fail" callback, instead of "done" callback.
function getTimeSlots() {
$("#reservationtimebuttonsplaceholder").hide();
$.post( "<?php echo Router::url(array('controller'=>'Bookings','action'=>'getMerchantAvailableTimeSlots_ajax')); ?>", $( ".reservationform" ).serialize(), function() {
$(".reservationtimebuttons").empty();
}, "json")
.done(function(data) {
var respstatus = data.status;
var message = data.message;
var failtype = data.failtype;
var timeslots = data.timeslots;
if (respstatus === false) {
$(".reservationtimebuttons").html(message)
}
if (respstatus === true) {
$.each(timeslots, function (dataKey, dataVal) {
$.each(dataVal, function(timeKey,timeVal){
$.each(timeVal,function(timePropKey, timePropVal){
btn_id_postfix = timePropKey.replace(/\:/g,"");
$output = "<button id=\"btn" + btn_id_postfix + "\" class=\"btn btn-grey btn-timeselection\" value=\"" + timePropKey + "\" type=\"button\">" + timePropVal + "</button>";
$(".reservationtimebuttons").append($output);
});
});
});
}
})
.fail(function() {
alert( "There was a problem getting the available timeslots! Please try again later" );
})
.always(function() {
});
}
you can use simple ajax call , and not specify "json" as part of it , then this will get anything that comes from the php into the response of your ajax call.
and then try to JSON.parse it , if this function cannot parse the reponse to JSON , this means reponse is not properly formated and that means you php code has maybe some error or warning ,
then you can check if the response has something like status , so it is what you want with no error , and if not , php has shoot some errors beside your response .
Here is the example delete options I'm using using in a jqGrid. It works just fine and my serverside scripts are working perfectly. The records get deleted, but there is something that goes wrong after the response from the server is received.
// Del Options
{
mtype: "POST",
modal: true,
url: "/internal/backupmanagement/backupmanager/deleteMySQLDB",
reloadAfterSubmit: false,
onclickSubmit: function () {
var post = $("#grid_" + o.id).jqGrid("getGridParam", "postData");
var server = post.serverID;
$.openDialog("load", "Deleting old database entry. Please wait...");
var selrow = $("#grid_" + o.id).jqGrid("getGridParam", "selrow");
var row = $("#grid_" + o.id).jqGrid("getRowData", selrow);
console.log("about to return", row, server);
return {
id: row.recid,
database: row.database,
server: server
};
},
afterSubmit: function (response, postdata) {
response = eval("(" + response.responseText + ")");
console.log(response);
return [true, "success"];
},
afterComplete: function (response, postdata, formid) {
response = eval("(" + response.responseText + ")");
var selrow = $("#grid_" + o.id).jqGrid("getGridParam", "selrow");
$("#grid_" + o.id).jqGrid("delRowData", selrow);
if (response.error == 0) {
$.openDialog("info", "Successfully deleted " + postdata.database + ".");
} else {
$.openDialog("info", "And error occured - " + response.msg + ".");
}
}
}
I get the following error before the afterComplete event is fired in the grid :
Uncaught TypeError: Object [object Array] has no method 'split'
So it seems something is being returned as an object when it was expecting a string. I'm not sure if my response from the server is formatted correctly and I wasn't able to find any expected response in the documentation either.
* UPDATE *
Server-side code as requested. I've just included the controller function that interacts with the jqGrid, the rest is working and happening further on in the application.
function deleteMySQLDB()
{
if (IS_AJAX) {
if (($this->Application->deleteMySQLDBData(
$_POST["id"],
$_POST["database"],
$_POST["server"]
)) === false) {
echo json_encode(
array(
"error" => 1,
"msg" => "Failed Deleting record from database: "
.$this->Application->error
)
);
return false;
}
echo json_encode(
array(
"error" => 0,
"msg" => "success"
)
);
return true;
} else {
header("Location: /");
}
}
I hope this helps to see what I'm currently returning to the grid.
* UPDATE *
What I have done is changed the source in the jqGrid plugin to include a toString() on the value before preforming the split.
On line 331 of jquery.jqGrid.min.4.3.1 :
var A=[];A=H.split(",");
Changed to :
var A=[];A=H.toString().split(",");
It seemed like a harmless change in the grand scheme of things and avoids arrays to be attempted to get split. Thanks a lot for the help guys. You certainly pointed me in the right place to start looking, Oleg!
Let's suppose that the origin of the described error is the code of your afterComplete callback. I think that you are using it in a wrong way. I don't understand some parts of the code, the part (testing of response.error) should be moved in afterSubmit.
The main problem will be clear if you examine the lines of code where afterComplete callback will be called. It will be executed inside of setTimeout with 0.5 sec delay. At the time new data in the grid can be loaded (or could be loading). So it would be wrong to use methods like delRowData and the value of selrow could be changed now.
I would strictly recommend you additionally don't use eval function. Instead of the line
response = eval("(" + response.responseText + ")");
it will be correct to use
response = $.parseJSON(response.responseText);
The code of onclickSubmit callback could be improved if you would use the fact that this inside of the callback (like the most other callbacks o jqGrid) are initialized to DOM element of the grid. So to get selrow option of the grid you can use
var selrow = $(this).jqGrid("getGridParam", "selrow");
instead of
var selrow = $("#grid_" + o.id).jqGrid("getGridParam", "selrow");
Another fact is onclickSubmit will be called by jqGrid with two parameters: options and postdata. The parameter postdata is rowid if you use don't use multiselect: true. In case of usage of multiselect: true the value of postdata parameter of the callback can be comma separated list of rowids of the rows which will be deleted. So the usage of postdata is better as the usage of selrow.
I"m making a good guess since you didn't include your server side code.
On the server you can return something like:
return Json(new { success = false, showMessage = true, message = "Error - You can't have a negative value", title = "Error" });
Then on your client you can have something to display a message (in this example if there was an error)
afterComplete: function (response) {
var DialogVars = $.parseJSON(response.responseText); //parse the string that was returned in responseText into an object
if (!DialogVars.success || DialogVars.showMessage) {
showDialog($('#Dialog'), DialogVars.message, DialogVars.title);
}
} //afterComplete
I am trying some things with JSON and PHP and there is something that I can't find a way to do, though I'm not 100% sure there is one. But because it looks like a nice option (If possible) I decided to ask here.
I have these examples from jquery offical site. There are two files, the first one is index.php where I execute my Ajax, hete it is:
<!DOCTYPE html>
<html>
<head>
<title>Simple form sending and receiving a JSON object to/from PHP</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var data =
{
"sales": [
{ "firstname" : "John", "lastname" : "Brown" },
{ "firstname" : "Marc", "lastname" : "Johnson" }
] // end of sales array
}
var dataString = JSON.stringify(data);
$.post('simpleformSubmi.php', { data: dataString}, showResult, "text");
});
function showResult(res)
{
$("#fullresponse").html("Full response: " +res);
}
</script>
<div id="fullresponse"></div>
</head>
<body>
Nothing complicated at all. And I have my simpleformSubmi.php which is :
<?php
$logFile = 'logFile';
$res = json_decode(stripslashes($_POST['data']), true);
error_log("result: ".$_POST['data'].", res=".json_encode($res), 3, $logFile);
error_log("\n", 3, $logFile);
//header("Content-type: text/plain");
foreach ($res as $key=>$value)
{
$str[] = $value;
}
$functionArray ="function(){ \$a = 10; echo \$a;}";
$jsStr = $str[0][1];
echo json_encode($jsStr['firstname']);
echo '<hr />';
echo json_encode($res);
echo '<hr />';
echo json_encode($functionArray);
?>
As you can see $functionArray - is in fact a string containing PHP function which I want to return back using JSON and to execute it after that. So is there any way to do that really? Now what I get in index.php afet executing the files is:
"function(){ $a = 10; echo $a;}"
Thanks
Lern
Seems like you're trying to execute a PHP function through JavaScript. Since PHP is executed server-side the only way you have to execute a PHP function in that context is to ask the server back to execute the function for you, by doing another ajax call for example.
Something like this:
index.php
$(document).ready(function(){
var data =
{
"sales": [
{ "firstname" : "John", "lastname" : "Brown" },
{ "firstname" : "Marc", "lastname" : "Johnson" }
] // end of sales array
}
var dataString = JSON.stringify(data);
//Change post() success callback function to executePHP()
$.post('simpleformSubmi.php', { data: dataString}, executePHP, "text");
//Let's define executePHP() outside post() call for clarity
function executePHP()
{
//Ask the server to execute function foo(), and get the result
$.get("example.com/somefile.php?function=foo", function(data)
{
//Success function, do whatever you want.
alert(data);
});
}
});
Then, in somefile.php
<?php
//Condition(s), if any. You could even implement this interface using REST.
//Get function to execute
if($_GET["function"] == "foo")
{
//Output function's result.
echo foo();
}
//The function you want to run
function foo()
{
//Do something
$a = 10;
return $a;
}
?>
If all went well, when JavaScript reaches the alert(data); statement you will see 10.
You cannot execute a PHP function after sending it as a response since the response is received on the client end, and PHP is a server side language.
Usually, you would just return the values. In your example, you would just return an associative array that holds the key value pair a,10.
You can return javascript functions from the PHP script and execute that on the client side using eval but eval'ing opens a pandora's box of security vulnerabilities.
You can't execute PHP code outside of a PHP server. So you can't run it in the browser.
You can, however, pass a string of JavaScript and run it through eval. Some people will tell you that's bad, but remember that eval used to be the only way to parse JSON in the first place.
In order to send back something to PHP, you must call the serverside via, p.e via GET or POST actions from a form. But, no, you cannot execute anything serverside via echo, as echo outputs to the client side. You could always use eval (http://php.net/manual/es/function.eval.php) at serverside to execute something from a POST message, but it is not recommended as it can open a great security hole.
You've returned a function (I'm assuming you meant this to be javascript), now you need to call it. This can be done by using the jQuery $.post success callback.
Try changing this..
$.post('simpleformSubmi.php', { data: dataString}, showResult, "text");
To
$.post('simpleformSubmi.php', { data: dataString}, function(data){eval(data)}, "text");
If its PHP (which it looks like) and not Javascript, then this will need to executed from the server. Being that its a server-side language 'n all.
I'm having a hard time figuring this one out. Seems like no matter what I try, PHP always ends up returning an empty array. Here's the code of my main file(index.php):
<script language="javascript" type="text/javascript">
$(document).ready(function(){
$(".ajaxlink").click(function() {
callServer();
return false; //Stop link from redirecting
});
});
var test = { "testName": "testValue" }
var testJSON = JSON.stringify(test);
function updatePage(data) {
document.getElementById("testDiv").innerHTML = data;
}
function callServer() {
$.ajax({
type: "POST",
url: "ajax/server.php",
data: testJSON,
success: function(data) {
updatePage(data);
},
//Upon error, output message containing a little info on what went wrong
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('An Ajax error occured\ntextStatus = ' + textStatus + '\nerrorThrown = ' + errorThrown + '\nstatus = ' + XMLHttpRequest.status);
}
});
}
</script>
<div id="testDiv">Something here</div>
Link! <br>
This basically runs the callServer() function when you click the "Link!". It then sends the test json data, that is { "testName": "testValue" } to server.php. Firebug reports that the json-data is indeed sent to the server.php.
My server.php looks like this:
<?php
print_r($_POST);
?>
This returns the following in the testDiv:
Array
(
)
The datatype in the .ajax function is not defined, so whatever output the server.php file spits out, it should be readable. All the necessary libraries(json, jquery) are included in my document as well. I'm running this on Apache 2.2 and PHP 5.3.1, but it shows the same on my webserver (which is a host for thousands of websites). The content-type used in the request-header is 'application/x-www-form-urlencoded; charset=UTF-8' so that should work correctly.
Thanks for your time.
Best regards
soren
I think you send the data in a wrong way. Either you send a string like testName=testValue or you assign the value in test directly to the data parameter of .ajax() and don't use the stringify method.
Because, if you use stringify, the actual sent data will be (I assume, I am not sure here):
'{ "testName": "testValue" }'
but this is not a valid parameter string.
It should be of form
'testName=testValue'
So use test directly, .ajax() will convert the object into an appropriate string:
function callServer() {
$.ajax({
type: "POST",
url: "ajax/server.php",
data: test,
success: function(data) {
updatePage(data);
},
//Upon error, output message containing a little info on what went wrong
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('An Ajax error occured\ntextStatus = ' + textStatus + '\nerrorThrown = ' + errorThrown + '\nstatus = ' + XMLHttpRequest.status);
}
});
}
I'm not sure your output from your PHP script is JSON formatted.
If you're using a newer version of PHP (which you are) you'll have access to the json_encode and json_decode functions. Instead of doing:
print_r($_POST);
Try:
print json_encode($_POST);
If your version of PHP doesn't have these functions you can use a library such as the Zend_Json class in the Zend Framework, in order to encode your PHP variables as JSON before outputting them.
And when it comes back, it'll be a JSON-formatted string. Setting the dataType in your jQuery.ajax call should evaluate it to a JS object. If not you would either have to call the Javascript eval function on it, or (preferably) use JSON.parse(data).
Use firefox and Live Http Headers extension.
With this you'll be able to see exactly where the problem lies,
Php or Js code.
live http headers