Doing form Post in Spry (2)
Last week or so I blogged about doing form postings with Spry. I was asked to provide a bit more documentation so I thought I'd show a slightly more detailed example.
First lets start with a very simple form:
2number one: <input type="text" name="one" id="one"><br>
3number two: <input type="text" name="two" id="two"><br>
4</form>
This form has two simple text fields named one and two. I want to use Spry to send the values of these two fields to the server. First lets add a simple button:
This simply fires off a JavaScript function. I'm going to break the function up and explain each and every line to make it as clear as possible. First, start the function.
We need to know where we will be posting the form, so next I define the URL:
Now I need to grab the values I want to post. Normally with a submit button you don't have to worry about this. The browser simply sends all the form fields. In this case though I have to specify the fields manually. First I'll grab the value of the form field, one, using the Spry/Prototype $() shortcut:
Then I'll grab the value from the second form field:
The form post data must be sent like a query string: foo1=value1&foo2=value2. Again, I have to do this by hand:
Next I encode any values in the string, like spaces or other special characters:
So the last thing we do is run the Spry code that will handle the form post. I talked about this more in the last post so I won't spend a lot of time on it.
The first argument defines the type of request (GET or POST). The second argument is the URL value I defined earlier. The third argument defines if the call is asynchronous or not. The fourth argument defines a function to run with the result of the HTTP call. Lastly there is a structure of arguments that define the request. Again I have to thank Keith for figuring this out.
So here is the function again all in one code block:
2 var url = "moon.cfm";
3 var one = $("one").value;
4 var two = $("two").value;
5 var formData = 'one='+one+'&two='+two;
6 formData = encodeURI(formData);
7 Spry.Utils.loadURL('POST', url, true, resFunc, {postData: formData, headers: {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}});
8}
So how do we handle this server side? We have a few options. As I mentioned, the loadURL function lets you define code to run with the result. So whatever the server returned I can work with in JavaScript. This can be either a string or XML or WDDX. To make it easier I'll just return a simple string:
2<cfparam name="form.one" default="0">
3<cfparam name="form.two" default="0">
4
5<cfif isNumeric(form.one) and isNumeric(form.two)>
6 <cfoutput>#form.one+form.two#</cfoutput>
7<cfelse>
8 <cfoutput>0</cfoutput>
9</cfif>
Obviously there isn't anything too complex here, just the addition of two numbers. I take the result and simply output it directly to the client requesting the data. With me so far?
Now let's return to JavaScript and work with the result. I had specified the a function named resFunc would handle the result. The function is all of 4 lines:
2 var result = request.xhRequest.responseText;
3 $("result").innerHTML = "Result was: " + result;
4}
Spry automatically passes a collection of data back. The information I'm interested in resides in xhRequest.responseText. Once I have that, I can write out the result in the browser.
So I had mentioned more than once I wanted to make this process a bit simpler. Here is my first draft at it:
2 var formdata = '';
3 var formarray = formlist.split(',');
4 for(var i=0; i < formarray.length; i++) {
5 formdata+='&'+formarray[i]+'=';
6 var fValue = $(formarray[i]).value;
7 formdata+=fValue;
8 }
9 formData = encodeURI(formdata);
10 Spry.Utils.loadURL('POST', url, true, resfunc, {postData: formdata, headers: {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}});
11}
This lets you pass in a url and a list of form fields to post. The third argument is optional. So to do a Spry post you can do this instead of the button and custom function I had before:
As I said though this is just a first draft. Right now it assumes just text fields.

