Hello.

I am using MYSQL to store articles. I wanted to present the articles in order by id, then let the user choose one of them and send the id of the article to another php page for processing, using ajax. To do so i have placed a simple form in the articles. like so:

$result = mysql_query("SELECT * FROM articles  ORDER BY id DESC")
or die(mysql_error());
 while($row = mysql_fetch_array($result)){

	$articletid = $row["id"];
	$category = $row["category"] . "<br/>";
	$title = $row["title"] . "<br/>";
	$date = strftime("%d/%m/%y", strtotime($row['date'])) . "<br/>";
	$body = $row["body"] . "<br/>";
 

echo '<div id="connectComplaint"><font size="3">';
echo $complaintid;
echo "<b><font color=red size=3>" . $title . "</b></font>";
echo "<font size=2>Category:" . $category;
echo "<font size=2>An article by:<font color=blue><a href=$self?userprofile=$user>" . $user . " </font></a>from:<font color=green>" . $date . "</font><br>";
echo "<br>" . nl2br($body);
echo '<br><form id="processrequest" action="" method="post">

<input type="hidden" id="complaintid" name="complaintid" value="'. $articletid .'">
<span style="color=blue; text-decoration:underline; cursor:hand;" onclick="javascript:makePOSTReques(this.parentNode);">choose this article!</span>
</form>';
echo "<br><hr><br></div>";
}

So you see, each article is presented in its turn with the submitting form attached to it, and the idea is that the form sends the ID of the article the user chooses.

I used this ajax script which i found on the net:

