Can't get Ajax works - php

I have a problem with Ajax. I'm totally noob with Ajax, and I apologize for such a stupid question.
I have a list of elements (loaded by a db) that I want to manage, i.e. Remove, Modify their name..; I want to use ajax to change db and the list.
But I want that the page is modified only AFTER the db has been modified. I can modify the page before the db is modified but it's not what I want.
That's my code:
function setXMLHttpRequest() {
var xhr = null;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
return xhr;
}
function modifyCat(n,newN){
xhrObj = setXMLHttpRequest();
var url = "modifyCat.php?action=modify&cat="+n+"&newCat="+newN;
xhrObj.open("GET", url, true);
links = document.getElementById("cat").getElementsByTagName("a");
updatePage(links);
xhrObj.send(null);
}
function updatePage(links) {
if (xhrObj.readyState == 4) {
var risp = xhrObj.responseText;
//code that works... if not put inside this if!
}
xhrObj.send(null);
}
ModifyCat.php is
//...
else if($action='modify'){
$n = cleanSimpleString($_GET['cat']);
$nN = cleanSimpleString($_GET['newCat']);
$qry = "UPDATE Categorie Set Nome='$nN' WHERE Nome='$n'";
$check = mysql_query($qry) or $db=0;
}
As I understand if (xhrObj.readyState == 4) should do want I'm asking. Instead with that If nothing happens (in the page, the php is correctly loaded). Without that If the page is correctly reloaded but while the db is working..
edit.
I would like to do that without framework, I think it's a simple thing that can be solved simply.
Thank you.

If you're "totally noob with Ajax" I'd recommend using an Ajax library, such as jQuery. Have a look at their Ajax page and you'll see that it's much more straightforward than working directly with XHR objects.
Also, you've got a typo - you've use hrObj in modifyCat.

You can either use the XMLHttpRequest to do a synchronous or asynchronous request. A synchronous request is easier to program, but will block your page until the result becomes available. An asynchronous request will execute a callback function when the result has become available. There are a number of events for which the callback will be executed, readyState = 4 means the result is available, see also:
http://en.wikipedia.org/wiki/XMLHttpRequest#The_onreadystatechange_event_listener
(and of course the rest of that article)
Having said that, take the suggestions elsewhere to heart, it is much easier (and more cross-browser compatible) to use jquery (or similar javascript/ajax library) to do this stuff.

It would save you a lot of headache if you just used jquery - it can be as easy as doing this:
$.get("modifyCat.php", { action: "modify", cat: n, newCat: newN },
function(data){
alert("Data Loaded: " + data);
});
http://api.jquery.com/jQuery.get/

Related

how to refresh the Div part of my page using javascript after ajax call