Anyway... nice stuff, Ray... between Spry and Flex2 my brain has been pretty stuffed the last few weeks. I HATE being behind the learning curve.
Thanks again Ray, you are a life saver. Before I try, will this pass multiple checked check boxes to coldfusion the normal way?
// delete images action function
function deleteImages() {
var url = "img-del.cfm";
var vaultImgFile = document.imgForm.vaultImgFile;
var formData = "vaultImgFile=";
for (i = 0; i < vaultImgFile.length; i++){
if (vaultImgFile[i].checked == true){
formData = formData + vaultImgFile[i].value + ",";
}//ends IF
}//ends FOR
// strip last comma
formData = formData.substr(0,formData.length-1);
// encode for spry
formData = encodeURI(formData);
Spry.Utils.loadURL('POST', url, true, delComplete, {postData: formData, headers: {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}});
}
function delComplete(request) {
var result = Spry.Utils.encodeEntities(request.xhRequest.responseText);
$("respContent").innerHTML = "Result was: " + result;
// reset status text area
setTimeout("clearVaultImageResults()",10000);
// reload image list
dsVaultImages.setURL("images.cfm?nocache="+d.getSeconds());
dsVaultImages.setXPath('images/image');
dsVaultImages.loadData();
}
Cheers.
Mark.
http://www.massimocorner.com/libraries/form/sample...
Hope it could help
Massimo
I can understand it all but for one part that will be obvious to anyone with a brain and knowledge of Java,
"Spry automatically passes a collection of data back. The information I'm interested in resides in xhRequest.responseText. Once I have that, I can write out the result in the browser."
HOW to I display the reasult?
I have it all working
see http://www.coolabah.com/spry/demos/gallery/test.cf... (underneath the large photo.
But how can I display the actual result????
Assume foo is the id of a div:
<div id="foo"></div>
Then in JS you can do:
var mydiv = document.getElementById("foo");
mydiv.innerHTML = "some stirng";
This will write out some string as the contents of the div.
On my page I have these functions as per your example
function doFormPost(url,formlist,resfunc) {
var formdata = '';
var formarray = formlist.split(',');
for(var i=0; i < formarray.length; i++) {
formdata+='&'+formarray[i]+'=';
var fValue = $(formarray[i]).value;
formdata+=fValue;
}
alert(formdata);
formData = encodeURI(formdata);
Spry.Utils.loadURL('POST', url, true, resfunc, {postData: formdata, headers: {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}});
}
function resFunc(request) {
var result = request.xhRequest.responseText;
$("result").innerHTML = "Result was: " + result;
}
doFormPost is called onclick.
Given THAT code, how do I display "result?
In the code snippet below I am trying to pass a value to Spry.Utils.loadURL that will them be passed to resfunc as request. But I cannot work out how to do this.
The function that calls Spry.Utils.loadURL works ok., I test that it is receiving the correct value by using alert(value). But how do I get this value into the argument list of Spry.Utils.loadURL so I can display it?
function doFormPost(url,photoId,resfunc) {
formData = encodeURI(photoId);
Spry.Utils.loadURL('POST', url, true, resfunc, {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"});
}
function resFunc(request) {
var mydiv = document.getElementById("foo");
var result = request.xhRequest.responseText;
$("result").innerHTML = "Result was: " + result ;
mydiv.innerHTML = result;
}
function HandleThumbnailClick(id, photoId)
{
StopSlideShow();
doFormPost('moon.cfm', photoId,resFunc);
dsPhotos.setCurrentRow(id);
ShowCurrentImage();
}
http://ray.camdenfamily.com/index.cfm/2007/1/29/Do...
but instead of passing a form variable, I'm trying to post an argument to the function .
I'm concerned with thew last argument -
{postData: formData, headers: {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}}
where I do not have "formdata", but a variable passed to the function.
name=value&name=value& etc
In function doFormPost(url,photoId,resfunc) {
formData = encodeURI(photoId);
Spry.Utils.loadURL('POST', url, true, resfunc, {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"});
}
How do I pass the contents of photoId
var formData = 'photoId='+photoId;
This says - pass the value photoId, but also give it a name of photoId. In your CFM code that processes this form post, you would use form.photoID.
Then you must encode the value:
formData = encodeURI(formData);
Lastly, you removed the part of loadURL that contained formData:
Spry.Utils.loadURL('POST', url, true, resFunc, {postData: formData, headers: {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}});
See how I pass formData as the value to postData?
I need to send post params.
I can send using this for example:
var dsPhotos = new Spry.Data.XMLDataSet("/photos.php", "/gallery/photos/photo", { method: "POST", postData: "galleryid=2000&offset=20&limit=10", headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" } });
Using post data it works,ok, or i can send using your example too, ok, it works.
But in my aplication a create a spry DataSet, and i dont trigger onload, i do that after a few actions.
So, i need to send a post params after i create the Dataset, because i use DataSet.loadData() after some time
But, your example should work, but i couldant populate a spry dataset with my xml result format
Could you help me??
Really sory, let´s try again
I need to send post params.
I can send using this for example:
var dsPhotos = new Spry.Data.XMLDataSet("/photos.php", "/gallery/photos/photo", { method: "POST", postData: "galleryid=2000&offset=20&limit=10", headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" } });
Using post data it works,ok, or i can send using your example too, ok, it works.
My problem is:
I dont know hot set Post Params, after define a spry DataSet
ex:
var myDs = new Spry.Data.XMLDataSet()
function triggerLater(){
myDs.setXPath("Node/ChildNode")
myDs.setURL(myxml.aspx?aLotOfParams=somevalue);
myDs.loadData()
}
those params ('aLotOfParams') must be POST, because they have a lot of info.
But in your example we heve that function:
function resFunc(request) {
var result = request.xhRequest.responseText;
$("result").innerHTML = "Result was: " + result;
}
than ok, i receive my xml, and i can see it, but i need to populate it in my spry data set
Somethink like:
function resFunc(request) {
var result = request.xhRequest.responseText;
mySpryDataSet=request
}
if you have time,could you help me?
there is the source: http://www.wl.com.br/spryXMLv2.zip
So, i have problems to parse my xml data, it works fine in firefox, but not in ie6, do you know why?
Another thing, i just could use it in Firefox when i removed all the white spaces from my XML, Is there some way to keep using spaces??
Thanks for your help!
I went ahead and modified the example slightly and incorporated Massimo's serializer with it. If anyone is interested in downloading the example, please go to:
http://blog.webexterminator.com/index.cfm/2007/12/...
Thanks again Ray and Massimo, you guys are the best!
http://www.massimocorner.com/spry/extractParamsFro...
On a side note, Prototype is affected by a similar bug. Actually, it's worst, since it returns different value for IE and FF. At least Spry is wrong, but consistent :-)
@MF - Did you report the bug?
Realizing that this is an OLD post, when I tried to implement I found that you may need to update this line:
First I'll grab the value of the form field, one, using the Spry/Prototype $() shortcut:
To:
First I'll grab the value of the form field, one, using the Spry Spry.$() shortcut:
The updated versions of the js files no longer support just $(), it is now Spry.$() - or atleast, by changing from $() to Spry.$() it worked