var http_request = false;
   function makePOSTRequest(url, parameters) {
      http_request = false;
      if (window.XMLHttpRequest) { // Mozilla, Safari,...
         http_request = new XMLHttpRequest();
         if (http_request.overrideMimeType) {
         	// set type accordingly to anticipated content type
            //http_request.overrideMimeType('text/xml');
            http_request.overrideMimeType('text/html');
         }
      } else if (window.ActiveXObject) { // IE
         try {
            http_request = new ActiveXObject("Msxml2.XMLHTTP");
         } catch (e) {
            try {
               http_request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {}
         }
      }
      if (!http_request) {
         alert('Cannot create XMLHTTP instance');
         return false;
      }
      
      http_request.onreadystatechange = alertContents;
      http_request.open('POST', url, true);
      http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded charset=utf-8;" );
      http_request.setRequestHeader("Content-length", parameters.length);
      http_request.setRequestHeader("Connection", "close");
      http_request.send(parameters);
   }

   function alertContents() {
      if (http_request.readyState == 4) {
         if (http_request.status == 200) {
       
            document.getElementById('processrequest').innerHTML = http_request.responseText;       
		
         } else {
            alert('There was a problem with the request.');
         }
      }
   }
   


   function get(obj) {
            var poststr = "articleid=" + encodeURI( document.getElementById("articleid").value );
      makePOSTRequest('processrequest.php', poststr);
   }

this worked great for me in other cases, but not when the form is inside a php while loop. this script only sends the latest article's ID. So if I have 6 articles in the database, the ID "6" is sent no matter which article you choose.

If I remove the ajax and use a regular submit button, it works fine. Obviously my problem is in the ajax, I figured I should "tell" ajax that the data is taken from a loop somehow...

Anyway, if anyone can tell me how to make this work properly using the ajax, i would greatly appreciate it!

Thanks!

Recommended Answers

All 16 Replies

your problem is in what you are sending the php script, not the php script itself. you are sending this.parentNode. instead of a valid url. if the php script was say called getarticle.php then this code would be applicable.

onclick="javascript:makePOSTRequest(this.parentNode.action,this.parentNode.children[0].value);"

basically what I am doing here is getting the url from the parent's action property and get the parameter from the hidden input element, then sending it to the postrequest thingy. and by the way there is a typo in your code the onclick= part says onclick="javascript:makePOSTReques" without the "t" at the end

your problem is in what you are sending the php script, not the php script itself. you are sending this.parentNode. instead of a valid url. if the php script was say called getarticle.php then this code would be applicable.

onclick="javascript:makePOSTRequest(this.parentNode.action,this.parentNode.children[0].value);"

basically what I am doing here is getting the url from the parent's action property and get the parameter from the hidden input element, then sending it to the postrequest thingy. and by the way there is a typo in your code the onclick= part says onclick="javascript:makePOSTReques" without the "t" at the end

Unfortunately it still does not work. I tried what you suggested but it still sends just the last article's ID.
Maybe I am doing something wrong. I basically just copy-pasted the code you suggested. Any thoughts?

currently the form that you are creating with the php script has no action. you need to set that to the correct php script before my script will work, also add an onsubmit for the form itself that just returns false so that when you click submit it won't actually go to the url.

currently the form that you are creating with the php script has no action. you need to set that to the correct php script before my script will work, also add an onsubmit for the form itself that just returns false so that when you click submit it won't actually go to the url.

I really appreciate the help, but still it doesn't work. I did as you suggested and still it sends only the the last article's id.

Now, i'm thinking of a different strategy. I'm thinking since it works fine if I remove the Ajax, what if I send the data to another PHP, process it, and then send it (all processed) again to an Ajax script which would then just update the div with the response?

Any thoughts? How does one send data to ajax without using forms?

Or, if you (or anyone else reading this) have any other ideas how to get it to work, I would be very grateful.

Thanks a lot!

Now, i'm thinking of a different strategy. I'm thinking since it works fine if I remove the Ajax, what if I send the data to another PHP, process it, and then send it (all processed) again to an Ajax script which would then just update the div with the response?

Any thoughts? How does one send data to ajax without using forms?

Stick with forms. They are as easy/hard as anything else. You just need to get the HTML and javascript right (simples!).

Not tested but should at least give you some clues :

$result = mysql_query("SELECT * FROM articles  ORDER BY id DESC")
or die(mysql_error());
while($row = mysql_fetch_array($result)){
	$action = "myURL?complaintid=" . $row["id"];//Change "myURL" to your path/file
	$category = $row["category"];
	$title = $row["title"];
	$date = strftime("%d/%m/%y", strtotime($row['date']));
	$body = $row["body"];

	echo '<div id="connectComplaint"><font size="3">';
	echo $complaintid;
	echo '<b><font color="red" size="3">' . $title . '</font></b><br/>';
	echo '<font size="2">Category:' . $category . '</font><br/>';
	echo '<font size="2">An article by:&nbsp;<a href="' . $self? . 'userprofile=' . $user . '"><font color="blue">' . $user . " </font></a>from:&nbsp;<font color=\"green\">" . $date . "</font><br/><br/>";
	echo nl2br($body) . '<br/>';
	echo '<form action="' . $action . '" method="GET" target="processrequest" onsubmit="makePOSTRequest(this); return false;"><input type="submit" value="Choose this article!" /></form>';
	echo '<br/><hr><br/></div>';
}
function getXmlHttpRequest(){
	http_request = false;
	try { http_request = new XMLHttpRequest(); }// Mozilla, Safari,...
	catch(e) {
		try { http_request = new ActiveXObject("Msxml2.XMLHTTP"); }
		catch (e) {
			try { http_request = new ActiveXObject("Microsoft.XMLHTTP"); }
			catch (e) {};
		}
	}
	return http_request;
}
function makePOSTRequest(form) {
	var http_request = getXmlHttpRequest();
	if (!http_request) {
		alert('Cannot create XMLHTTP instance');
		return false;
	}
	if (http_request.overrideMimeType) {
		http_request.overrideMimeType('text/html');
	}
	var method = form.method;//ie. GET
	var url = form.action;
	var target = form.target;
	http_request.open(method, url, true);
	http_request.onreadystatechange = function() {
		if (http_request.readyState == 4) {
			if (http_request.status == 200) {
				document.getElementById(target).innerHTML = http_request.responseText;
			}
			else {
				alert('There was a problem with the request.');
			}
		}
	};
	http_request.send(null);
}

You'll see I'm using "GET" here, which reduces some uncertainty. You will need to pick up $_GET in PHP. Once you have it working, you should be able to revert to "POST" without too many changes.

Airshow

Stick with forms. They are as easy/hard as anything else. You just need to get the HTML and javascript right (simples!).

Not tested but should at least give you some clues :

$result = mysql_query("SELECT * FROM articles  ORDER BY id DESC")
or die(mysql_error());
while($row = mysql_fetch_array($result)){
	$action = "myURL?complaintid=" . $row["id"];//Change "myURL" to your path/file
	$category = $row["category"];
	$title = $row["title"];
	$date = strftime("%d/%m/%y", strtotime($row['date']));
	$body = $row["body"];

	echo '<div id="connectComplaint"><font size="3">';
	echo $complaintid;
	echo '<b><font color="red" size="3">' . $title . '</font></b><br/>';
	echo '<font size="2">Category:' . $category . '</font><br/>';
	echo '<font size="2">An article by:&nbsp;<a href="' . $self? . 'userprofile=' . $user . '"><font color="blue">' . $user . " </font></a>from:&nbsp;<font color=\"green\">" . $date . "</font><br/><br/>";
	echo nl2br($body) . '<br/>';
	echo '<form action="' . $action . '" method="GET" target="processrequest" onsubmit="makePOSTRequest(this); return false;"><input type="submit" value="Choose this article!" /></form>';
	echo '<br/><hr><br/></div>';
}
function getXmlHttpRequest(){
	http_request = false;
	try { http_request = new XMLHttpRequest(); }// Mozilla, Safari,...
	catch(e) {
		try { http_request = new ActiveXObject("Msxml2.XMLHTTP"); }
		catch (e) {
			try { http_request = new ActiveXObject("Microsoft.XMLHTTP"); }
			catch (e) {};
		}
	}
	return http_request;
}
function makePOSTRequest(form) {
	var http_request = getXmlHttpRequest();
	if (!http_request) {
		alert('Cannot create XMLHTTP instance');
		return false;
	}
	if (http_request.overrideMimeType) {
		http_request.overrideMimeType('text/html');
	}
	var method = form.method;//ie. GET
	var url = form.action;
	var target = form.target;
	http_request.open(method, url, true);
	http_request.onreadystatechange = function() {
		if (http_request.readyState == 4) {
			if (http_request.status == 200) {
				document.getElementById(target).innerHTML = http_request.responseText;
			}
			else {
				alert('There was a problem with the request.');
			}
		}
	};
	http_request.send(null);
}

You'll see I'm using "GET" here, which reduces some uncertainty. You will need to pick up $_GET in PHP. Once you have it working, you should be able to revert to "POST" without too many changes.

Airshow

Unfortunately, still not working.
I keep getting the "there was a problem" alert, even though i know everything is in its right place... any thoughts?

It may be something to do with the way the php pages are served.

Try inserting alert(http_request.status) immediately after if (http_request.readyState == 4) { to see what the status code is.

Airshow

It may be something to do with the way the php pages are served.

Try inserting alert(http_request.status) immediately after if (http_request.readyState == 4) { to see what the status code is.

Airshow

The problem appears to be the form.action part. Once I removed it and replaced it with the actual file name ("process.php"), it almost worked...

You see, I ran a simple test to see the the values are being delivered to the processing php page. The page echoes the values along with a little message that says "These are your values!", and the returned response is just this message. Which means of course that the values are not being delivered by the ajax, although it does communicate with the correct php process file (as evident by the "these are you values" message).
Now, I know the problem is in the ajax code, because if I remove it the PHP page echoes the values as well.

I tried to make some changes to the ajax, but still I can't seem to make it work.
Can you imagine how frustrating this is? I have one code which won't send the values, and another one which will send only the last entry in a while loop...

I really appreciate your help, guys. If you have any more ideas, I will try anything at this point...

try an alert(url); just after you set it, and put that into your browser to make sure that the url is correct. another thing is that you are declaring http_request as a local variable because you are putting var in front of it try taking var out.

..... Now, I know the problem is in the ajax code, because if I remove it the PHP page echoes the values as well. ...

It sounds like the request part of the url isn't being composed properly.

See my line $action = "myURL?complaintid=" . $row["id"]; . As far as I can tell, that's the correct format. You can check these urls are OK (and the rest of the HTML) with right-click > view_source in the browser.

Then it's a question of making sure makePOSTRequest picks up the values from the HTML correctly. As Gerbiler says, alert(url) , but also alert(target) . Both values should be identical to what you saw when you inspected the HTML with view_source.

If you still can't get it working then post the served HTML here (ie. what you get from view_source). That's far more useful than the PHP. Gerbiler or I should then be able to run it (with some dummy file in place of the real process.php) and debug the javascript if that's what needs doing.

Airshow

It sounds like the request part of the url isn't being composed properly.

See my line $action = "myURL?complaintid=" . $row["id"]; . As far as I can tell, that's the correct format. You can check these urls are OK (and the rest of the HTML) with right-click > view_source in the browser.

Then it's a question of making sure makePOSTRequest picks up the values from the HTML correctly. As Gerbiler says, alert(url) , but also alert(target) . Both values should be identical to what you saw when you inspected the HTML with view_source.

If you still can't get it working then post the served HTML here (ie. what you get from view_source). That's far more useful than the PHP. Gerbiler or I should then be able to run it (with some dummy file in place of the real process.php) and debug the javascript if that's what needs doing.

Airshow

Everything seems to be in order, but still it doesn't work. Here is the served HTML:

<div id="showusercomplaints">
<div id="connectComplaint"><b><font color=red size=3>My First Article<br/></b></font><font size=2>Category: Other<br/><font size=2>By:<font color=blue><a href=?userprofile=shukybenami>shukybenami </font></a>Posted On:<font color=green>24/09/10<br/></font><br><br>First article, just a test <br/><br>
<form id="joingroupform" action="connectcomplaintogroup.php" method="post">
<input type="hidden" id="complaintid" name="complaintid" value="connectcomplaintogroup.php?complaintid=6">
<span style="color=blue; text-decoration:underline; cursor:hand;" onclick="javascript:makePOSTRequest(this);">Choose this article!</span>
</form><br><hr><br></div><
<div id="connectComplaint"><b><font color=red size=3>My Second Article<br/></b></font><font size=2>Category: Other<br/><font size=2>By:<font color=blue><a href=?userprofile=shukybenami>shukybenami </font></a>Posted On:<font color=green>24/09/10<br/></font><br><br>Second article, just a test <br/><br>
<form id="joingroupform" action="connectcomplaintogroup.php" method="post">
<input type="hidden" id="complaintid" name="complaintid" value="connectcomplaintogroup.php?complaintid=5">
<span style="color=blue; text-decoration:underline; cursor:hand;" onclick="javascript:makePOSTRequest(this);">Choose this article!</span>
</form><br><hr><br></div></td><td valign="top">
</div>

You might notice that I've changed the button with a span, but it doesn't matter, I get the same results when using a button input.
Also I changed a bit the structure of the form, but again I don't think it matters. It didn't work with the structure Airshow suggested also.

Now, I take the Javascript from a file of scripts included in the head of my page.
the script:

function getXmlHttpRequest(){
http_request = false;
try { http_request = new XMLHttpRequest(); }// Mozilla, Safari,...
catch(e) {
try { http_request = new ActiveXObject("Msxml2.XMLHTTP"); }
catch (e) {
try { http_request = new ActiveXObject("Microsoft.XMLHTTP"); }
catch (e) {};
}
}
return http_request;
}
function makePOSTRequest(form) {
var http_request = getXmlHttpRequest();
if (!http_request) {
alert('Cannot create XMLHTTP instance');
return false;
}
if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/html');
}
var method = form.method;
var url = "connectcomplaintogroup.php";
var target = form.target;

http_request.open(method, url,true);
http_request.onreadystatechange = function() {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
document.getElementById("showusercomplaints").innerHTML = http_request.responseText;
}
else {
alert('There was a problem with the request.');
}
}


};
http_request.send(null);
}


and of course, the form is on a php file which connects to MYSQL to retrieve the articles.

So, any thoughts?

Again, I really want to thank you for your help...

WebKoller,

Unfortunately, changing the button to a span matters very much because a span doesn't act as a submit button, which is critical if we stick with forms. If you want to have clickable text rather than a button, then maybe it's time to drop forms. This means hard-coding in javascript a couple of strings, which were previously picked up from the form tags.

Several other things need sorting out too, for example simplifying the HTML by styling with CSS rather than bulky <font> etc tags, and it's a good idea to use block elements <div> or <p> instead of <br>s for line breaks. Also, element ids should always be unique. Use classes for styling/addressing repeated elements, or a repeated class together with unique ids in some circumstances.

I'm not sure exactly what onscreen effect you want when the user clicks "Choose this article" so I've made some guesses in coding the attached page. Try setting the variable collapseList to true/false to change the behaviour.

The ajax call is hard-coded to "GET", so make sure your php picks up $_GET ($_REQUEST should pick up the value from either $_GET or $_POST).

You will see that I have placed all javascript code inside a document.onload handler. This may be unfamiliar to you but has several advantages, primarily not cluttering up the global namespace, avoiding repetition in the code, and giving simpler access to event related data.

It may not be exactly what you want but should give you an idea of how to organise HTML, CSS and JavaScript into a coherent application.

