PDA

View Full Version : Problem with Ajax POST request



bslashdash
08-08-2008, 07:47 AM
Hi there, I was wondering if any of you guys on here can help me with this.

I'm a total newbie when It comes to AJAX and Javascript in general so forgive me if this is really simple.

I have a script that I found on www.captain.at which basically allows an html form to be submitted, processes the corresponding php file and shows the result.

The code is as follows


<script type="text/javascript" language="javascript">
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");
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) {
//alert(http_request.responseText);
result = http_request.responseText;
document.getElementById('addfriend').innerHTML = result;
} else {
alert('There was a problem with the request.');
}
}
}
function get(obj) {
var poststr = "userID=" + encodeURI( document.getElementById("userID").value ) +
"&friendID=" + encodeURI( document.getElementById("friendID").value );
makePOSTRequest('requests/addFriend.php', poststr);
}
</script>


And this is the code used for the form


<form action="javascript:get(document.getElementById('addfriend'));" name="addfriend" id="addfriend">
<input type="hidden" id="userID" value="{me.id}">
<input type="hidden" id="friendID" value="{user.id}">
<input type="button" name="button" value="Add to friends" onclick="javascript:get(this.parentNode);" class="ajaxbutton">
</form>

Now this works perfectly however I have more than one request I need to process in this way. The above code lets a user add another user to their friends list. I need the users to be able to add users to their favorites list also, and this would be done through a separate form.

What changes need to be made to the javascript code to allow me to have multiple forms leading to different php files on one page.

Any help would be greatly appreciated.

Thanks :o) :o)

Jesdisciple
08-08-2008, 05:26 PM
Have you tried this?
<form action="javascript:get(document.getElementById('addfriend'));" name="addfriend" id="addfriend">
<input type="hidden" id="userID" value="{me.id}">
<input type="hidden" id="friendID" value="{user.id}">
<input type="button" name="button" value="Add to friends" onclick="get(this.parentNode);" class="ajaxbutton">
</form>

<form action="javascript:get(document.getElementById('addfavorite'));" name="addfavorite" id="addfavorite">
<input type="hidden" id="userID" value="{me.id}">
<input type="hidden" id="pageID" value="{page.id}">
<input type="button" name="button" value="Add to favorites" onclick="get(this.parentNode);" class="ajaxbutton">
</form>NOTE: I removed the "javascript:" protocol from the onclick handlers because it's unnecessary and improper. It's only needed where a URL is expected in the HTML.

bslashdash
08-08-2008, 10:19 PM
Thanks for your reply.

Yeah I did change the form aspect of it to what you have suggested but I need the script to call the addFavourite.php file when it is submitted instead of the addFriend.php script.

So i guess there needs to be some addition to the current javascript code for this?

Jesdisciple
08-08-2008, 10:24 PM
Note that you can, of course, prefix url with 'requests/' for convenience if all AJAX requests will go to that folder.
function get(obj, url) {
var poststr = "userID=" + encodeURI( document.getElementById("userID").value ) +
"&friendID=" + encodeURI( document.getElementById("friendID").value );
makePOSTRequest(url, poststr);
}
<form action="javascript:get(document.getElementById('addfriend'), 'requests/addFriend.php');" name="addfriend" id="addfriend">
<input type="hidden" id="userID" value="{me.id}">
<input type="hidden" id="friendID" value="{user.id}">
<input type="button" name="button" value="Add to friends" onclick="get(this.parentNode, 'requests/addFriend.php');" class="ajaxbutton">
</form>

<form action="javascript:get(document.getElementById('addfavorite'), 'requests/addFavorite.php');" name="addfavorite" id="addfavorite">
<input type="hidden" id="userID" value="{me.id}">
<input type="hidden" id="pageID" value="{page.id}">
<input type="button" name="button" value="Add to favorites" onclick="get(this.parentNode, 'requests/addFavorite.php');" class="ajaxbutton">
</form>

bslashdash
08-08-2008, 10:46 PM
Ahh perfect thanks for that.

One last thing if I had to pass different information for each form for example for the addFriend.php function I need to pass userID and friendID but what if i had to pass different information for the addFavourite.php function see the code below.



<form action="javascript:get(document.getElementById('addfriend'), 'requests/addFriend.php');" name="addfriend" id="addfriend">
<input type="hidden" id="userID" value="{me.id}">
<input type="hidden" id="friendID" value="{user.id}">
<input type="button" name="button" value="Add to friends" onclick="get(this.parentNode, 'requests/addFriend.php');" class="ajaxbutton">
</form>

<form action="javascript:get(document.getElementById('addfavorite'), 'requests/addFavorite.php');" name="addfavorite" id="addfavorite">
<input type="hidden" id="userID" value="{me.id}">
<input type="hidden" id="favouriteID" value="{favourite.id}">
<input type="hidden" id="favLinkID" value="{favlink.id}">
<input type="button" name="button" value="Add to favorites" onclick="get(this.parentNode, 'requests/addFavorite.php');" class="ajaxbutton">
</form>

Also after the addFriend.php function has run it displays the results in a span called
<span name="addfriend" id="addfriend"></span> and i need the addFavourite.php function to display it's results in a span called
<span name="addfavourite" id="addfavourite"></span>

Jesdisciple
08-08-2008, 11:39 PM
I have an appointment that I'm late for, but that first modification is fairly easy. Pass an array of strings as the third parameter to get. Use each value (for(index in names){var name = names[index]; /*...*/}) for both the POST variable and the input-element's ID. Or you could take the names of the input-elements from the input-elements themselves by traversing the DOM. That's a more flexible design but also more complex.

