...

Can't POST data from form elements loaded thru AJAX?

djmonkey1
06-03-2007, 03:37 PM
I'm working on a form where, in certain situations, data has to be submitted to the PHP side for calculations, then new data is displayed to the user.

The crux of my problem seems to be that once the new data is displayed, apparently it's no longer part of the form.

For instance if I had the array

1=2
3=4
5=6
7=8

and I submit the data in the form, then regenerate a portion of the array so that what the PHP now retrieves from the database and is displayed via AJAX now says

1=2
3=4
x=y
7=8

where the x=y portion is what has been changed via AJAX. But now if I submit the form, either thru AJAX or through somthing simple like this.form.submit(), the x=y portion isn't part of the POST array. I can print_r the whole POST array using PHP and after one or multiple AJAX calls have been made on the form, whatever data is loaded through AJAX apparently isn't POSTable.

So, why not? Do I have to do something special to retrieve the new data?

I'm using this function to retrieve the data in the first place: function obtainTotals(data) { //this is used for processing/updating order totals

// Set up data variable
var formdata = "";

// Loop through form fields
for (i=0; i < data.length; i++)
{

formdata = formdata + data.elements[i].name + "=" + escape(data.elements[i].value) + "&";

}

makePOSTRequest('filename', formdata, 'totals');
}//end function obtainTotals(obj) {

(on a side note, this function pulls all the data from the form, which I don't actually need, but I'll work on that later)

This function works fine on a fresh page- it gets all the data and passes it on thru makePOSTRequest where it does a little magic, gets passed through a PHP file, and comes back to me. But, as I've described, only on a fresh page.

djmonkey1
06-03-2007, 04:16 PM
Forgot to mention: the variable data that is submitted to the function obtainTotals is "this.form". So is there something that would work with the AJAX generated data such as "this.document" or "this.page"?

djmonkey1
06-03-2007, 07:45 PM
I've played with this a bit and set data = document.all. When I do that I get the error "data.elements has no properties" which is interesting as I take that to mean that both data and data.length do have properties. Unfortunately I don't know what to do with this information.

djmonkey1
06-03-2007, 08:06 PM
So I stuck with document.all and removed 'elements' from my function:

function obtainTotals(data) { //this is used for processing/updating order totals

// Set up data variable
var formdata = "";

// Loop through form fields
for (i=0; i < data.length; i++)
{

formdata = formdata + data[i].name + "=" + escape(data[i].value) + "&";

}

makePOSTRequest('filename', formdata, 'totals');
}//end function obtainTotals(obj) {

And.... it works the same way. The AJAX generated data doesn't show up in the $_POST array (or $_GET or $_SESSION for that matter).

djmonkey1
06-05-2007, 01:02 AM
So there's no way to POST data from form elements that were loaded into the browser using AJAX?

glenngv
06-05-2007, 05:37 PM
How did you add the fields to the form? Do you have the page online?

djmonkey1
06-05-2007, 07:21 PM
The fields are all part of the form in the first place.

The form itself is part of the backend of an e-commerce site; if the shop admin were to do something like change where the order is shipping to, the order currency, etc, this would require that the order totals and shipping quotes be regenerated using the newly submitted info and reloaded into the page.

I suppose this is why it's tricky; portions of the form are dependent on other parts of the form, but regardless of what has been regenerated/reloaded the whole document should still function as a single form.

glenngv
06-05-2007, 08:40 PM
Related codes would be helpful. If you add the fields correctly then your for-loop would be ok.

djmonkey1
06-06-2007, 01:41 AM
Here is the code for the zip code box:

<input name="update_delivery_postcode" size="5" value="91932" onChange="updateShippingZone('delivery_postcode', encodeURIComponent(this.value), this.form)">

So if a change is made to the zip updateShippingZone is called:function updateShippingZone(field, value, data) {

updateOrdersField(field, value);

if (confirm('You have changed some shipping information. Would you like to recalculate the order totals?')) {

obtainTotals(data);

}

}//end function updateShippingZone(field, value) {

I'm going to skip updateOrdersField for now. obtainTotals we have already seen, this is where the data is looped: function obtainTotals(data) { //this is used for processing/updating order totals

// Set up data variable
var formdata = "";

// Loop through form fields
for (i=0; i < data.length; i++)
{
//Build Send String
formdata = formdata + data.elements[i].name + "=" + escape(data.elements[i].value) + "&";

}
makePOSTRequest('filename', formdata, 'totals');
}//end function obtainTotals(obj) {