i am submitting a form using Ajax and storing the data in the database. It is storing the data in the database and without reloading the page it is giving alert box showing that that content has been added.
The same page is showing the content of the database, i need that part to refresh automatically without reloading the page so that it can also fetch the just added information.
<script type="text/javascript">
function GetXmlHttpObject()
{
if(window.XMLHttpRequest)
{
return new XMLHttpRequest();
}
if(window.ActiveXobject)
{
return new ActiveXObject("Microsoft.XMLHTTP");
}
return null;
}
function submitformwithajax()
{
var myAjaxPostrequest=new GetXmlHttpObject();
var coursename=document.getElementsByName('cvalue')[0].value;
var parameter="cvalue="+coursename;
myAjaxPostrequest.open("POST", "process/do_course.php", true);
myAjaxPostrequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
myAjaxPostrequest.send(parameter);
myAjaxPostrequest.onreadystatechange=function(){
if(myAjaxPostrequest.readyState==4){
if(myAjaxPostrequest.status==200){
if(myAjaxPostrequest.responseText=="true")
{
alert("Course Has Been Successfully Added To The Curiculum !");
var container = document.getElementById('c');
var refreshContent = container.innerHTML;
container.innerHTML = refreshContent;
}
}
else
document.getElementById("submitcourse").innerHTML="An error has occured making the request";
}
}
}
</script>
'c' is the ID of the div tag which has to be reloded.
Thanks
This seems a bit nonsense:
var refreshContent = container.innerHTML;
container.innerHTML = refreshContent;
That way you're not refreshing, the content is exactly the same.
I don't know exactly what do you mean by "DB content", assuming coursename is what you want to add to your DIV then you have to do something like:
container.innerHTML += '<p>'+ coursename +'</p>';
jQuery would benefit your work a lot, your current code via jQuery would look like
function submitformwithajax() {
var coursename = $("[name=cvalue]").val();
$.post("process/do_course.php", {cvalue: coursename}, function(response) {
if (response === "true")
{
alert("Course Has Been Successfully Added To The Curiculum !");
var container = $("#c");
// Not sure why you're setting the container to the container here
container.html(container.html());
}
else
$("#submitcourse").text("An error has occured making the request");
}, "text");
}
I don't know why you set the text of the container to the text in the container but that may be an issue you are having. If your server response returns the data that needs to be displayed in th area you can use jQuery (or if you really prefer, the DOM) to update the fields or elements (or add as needed) on the fly. If you need to refresh that section based off a GET request, then just make a GET request for the data in the success statement.
I would also recommend using JSON for the return type from the server instead of plain text. A {"success": true} will allow you to check if (response.success) instead of using string comparison there.
Also, as a final side note, in Javascript you should always prefer === over == as === verifies that value and type both match, the downside to this is that in Javascript 1 == "1" but 1 === "1" is not true.
EDIT
In response to your comment, should you not persue the jQuery route, you can still implement all of that which I have explained here however you'll have to manually parse the response:
var resposne = JSON.parse(myAjaxPostRequest.responseText);
From there you can still check if (response.success).
I, personally, recommend showing the students how to do it this long and complex way, and then teaching them how to do it with jQuery. Should any of them pursue a web development career then they will either use jQuery or something very similar in function to it and it's best they learn about these things early on instead of after they get hired. I also suggest JSON returns from the server because it's a more expressive way to return data, instead of just "true" (what is true?) you say {"success": true} so you can see the request was successful.
The easiest way to do this is going to be return the contents of the "c" element from the ajax call, and then replace the old contents of "c" with the content returned by the ajax call.
After seeing your code: You are not filling that table with AJAX. I can only give you this advice. Fill that table dynamically with Javascript.
Create function which will find div#c.
If div#c has some children, destroy them.
Create a new element table.
Fill that table with new rows.
This is how you can make a table dynamically with data from the server which is provided by Ajax. So after sending data from the form you can call this function and your table will be recreated.

is it possible to evaluate JavaScript code using XMLHttpRequest

I'm trying to use this AJAX request to call a file with some PHP which is working ok and some JavaScript which is not. any ideas?
function showpart2(){
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","atuamae.org/parte2-encomendar.php",false);
xmlhttp.send(null);
}
document.getElementById('part2').innerHTML = xmlhttp.responseText;
eval(xmlhttp.responseText.getElementById('part2').innerHTML)
setTimeout('showpart2()',15000);
}
showpart2();
One big problem with the sample code is that making XMLHttpRequest.send synchronous means all JS execution must pause while waiting for the request to be received. There's no reason not to use an asynchronous call.
Asynchronous calls can improve responsiveness, but what they don't give you is coordination, which means a task won't run until the data it needs is ready. The standard way of coordinating asynchronous code is to pass to the asynchronous function a function that, when executed, performs the rest of the computation that relies on the data. This function has the technical name "continuation", which is simply a function that represents the rest of the computation from a given point forward. That is, turn:
f1();
f2();
async();
f3();
f4();
into:
f1();
f2();
async(function() {
f3();
f4();
});
Because you're passing around a continuation, this is known as "continuation passing style". XMLHttpRequest is a special case in that rather than passing a function to the asynchronous function, you set it as a listener for the readystatechange event on the XHR object. That is, you assign the continuation to xmlhttp.onreadystatechange.
There are a few more improvements to make. First, add error detection. The status property of the XHR instance holds the HTTP status, which you can use to check for errors.
As a number of others have mentioned, eval can be problematic and should be avoided when there's another option. For one thing, you have to make sure the string comes from a trusted source. The particular problem with eval here is that the script is evaluated in the same context as the call to eval. If the eval happens inside a function, anything defined by the script isn't visible outside the function. If your script doesn't need to define anything (and will never need to define anything; always consider the future of your code), you can use eval. Otherwise, dynamically create a script element with the script as content and add it to the document; you can define a function that does this (see globaleval in the sample below).
xmlhttp is a global variable, which is bad. Instead, declare it as a local variable.
Rather than setTimeout, which is for one-shot calls, use setInterval, which calls the passed function periodically. Note that both setTimeout and setInterval may take longer than the given delay to run, though that shouldn't be an issue here.
(function () {
// keep variable from polluting global namespace
var showpart2Interval = 0,
scriptElt = {parentNode: {removeChild: function() {}}};
function globaleval(script) {
scriptElt.parentNode.removeChild(scriptElt);
scriptElt = document.createElement('script');
scriptElt.type = 'text/javascript'
scriptElt.appendChild(document.createTextNode(script));
document.body.appendChild(scriptElt);
}
function showpart2(){
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","atuamae.org/parte2-encomendar.php",false);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
if (200 <= xmlhttp.status && xmlhttp.status < 300) {
globaleval(xmlhttp.responseText);
} else {
// HTTP error
...
}
}
}
xmlhttp.send(null);
}
function startShowpart2() {
if (window.XMLHttpRequest && !showpart2Interval) {
showpart2();
showpart2Interval = setInterval(showpart2, 15000);
}
}
function stopShowpart2() {
clearInterval(showpart2Interval);
showpart2Interval = 0;
}
window.startShowpart2 = startShowpart2;
window.stopShowpart2 = stopShowpart2;
})();
startShowpart2();
If you don't care about implementing all of this yourself, have jQuery do the heavy lifting. It's good to know how to do things yourself, but (for production code) using standard libraries with standard interfaces speeds up development in a number of ways.
See also
Javascript: Set the order of functions
You need to actually evaluate the JS-tags (manually, either through eval or through DOM insertion). A library like jQuery would do this for you, but if you need to use a custom solution you'll need to add that as well.
You write:
xmlhttp.responseText.getElementById('part2')
The responseText is a string, and won't have any getElementById method.
You either want to use xmlhttp.responseXML.getElementById("part2") or use string methods to extract the second part.
Like Adam Rackis I recommend you use $.ajax is reallyyyy easy try it.....but if it is not an option for you here is a function as used to use when making ajax calls and worked in IE and Firefox, Chrome I recommend to you if you can not use Jquery.
The problem in your function not works in IE as it has no xmlhttprequest object.
Hope this helps you.
function newAjaxObject()
{
var oHttp=false;
var asParsers=[
"Msxml2.XMLHTTP.5.0",
"Msxml2.XMLHTTP.4.0",
"Msxml2.XMLHTTP.3.0",
"Msxml2.XMLHTTP",
"Microsoft.XMLHTTP"
];
if ( !oHttp && typeof XMLHttpRequest != 'undefined')
{
oHttp=new XMLHttpRequest();
}
if( !oHttp){
for (var iCont=0; !oHttp && iCont < asParsers.length; iCont++)
{
try
{
oHttp=new ActiveXObject(asParsers[iCont]);
}
catch(e)
{
oHttp=false;
}
}
}
return oHttp;
}

Can AJAX get results from an internal PHP function rather than an external page?

I have just started into OO PHP and have created my first class. As it is, it works, but I want to tidy things up a bit.
Right now elements in the class call an ajax function that is declared in the head of the document.
I don't want the class to be dependent on a proper head, so to keep it self contained, I moved the script functions into the class file. I could not find information on whether this is a no-no, so if it is, I want to know "Why is putting javascript/ajax in a PHP class bad form?" If, however, it is an acceptable practice, I have a trickier question.
The AJAX calls a PHP page who's results will then fill in more of the class object on the page. But, I figure the class would be better if it didn't rely on external php files either. So, I moved the files into functions on the class file. Here's the tricky bit.
How do I get the AJAX to get the results from a function located on the same file as the AJAX call instead of an external page?
Here is my AJAX code so far. var url currently is the path to one of two possible PHP pages instead of the desired internal php functions. var dest is where in the class object the results end up.
function createRequestObject() {
var ro;
var browser = navigator.appName;
if(browser == "Microsoft Internet Explorer"){
ro = new ActiveXObject("Microsoft.XMLHTTP");
}else{
ro = new XMLHttpRequest();
}
return ro;
}
var http = createRequestObject();
function sndReq(url,dest) {
http.open('get',url);
http.onreadystatechange = function () {
if (http.readyState == 4) {
if (http.status == 200) {
var responce = http.responseText;
document.getElementById(dest).innerHTML = responce;
}
}
};
http.send(null);
}
What you're asking for sounds like xml-rpc or json-rcp. It lets you dynamically execute server-side code and get the results.
Example javascript rpc library: http://barracudaserver.com/doc/WebServices/JRpcDoc.html
However, I think that simply passing parameters is what you want. The simplest way is to pass get parameters in the url
http://www.site.com/ajax.php?cmd=find_user&user_id=12
then in php check for those parameters in the global $_GET variable
if(isset($_GET["cmd"]) && $_GET["cmd"] == "find_user"){
$user_id = $_GET["user_id"];
//some server-side stuff
echo results;
}