The second modification depends mostly upon the PHP pages. However, it would make everything a bit simpler (I think) if the case for 1) the form's name, 2) the PHP file's name, and 3) the span's name & id... were consistent. For example: addFriend; addFriend.php; and addFriend... rather than: addfriend; addFriend.php; and addfriend. An include common to all PHP files of this type could take the name of the requested script and deduce the span's name & id from it.

bslashdash
08-09-2008, 06:52 AM
Thanks again for your reply and I appreciate your help but being a total newbie to javascript and ajax what you have said means nothing to me lol.

I don't think the php script has anything to do with where the data is output I've pasted the code from my addFriend.php script below.


<?php
include 'config.php';
include 'opendb.php';

// Check to see if this user has already made a friend request with you
$check = mysql_query("SELECT * FROM `phpizabi_friends`
WHERE `userid` = '{$_POST["friendID"]}'
AND `friendid` = '{$_POST["userID"]}'
AND `accepted` = 'No'");

$num_rows = mysql_num_rows($check);
// If there is a pending friend request from this user set accepted to yes and create a new connection between you and them
if ($num_rows > 0)
{
mysql_query("UPDATE `phpizabi_friends` SET accepted = 'Yes'
WHERE `userid` = '{$_POST["friendID"]}'
AND `friendid` = '{$_POST["userID"]}'");

mysql_query("INSERT INTO `phpizabi_friends`

( `userid`,`friendid`,`accepted`) VALUES ('{$_POST["userID"]}','{$_POST["friendID"]}','Yes') ");
echo "You are now friends with this user";

}
// If not then lets generate a new friend request
else {

mysql_query("
INSERT INTO `phpizabi_friends`

( `userid`,
`friendid`,
`accepted`

)

VALUES

(

'{$_POST["userID"]}',
'{$_POST["friendID"]}',

'No'

)

");
echo "Friend request sent";
}

include 'closedb.php';
?>

Where the data is output seems to be controlled by the javascript see this part of the code...


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

As to the first modifcation I have no idea how to do what you have said to do.

Jesdisciple
08-09-2008, 09:38 AM
Oops, you're right. I was thinking of a normal form, where the PHP would control the response's layout.

As I thought about it, I realized that you actually need 2 copies of everything involved. Your script wasn't built for that, although it 'should' have been according to convention. I've rearranged it so it now works
with any number of forms and inputs,
with minimal extra effort (compared to a normal form) on the designer's part, and
in a degradable way, so browsers without JS will still submit the form as normal.


Note that your PHP needs to do something special for the last point to be true. I added an extra value, 'ajax=true', to the request string, so...
if(isset($_POST['ajax']) && $_POST['ajax'] == 'true'){
//Only output the data.
}else{
//Output an entire page.
}

Note also that it's made to accept GET forms as well, but support for that isn't implemented. But that would be really simple, mostly copy-and-paste.

<html>
<head>
<title>Titled Document</title>
<script type="text/javascript" language="javascript"><!--
function AjaxForm(form, display){
var that = this;
this.form = typeof form == 'string' ? document.forms[form] : form;
this.form.onsubmit = function (){
that[that.form.method.toLowerCase()]();
return false;
};
this.display = typeof form == 'string' ? document.getElementById(display) : display;
}
AjaxForm.prototype = {
request: null,
post: function(){
var that = this;
this.request = null;
var parameters = [];
for(var i = 0; i < this.form.elements.length; i++){
var element = this.form.elements[i];
parameters.push(element.name + '=' + element.value);
}
parameters.push('ajax=true');
if (window.XMLHttpRequest) { // Mozilla, Safari,...
this.request = new XMLHttpRequest();
if (this.request.overrideMimeType) {
// set type accordingly to anticipated content type
//http_request.overrideMimeType('text/xml');
this.request.overrideMimeType('text/html');
}
} else if (window.ActiveXObject) { // IE
try {
this.request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
this.request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!this.request) {
alert('Cannot create XMLHTTP instance');
return false;
}
this.request.onreadystatechange = function () {
if (that.request.readyState == 4) {
if (that.request.status == 200) {
var result = that.request.responseText;
//alert(result);
that.display.innerHTML = result;
} else {
alert('There was a problem with the request.');
}
}
};
parameters = parameters.join('&');
this.request.open('POST', this.form.action, true);
this.request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
this.request.setRequestHeader("Content-length", parameters.length);
this.request.setRequestHeader("Connection", "close");
this.request.send(parameters);
}
};
window.onload = function(){
var form = new AjaxForm('addfriend', 'addfriend');
var form = new AjaxForm('addfavourite', 'addfavourite');
};
//--></script>
</head>
<body>
<form action="addFriend.php" method="POST" name="addfriend" id="addfriend">
<input type="hidden" name="userID" id="userID" value="{me.id}">
<input type="hidden" name="friendID" id="friendID" value="{user.id}">
<input type="submit" name="submit" value="Add to friends" class="ajaxbutton">
</form>
<form action="addFavourite.php" method="POST" name="addfavourite" id="addfavourite">
<input type="hidden" name="userID" id="userID" value="{me.id}">
<input type="hidden" name="friendID" id="friendID" value="{user.id}">
<input type="submit" name="submit" value="Add to favorites" class="ajaxbutton">
</form>
</body>
</html>

bslashdash
08-09-2008, 01:48 PM
Hi, thanks again for your help.

I've copied and pasted your revised script exactly however on testing it it just returns the There was a problem with the request. alert.

Jesdisciple
08-09-2008, 05:52 PM
Change the action attributes of the forms to include your requests/ directory. The JS/AJAX is completely dependent on the conventional HTML form, and I didn't bother making a subdirectory of this item in my code library as I was developing it.

EDIT: And note that, when I said "that sould be really simple," I meant for whoever knows JS and decides to help you if you decide you need GET.