Zipped file attached. Plenty of comments in the code.

Airshow

WebKoller,

Unfortunately, changing the button to a span matters very much because a span doesn't act as a submit button, which is critical if we stick with forms. If you want to have clickable text rather than a button, then maybe it's time to drop forms. This means hard-coding in javascript a couple of strings, which were previously picked up from the form tags.

Several other things need sorting out too, for example simplifying the HTML by styling with CSS rather than bulky <font> etc tags, and it's a good idea to use block elements <div> or <p> instead of <br>s for line breaks. Also, element ids should always be unique. Use classes for styling/addressing repeated elements, or a repeated class together with unique ids in some circumstances.

I'm not sure exactly what onscreen effect you want when the user clicks "Choose this article" so I've made some guesses in coding the attached page. Try setting the variable collapseList to true/false to change the behaviour.

The ajax call is hard-coded to "GET", so make sure your php picks up $_GET ($_REQUEST should pick up the value from either $_GET or $_POST).

You will see that I have placed all javascript code inside a document.onload handler. This may be unfamiliar to you but has several advantages, primarily not cluttering up the global namespace, avoiding repetition in the code, and giving simpler access to event related data.

It may not be exactly what you want but should give you an idea of how to organise HTML, CSS and JavaScript into a coherent application.

Zipped file attached. Plenty of comments in the code.