PHP, jQuery & Ajax calls out of order

I am using jQuery for my Ajax calls... I have x amount of Ajax calls that append to a div. These Ajax load requests are generated by a PHP foreach loop... The problem is they render out of the order; they are set in the array...
<script type="text/javascript">
function loadPage(target, url, append)
{
if (append == true) {
$.get(url, function(data) { $(target).append(data) });
}
else {
$(target).load(url);
}
return false;
}
</script>
////// ----- PHP
<?php
$this->data['sidebar'] = array('login', 'active_leagues', 'latest_forum_threads', 'latest_matches', 'sponsors');
if (isset($sidebar[0]) && !empty($sidebar[0]))
{
echo '<div class="right_col">';
foreach($sidebar as $val)
{
echo "<script>loadPage('.right_col', 'http://dev.banelingnest.com/sidebar/". $val ."', true)</script>";
}
echo '</div>';
}
I am wonder if the cause of this is the web server responding slower to some requests than others... Other than that, I have no clue why this could be happening. Do you have any thoughts how I could keep the requests in order?
You have to create reference points before the requests, and append the results to them:
var counter = 0;
function loadPage(target,url,append)
{
if (append == true) {
var id = "container_"+counter;
$(target).append("<div id='"+id+"'></div>")
$.get(url, function(data) {
$("#"+id).append(data);
});
counter++;
} else {
$(target).load(url);
}
return false;
}
Your reference elements will be appended to the target on every loadPage() call, so they will be in the correct order, and the request can come in any order they will be loaded in their right place.
This is happening because the ajax calls are asynchronous, and the order they go out has nothing to do with the order they are returned. They will all happen independently and it's expected for some to run faster than others.
You will need to use $.ajax instead of $.get, and set async to false.
See this question: How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?
You can also use the unique and interesting solution presented by #inti.
You could do synchronous requests instead of asynchronous, which'd force the browser to wait until each individual request finishes before starting the next. The downside that is for any "lengthy" requests (or many short ones), the browser will be locked up.
You may want to investigate sending all your requests in a single AJAX call, rather than doing one-request-per-call. That way it'd be easy for the scripts on both sides to keep everything in order. Otherwise you're stuck depending on the user link to your server having low error rates, low latency, and low congestion.
So instead of doing the equivalent of
loadPage(1); // fetch data #1
loadPage(37); // fetch data #37
loadPage(203); // fetch data #203
do something like
loadPage([1,37,203]); // fetch all 3 at once.
I have 2 ideas that may help, the first is:
jQuery has a $(document).ready(function() function that is possibly being called from a parent function or being inherited somehow, this means the JavaScript won't run before the rest of the PHP has loaded.
I have seen some functions inherit this from jQuery without it being declared.
The second is:
I am assuming that this function is running in the head or early on in your page and not the foot or later on in the document.
I hope they help.
This is the nature of AJAX, and yes the server is responding faster to some than others.
If you want them in order, you would have to make the first call, then on the complete event, call the next one, and so on; in essence creating a synchronous chain of calls (kind of goes against the A in AJAX).
Without knowing your specific reasons for wanting them in order, this may be a lot more work than what it's worth.
However you do it, it will take away from the user experience, because if one call is slow, all of the other will have to wait.
The simplest solution is creating placeholders, as inti described. Your elements will not necessarily appear in order, but they will end up in the right order. If you need them to appear in order too, here is a simple queue using deferreds:
var queue = [];
function loadPage(target,url) {
queue.push($.get(url));
$.when.call($, queue).then(function() {
$(target).append(Array.prototype.pop.call(arguments));
});
}
The AJAX calls will run in parallel, but the callbacks will fire strictly in order.
Here is what I did with the array or urls I needed to load in order.
I created the order of wrappers first, than did the ajax calls, and load the results into the matching wrapper. This keeps the calls asynchronous, but you still the the proper order.
$.fn.dashboarder = function(options)
{
var settings = $.extend({
urls: [],
}, options || {});
var self = this;
if (settings.urls.length)
{
$(self).html('');
/// create wrapper blocks in the proper order, so they eventually display in this order
$(settings.urls).each(function( index, value )
{
var wrapper = $( "<div />" )
.addClass('dashboard-block-item')
.attr('id', 'dashboard-block-item-'+index);
$(self).append($(wrapper));
});
$(settings.urls).each(function( index, value )
{
$('#dashboard-block-item-'+index).load(value, function( response, status, xhr )
{
}).delay(5000 * index);
});
}
return this;
}
function debug( obj ) {
if ( window.console && window.console.log ) {
window.console.log( obj );
}
};

How to insert a PHP dropdown in a HTML / Javascript page

Ok, this is my second post, and PLEASE accept that I am a complete newbie, willing to learn, spending many hours trauling various sites for answers, and I've almost got to where I need to be (at least for this bit).
I have a web page which has a nubmer of javascript functions that work together to generate a Google Map with various lines etc. using the google maps API.
I also have a MySQL Database with some information in.
I have created a PHP script to dynamically generate a dropdown box with information from the database. (and that bit seems to work fine) - http://www.bournvilleconservatives.com/temp/select.php
What I now need to do is get that dropdown box to appear in the HTML / Javascript page that I already have, so that when a user selects something from the list, it calls a javascript function with the value selected.
I'm told I need to use AJAX to pull the box in, and use innerhtml to display it, but I really have no idea how, and could do with an example of something similar to help me on my way.
I would put the PHP in the html page, but that page is actually wrapped up in a Joomla! wrapper, so its all rather complicated.
Thanks in advance.
jQuery solution
If you are willing to use jQuery, it will help you a lot with accessing the DOM, making Ajax calls and stuff. Let me give you a solution in jQuery:
First, put a div into HTML (this will store your select box):
<div id="i_want_my_select_here"></div>
Then put this code in the end of you HTML before </body>.
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#i_want_my_select_here').load('/temp/select.php');
});
</script>
In the first script tag, we include the jQuery library from Google's CDN. In the second, we write our Javascript/jQuery code. The .load() function makes it easy to make an Ajax call and load the response into an HTML element.
You can see this is much easier than all that code in my other answer :).
If you're using prototype, you can use either Ajax.Request or Ajax.Updater, tho you should have a parent div with either to replace/insert into.
Example w/ Request:
new Ajax.Request('select.php', {
method: 'post',
onSuccess: function(r) {
var select = r.responseText;
$('parent_div').update(select);
}
});
Example w/ Updater:
new Ajax.Request('parent_div', 'select.php', { method: 'post' });
First, the Ajax example (taken from tizag.com and modified), Javascript code comes:
var ajaxRequest; // The variable that we will put an XMLHTTPRequest object in
//We try to create an XMLHTTPRequest object,
//it is the object that lets us use Ajax
try{
// Opera 8.0+, Firefox, Safari
ajaxRequest = new XMLHttpRequest();
} catch (e){
// Internet Explorer Browsers
try{
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try{
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
// Something went wrong
alert("Your browser broke!");
return false;
}
}
}
// Create a function that will receive data sent from the server
// and do stuff with it (this function will only run,
// when the data arrives back from the server!)
ajaxRequest.onreadystatechange = function(){
if(ajaxRequest.readyState == 4){ //if request is successful
//HERE COMES THE DOM INSERTION
}
}
//We call the PHP file
ajaxRequest.open("GET", "/temp/select.php", true);
ajaxRequest.send(null);
What basically happened is that through XMLHTTPRequest we called your PHP file. When the response (PHP file's output) comes, ajaxRequest.onreadystatechange will run instantly. So whatever we want to do with the data received, we have to do it in the place I've written //HERE COMES THE DOM INSERTION.
We want to insert the output into the HTML. To take the easiest route, first create a div/span in your HTML at the exact place you want your select to appear (it's very important to define the ID).
<div id="i_want_my_select_here"></div>
Then again, here comes the Javascript that replaces //HERE COMES THE DOM INSERTION.
//use the id to get Javascript access to the DIV
var div=document.getElementById('i_want_my_select_here');
//put the output of PHP into the div
div.innerHTML=ajaxRequest.responseText;

Categories