I have a lil problem with an AJAX request.
We have a lil PHP, JavaScript application (Website). The application is running fine on all desktop browsers + on our old MDE's (some Windows CE6 MDE). Now on our new Motorola MC9200 (Windows Embedded Compact 7 formerly CE7) it's not working anymore.
The problem is some small JavaScript function. It disables the buttons/input fields, starts a Ajax.Request (prototype 1.72 but I tested jQuery 1.11.1 too), does something on the database and when everything went right it is refreshing the site via window.location. This function isn't working always on the new devices. Sometimes it does, sometimes not.
simplified code:
function loadSite(siteName) {
disableForm();
var parameters = {
/* SOME PARAMETERS */
};
new Ajax.Request('ajax/ajax_db_execute.php', {
method: 'post',
parameters: parameters,
onSuccess: callbackFunc
});
}
function callbackFunc(transport) {
response = transport.responseText.evalJSON(true);
if(response.retcode === 0) {
window.location = "start.php?id=<?php echo $id; ?>";
} else {
show_error_box(response.errortext);
enableForm();
}
}
I tried to output the response in the callbackFunc but that function wasn't even called. Next thing I tried was to put some alert at the end of the loadSite function, it was fired everytime. I already checked the parameters and they look fine too.
After that I put some simple fwrite in the php file. It looks like that file isn't even called sometimes. So the question is why?
By changing the method to 'get' I couldn't reproduce the problem and everything is working fine. Problem about that is that I don't want to use get + some parameters might be too long for get to handle.
The parameters in that example were just some simple integers and strings. Does anyone have an idea what might cause the problem and some workaround?
It seems that your post request response is not synchronized. So please use setTimeout function in your post callback like that
setTimeout(function(transport) {
response = transport.responseText.evalJSON(true);
if(response.retcode === 0) {
window.location = "start.php?id=<?php echo $id; ?>";
}
else
{
show_error_box(response.errortext);
enableForm();
}
}, 3000);
Related
Is there a way I can run a php function through a JS function?
something like this:
<script type="text/javascript">
function test(){
document.getElementById("php_code").innerHTML="<?php
query("hello"); ?>";
}
</script>
<a href="#" style="display:block; color:#000033; font-family:Tahoma; font-size:12px;"
onclick="test(); return false;"> test </a>
<span id="php_code"> </span>
I basically want to run the php function query("hello"), when I click on the href called "Test" which would call the php function.
This is, in essence, what AJAX is for. Your page loads, and you add an event to an element. When the user causes the event to be triggered, say by clicking something, your Javascript uses the XMLHttpRequest object to send a request to a server.
After the server responds (presumably with output), another Javascript function/event gives you a place to work with that output, including simply sticking it into the page like any other piece of HTML.
You can do it "by hand" with plain Javascript , or you can use jQuery. Depending on the size of your project and particular situation, it may be more simple to just use plain Javascript .
Plain Javascript
In this very basic example, we send a request to myAjax.php when the user clicks a link. The server will generate some content, in this case "hello world!". We will put into the HTML element with the id output.
The javascript
// handles the click event for link 1, sends the query
function getOutput() {
getRequest(
'myAjax.php', // URL for the PHP file
drawOutput, // handle successful request
drawError // handle error
);
return false;
}
// handles drawing an error message
function drawError() {
var container = document.getElementById('output');
container.innerHTML = 'Bummer: there was an error!';
}
// handles the response, adds the html
function drawOutput(responseText) {
var container = document.getElementById('output');
container.innerHTML = responseText;
}
// helper function for cross-browser request object
function getRequest(url, success, error) {
var req = false;
try{
// most browsers
req = new XMLHttpRequest();
} catch (e){
// IE
try{
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
// try an older version
try{
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
return false;
}
}
}
if (!req) return false;
if (typeof success != 'function') success = function () {};
if (typeof error!= 'function') error = function () {};
req.onreadystatechange = function(){
if(req.readyState == 4) {
return req.status === 200 ?
success(req.responseText) : error(req.status);
}
}
req.open("GET", url, true);
req.send(null);
return req;
}
The HTML
test
<div id="output">waiting for action</div>
The PHP
// file myAjax.php
<?php
echo 'hello world!';
?>
Try it out: http://jsfiddle.net/GRMule/m8CTk/
With a javascript library (jQuery et al)
Arguably, that is a lot of Javascript code. You can shorten that up by tightening the blocks or using more terse logic operators, of course, but there's still a lot going on there. If you plan on doing a lot of this type of thing on your project, you might be better off with a javascript library.
Using the same HTML and PHP from above, this is your entire script (with jQuery included on the page). I've tightened up the code a little to be more consistent with jQuery's general style, but you get the idea:
// handles the click event, sends the query
function getOutput() {
$.ajax({
url:'myAjax.php',
complete: function (response) {
$('#output').html(response.responseText);
},
error: function () {
$('#output').html('Bummer: there was an error!');
}
});
return false;
}
Try it out: http://jsfiddle.net/GRMule/WQXXT/
Don't rush out for jQuery just yet: adding any library is still adding hundreds or thousands of lines of code to your project just as surely as if you had written them. Inside the jQuery library file, you'll find similar code to that in the first example, plus a whole lot more. That may be a good thing, it may not. Plan, and consider your project's current size and future possibility for expansion and the target environment or platform.
If this is all you need to do, write the plain javascript once and you're done.
Documentation
AJAX on MDN - https://developer.mozilla.org/en/ajax
XMLHttpRequest on MDN - https://developer.mozilla.org/en/XMLHttpRequest
XMLHttpRequest on MSDN - http://msdn.microsoft.com/en-us/library/ie/ms535874%28v=vs.85%29.aspx
jQuery - http://jquery.com/download/
jQuery.ajax - http://api.jquery.com/jQuery.ajax/
PHP is evaluated at the server; javascript is evaluated at the client/browser, thus you can't call a PHP function from javascript directly. But you can issue an HTTP request to the server that will activate a PHP function, with AJAX.
The only way to execute PHP from JS is AJAX.
You can send data to server (for eg, GET /ajax.php?do=someFunction)
then in ajax.php you write:
function someFunction() {
echo 'Answer';
}
if ($_GET['do'] === "someFunction") {
someFunction();
}
and then, catch the answer with JS (i'm using jQuery for making AJAX requests)
Probably you'll need some format of answer. See JSON or XML, but JSON is easy to use with JavaScript. In PHP you can use function json_encode($array); which gets array as argument.
I recently published a jQuery plugin which allows you to make PHP function calls in various ways: https://github.com/Xaxis/jquery.php
Simple example usage:
// Both .end() and .data() return data to variables
var strLenA = P.strlen('some string').end();
var strLenB = P.strlen('another string').end();
var totalStrLen = strLenA + strLenB;
console.log( totalStrLen ); // 25
// .data Returns data in an array
var data1 = P.crypt("Some Crypt String").data();
console.log( data1 ); // ["$1$Tk1b01rk$shTKSqDslatUSRV3WdlnI/"]
I have a way to make a Javascript call to a PHP function written on the page (client-side script). The PHP part 'to be executed' only occurs on the server-side on load or refreshing'. You avoid 'some' server-side resources. So, manipulating the DOM:
<?PHP
echo "You have executed the PHP function 'after loading o refreshing the page<br>";
echo "<i><br>The server programmatically, after accessing the command line resources on the server-side, copied the 'Old Content' from the 'text.txt' file and then changed 'Old Content' to 'New Content'. Finally sent the data to the browser.<br><br>But If you execute the PHP function n times your page always displays 'Old Content' n times, even though the file content is always 'New Content', which is demonstrated (proof 1) by running the 'cat texto.txt' command in your shell. Displaying this text on the client side proves (proof 2) that the browser executed the PHP function 'overflying' the PHP server-side instructions, and this is because the browser engine has restricted, unobtrusively, the execution of scripts on the client-side command line.<br><br>So, the server responds only by loading or refreshing the page, and after an Ajax call function or a PHP call via an HTML form. The rest happens on the client-side, presumably through some form of 'RAM-caching</i>'.<br><br>";
function myPhp(){
echo"The page says: Hello world!<br>";
echo "The page says that the Server '<b>said</b>': <br>1. ";
echo exec('echo $(cat texto.txt);echo "Hello world! (New content)" > texto.txt');echo "<br>";
echo "2. I have changed 'Old content' to '";
echo exec('echo $(cat texto.txt)');echo ".<br><br>";
echo "Proofs 1 and 2 say that if you want to make a new request to the server, you can do: 1. reload the page, 2. refresh the page, 3. make a call through an HTML form and PHP code, or 4. do a call through Ajax.<br><br>";
}
?>
<div id="mainx"></div>
<script>
function callPhp(){
var tagDiv1 = document.createElement("div");
tagDiv1.id = 'contentx';
tagDiv1.innerHTML = "<?php myPhp(); ?>";
document.getElementById("mainx").appendChild(tagDiv1);
}
</script>
<input type="button" value="CallPHP" onclick="callPhp()">
Note: The texto.txt file has the content 'Hello world! (Old content).
The 'fact' is that whenever I click the 'CallPhp' button I get the message 'Hello world!' printed on my page. Therefore, a server-side script is not always required to execute a PHP function via Javascript.
But the execution of the bash commands only happens while the page is loading or refreshing, never because of that kind of Javascript apparent-call raised before. Once the page is loaded, the execution of bash scripts requires a true-call (PHP, Ajax) to a server-side PHP resource.
So, If you don't want the user to know what commands are running on the server:
You 'should' use the execution of the commands indirectly through a PHP script on the server-side (PHP-form, or Ajax on the client-side).
Otherwise:
If the output of commands on the server-side is not delayed:
You 'can' use the execution of the commands directly from the page (less 'cognitive' resources—less PHP and more Bash—and less code, less time, usually easier, and more comfortable if you know the bash language).
Otherwise:
You 'must' use Ajax.
I have an ajax call to a php script which runs some things on the server. When this is completed I want to make php call out a javascript function. To do this I used this.
//This line works in chrome and firefox.
echo "<style onload='test()'></style>";
//this one doesnt work after an ajax call.
echo "<script type='text/javascript'>test()</script>";
This line works and triggers in chrome and firefox, but not in internet explorer.
So my question is, is there a solution or an alternative for this?
Is there a way to call a new javascript function after an ajax call depending on the result of the ajax call? (not just succes or failure)
Ill explain my system a bit more for extra information. I store a lot of my data in a session.
I got my code here and stripped it from extra or useless code for this example, during this spelling errors, parse errors or other syntax errors might have occurred this is not the problem though.
//Index.php
<head><script src='location' type='text/javascript'></script></head>
<body>
<div id='container'>
<div id='head'></div>
<div id='content'></div>
</div>
<div id='hidden'></div> // this div is hidden for js feedback
<script type='text/javascript'>loadContent();</script>
</body>
//javascript file
function loadContent(){
//my ajax function works it requires 3 variables
//url to php, div that will be changed, array with post variables.
Ajax("urltophp", "hidden", Array(""));
}
function loadHome(){
Ajax("urltophp2", "head", Array("headhome"));
Ajax("urltophp2", "cont", Array("conthome"));
}
function loadLogin(){
Ajax("urltophp2", "head", Array("headlogin"));
Ajax("urltophp2", "cont", Array("contlogin"));
}
function test(){
alert("test"); //for testing
}
//then urltophp
$ses = $_SESSION("ses"); //this is an object of class SESSION
$timeout = $ses->getTimeout();
$loggedin = $ses->getLoggedin();
//THIS WORKS IN CHROME AND FIREFOX NOT IN IE.
if(time() - $timeout < 3600){ //if an hour hasnt passed since last action.
if($loggedin){ //if user was logged in.
echo "<style onload='loadHome()'></style>";
}else{
echo "<style onload='loadLogin()'></style>";
}
}
//urltophp2
$p = $_POST['var1'];
$ses = $_SESSION["ses"];
//used for checking if user is logged in before loading page
//in case of cross-site scripting. left out in this example.
$loggedin = $ses->getloggedin();
switch($p){
case "headhome":
echo $homehead; //assume I loaded this from a file.
break;
case "conthome":
echo $conthead; //assume the same.
break;
etc. for all options.
}
Thanks in advance kpp.
Is there a way to call a new javascript function after an ajax call depending on the result of the ajax call?
Yes.
$.get("test.php", function(data) {
if (data.prop === "A") {
foo();
} else {
bar();
}
});
Note: Obviously I'm using jQuery here.
Edit: Maybe I made the question more complex than it should. My questions is this: How do you make API calls to a server from JS.
I have to create a very simple client that makes GET and POST calls to our server and parses the returned XML. I am writing this in JavaScript, problem is I don't know how to program in JS (started to look into this just this morning)!
As n initial test, I am trying to ping to the Twitter API, here's the function that gets called when user enters the URL http://api.twitter.com/1/users/lookup.xml and hits the submit button:
function doRequest() {
var req_url, req_type, body;
req_url = document.getElementById('server_url').value;
req_type = document.getElementById('request_type').value;
alert("Connecting to url: " + req_url + " with HTTP method: " + req_type);
req = new XMLHttpRequest();
req.open(req_type, req_url, false, "username", "passwd");// synchronous conn
req.onreadystatechange=function() {
if (req.readyState == 4) {
alert(req.status);
}
}
req.send(null);
}
When I run this on FF, I get a
Access to restricted URI denied" code: "1012
error on Firebug. Stuff I googled suggested that this was a FF-specific problem so I switched to Chrome. Over there, the second alert comes up, but displays 0 as HTTP status code, which I found weird.
Can anyone spot what the problem is? People say this stuff is easier to use with JQuery but learning that on top of JS syntax is a bit too much now.
For security reasons, you cannot use AJAX to request a file from a different domain.
Since your Javascript isn't running on http://api.twitter.com, it cannot request files from http://api.twitter.com.
Instead, you can write server-side code on your domain to send you the file.
Trying to get a very simple request working with MooTools Request.JSON. After having no success building it from scratch, I took an example from somewhere and slowly pared it down to the bare, bare minimum, then put it back into my own page. The only things changed are the url and element ID, but to no avail.
Any help, ideas, will be greatly appreciated.
json.php
<?php
$result['name'] = 'yay';
header('Content-type: application/json');
echo json_encode($result);
?>
demo.js (snippet inside window.addEvent('domready', function() { )
$(document.body).getElement('input[id=game_name]').addEvents({
'keydown' : function(){
alert('hmm'); //this fires
var jsonRequest = new Request.JSON({
url: "json.php",
onComplete: function(result){ //changing to onSuccess kills everything afterwards
alert('result.name'); //this fires
alert(result.name); //this does not fire
alert('result.name'); //this does not fire
}
}).get();
}
});
PS. in neither my page, or the pared down example pages, can i get the request to send on domready, only inside an event. why is that?
thanks again
As it turns out, the problem was that I had accidentally loaded a synced duplicate file into my browser that was therefore (obviously) unable to execute anything server side.
Thank you very much for your help.
Several suggestions/questions:
Are you getting any errors in your web browser's console? Which web browser are you using? The fact that the third alert doesn't fire at all suggests that alert(result.name); is throwing an error, in which case, all further execution will be stopped and an error will appear on your browser's console.
When you say "changing to onSuccess kills everything afterwards", what exactly do you mean? Does code further down (i.e. code that's not included in the above code snippet) never execute? Or does onSuccess just never fire?
Is json.php in the same directory as the page where this script is running? Try replacing json.php in url: "json.php" with an absolute URL (/mydirectory/json.php or http://www.mywebsite.com/mydirectory/json.php) and see whether this works.
If it's any help, the following code results in an alert reading "yay" (running on a local server; json.php is a file containing the PHP code in your question):
var jsonRequest = new Request.JSON({
url: "json.php",
onSuccess: function(result) {
alert(result.name);
}
}).get();
you can find a great tutorial here
http://net.tutsplus.com/tutorials/javascript-ajax/checking-username-availability-with-mootools-and-request-json/
Exactly the same problem here.
I solved it by decoding the JSON string, which is given as parameter (instead of the expected object).
onSuccess: function(jsonString) {
console.log(JSON.decode(jsonString));
}
Here ist the documentation:
http://mootools.net/docs/core/Utilities/JSON#JSON:decode
I have a page where I need to add a drag and drop functionality to certain elements. When the drop event occurs, it makes an ajax call to a php function and then refreshes the contents of a div. I'm using jQuery with jQueryUI for the drag and drop, and CakePHP as a PHP framework (not sure if this is relevant).
Everything is working just fine in Firefox, Safari and even IE, but in Opera or Chrome the contents of the div isn't refreshed (although the action from the PHP function is executed).
So, here is the code:
jQuery('#lists div').
filter(function() {return this.id.match(/item[\d]+_[\d]+/);}).
each(function() { jQuery(this).draggable( {axis: 'y'}); });
jQuery('#lists div').
filter(function() {
return this.id.match(/list[\d]+/);}).
each(function() {
jQuery(this).droppable({
drop: function(event, ui) {
dropID = jQuery(event.target).attr('id');
dragID = jQuery(ui.draggable).attr('id');
itemID = dragID.substr(dragID.lastIndexOf('_') + 1);
oldListID = dragID.substr(4).replace(/_[\d]+/g, '');
newListID = drop.substr(4);
jQuery.ajax({
url: "/lists/itemToList/"+itemID+"/"+oldListID+
"/"+newListID,
type: "POST",
success: function (data) {
jQuery('#lists').html(data);}
});
}
});
});
Basically, the success function isn't executed, but if I try to see the errorThrown (on the error event) it is "undefined"
Try something like this:
jQuery.ajax({
url: "/lists/itemToList/"+itemID+"/"+oldListID+
"/"+newListID,
type: "POST",
success: function (data) {
jQuery('#lists').html(data);
}
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.status);
alert(XMLHttpRequest.responseText);
}
});
It will show you what http response are you getting for your request. I had the same problem some time ago. My script worked great in Firefox and Chrome, but it didn't do anything in Opera and IE. I checked it and the problem was, that the php backend was returning 404 (I still don't know how did it work under Chrome and FF).
I know it's been a long time since I've posted the question, but here is what I found to be the solution, in case somebody else needs it: the problem was not the in javascript but with CakePHP: the html that was added on success contained an ajax form (rendered using $ajax->form()). $ajax->form() needed the $data variable from the controller to be an array, but for some reason it wasn't, and this broke the rendering of the form, and Opera and Chrome didn't like this. So the solution was to simply add
$this->data = array();
to the itemToList() function in my controller.
I don't see anything in the code that would cause a cross browser issue. My feeling is that it's a problem doesn't lie in the code at all, but in the rendering of the div and/or its contents in Chrome and Opera (i.e. a CSS problem or something along those lines where the innerHTML of the div is updated, but because of styling or positioning you don't get the visual result you were looking for).
Have you checked using Dragonfly or some other developer tool to verify that the contents of the target element are in fact unchanged after a successful request? Along those lines have you tried stepping through the code execution in the problem browsers? You could also try adding a error handler to the JQuery.ajax options to see if there is some problem with the request itself, although I don't believe that is where the problem lies.
EDIT: I didn't see that last bit below the code block. So you have verified that the success handler isn't being executed. You said that you did try and implement an error handler for the request and got some undefined result, but I don't see it in the code. Could you post the code for the error handler and describe what in the error is undefined?
I think he means, that alert(errorThrown) is showing 'undefined'.