Airshow

Airshow, wow, thank you very much!

I can't believe the time and work you put into it, this is amazing!
I seriously appreciate this.

As for my coding, that's just the way I work. When I begin a new project I like to have the system working before I use CSS to style it. It's a bit messy, I know, but it's a work habit I picked up along the way.

BTW, you CAN use span to submit a form using ajax, because the span calls for the ajax function and the function actually submits the data (not the span). My original code worked great with the span, with the only problem being the fact that it sent the last entry only for some reason when used from within a while loop...

Anyway, again, thank you for all your help (and you to, Gerbiler)!

No probs.

As for my coding, that's just the way I work. When I begin a new project I like to have the system working before I use CSS to style it. It's a bit messy, I know, but it's a work habit I picked up along the way.

I'm exactly the same. As someone once said, "Do as I say, not as I do".

BTW, you CAN use span to submit a form using ajax,

Yup, but the javascript was written to be called from onsubmit=... in the form tag. By calling from anything other than onsubmit=... it wouldn't pick up the form tag's action or method attributes. this , passed as an argument, means somthing different in the two cases.

Good luck with the rest of the project.

Airhow

No probs.


I'm exactly the same. As someone once said, "Do as I say, not as I do".


Yup, but the javascript was written to be called from onsubmit=... in the form tag. By calling from anything other than onsubmit=... it wouldn't pick up the form tag's action or method attributes. this , passed as an argument, means somthing different in the two cases.

Good luck with the rest of the project.

Airhow

Is it possible to use the script you sent me to send 2 variables at the same time? If so, how?
Or do I have to change it to POST if I want to do that?

Thanks again!

WebKoller,

POST and GET are equally capable in this reagard. You can send as many variables as you like. Just stack them up in the "search" part of the URL (bit after the ?).

This pattern is useful:

var search = [
  "complaintid=" + cid,
  "var2" + xxx
  //...
];
var url = 'connectcomplaintogroup.php? + search.join('&');
//...

Airshow

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.