Then we go to makePOSTRequest and alertTotals or alertComments (I'm going to condense some of these functions down once I get this functioning properly): var http_request = false;
function makePOSTRequest(url, parameters, div) {
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;
}

if (div == 'comments') {http_request.onreadystatechange = alertComments;}
if (div == 'totals') {http_request.onreadystatechange = alertTotals;}
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 alertComments() {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
//alert(http_request.responseText);
document.getElementById("commentsBlock").innerHTML = http_request.responseText;

} else {
alert('There was a problem with the request.');
}
}
}


function alertTotals() {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
//alert(http_request.responseText);
document.getElementById("totalsBlock").innerHTML = http_request.responseText;

} else {
alert('There was a problem with the request.');
}
}
}

At this point the data from filename is loaded into the browser in the appropriate place. I've compared HTML from the original and regenerated data and have found no differences in structure or content.

glenngv
06-06-2007, 09:08 PM
Is totalsBlock inside the form tag? Can you post a sample of the generated form field tags returned by responseText?

But why not just generate the values of the totals excluding the field tags? Something like this.

100.00|5.00|110.00

And then just split it to get each total and update the corresponding field.

var totals = http_request.responseText.split("|");
if (totals.length==3){ //change 3 to number of totals you are expecting
//update the corresponding fields
var frm=document.formNameHere;
frm.whateverField1.value = totals[0];
frm.whateverField2.value = totals[1];
frm.whateverField3.value = totals[2];
}

djmonkey1
06-07-2007, 02:01 AM
Is totalsBlock inside the form tag? Yes.

Can you post a sample of the generated form field tags returned by responseText? <tr class="dataTableRow">
<td class="dataTableContent" height="15" valign="middle"><span id="update_totals[2]"><a href="javascript:setCustomOTVisibility('update_totals[3]', 'visible', 'update_totals[2]');"><img src="images/plus.gif" alt="Insert new custom order total after this one" title=" Insert new custom order total after this one " border="0"></a></span></td>
<td class="dataTableContent" align="right"><input name="update_totals[2][title]" value="Tax:" readonly="readonly"></td>

<td class="dataTableContent" align="right" nowrap="nowrap">$166.51<input name="update_totals[2][value]" value="166.51" type="hidden"><input name="update_totals[2][class]" value="ot_tax" type="hidden"></td>
</tr>

But why not just generate the values of the totals excluding the field tags? Something like this.

100.00|5.00|110.00

And then just split it to get each total and update the corresponding field.

var totals = http_request.responseText.split("|");
if (totals.length==3){ //change 3 to number of totals you are expecting
//update the corresponding fields
var frm=document.formNameHere;
frm.whateverField1.value = totals[0];
frm.whateverField2.value = totals[1];
frm.whateverField3.value = totals[2];
}

The number of totals fields is variable and can change every time data is submitted from the form.

Couldn't I use a regular expression to pull just the update_totals array from the form? That was what I originally tried to do, but couldn't get it to work. For example if I had something like var data = document.getElementsByName(updateTotals); and var updateTotals = /^update_totals/;

glenngv
06-07-2007, 05:55 PM
What element is totalsBlock? Since you are inserting table rows in it, totalsBlock should be <tbody> and not <table>.
<table>
<tbody id="totalsBlock">

</tbody>
</table>
And when you are looping through the fields to build the form data, you need also to escape the field name because you have special characters (e.g. update_totals[2][title]) in it.

djmonkey1
06-08-2007, 03:15 AM
I'm not going to be able to work on this for 11 days or so, but I'll be back...

Thanks for the help so far.

djmonkey1
06-20-2007, 12:35 AM
What element is totalsBlock? Since you are inserting table rows in it, totalsBlock should be <tbody> and not <table>.
<table>
<tbody id="totalsBlock">

</tbody>
</table>
And when you are looping through the fields to build the form data, you need also to escape the field name because you have special characters (e.g. update_totals[2][title]) in it.

Ok, I have done both these things and am still getting the same result. So far all of my testing has been done in Firefox; today I tried to use IE7 and found that the code to regenerate the form components doesn't work at all; it fails and generates the error "Unknown runtime error".

glenngv
06-20-2007, 12:52 AM
Do you have the page online?

djmonkey1
06-20-2007, 01:01 AM
Do you have the page online?

Yes- can I pm you a link to it?

glenngv
06-20-2007, 01:04 AM
Why not post it here?

djmonkey1
06-20-2007, 01:07 AM
It's the backend of my sandbox e-commerce site and I'd rather not have God-knows-who monkeying with it. :)

djmonkey1
07-07-2007, 03:19 PM
Rather than trying to generate data within the <tbody> element, I put the entire block of code inside a <div> and reloaded the div. It seems to be working fine now.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum