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:
<form>
number one: <input type="text" name="one" id="one"><br>
number two: <input type="text" name="two" id="two"><br>
</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:
<input type="button" value="Add" onClick="doAddPost()">
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.
function doAddPost() {
We need to know where we will be posting the form, so next I define the URL:
var url = "moon.cfm";
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:
var one = $("one").value;
Then I'll grab the value from the second form field:
var two = $("two").value;
The form post data must be sent like a query string: foo1=value1&foo2=value2. Again, I have to do this by hand:
var formData = 'one='+one+'&two='+two;
Next I encode any values in the string, like spaces or other special characters:
formData = encodeURI(formData);
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.
Spry.Utils.loadURL('POST', url, true, resFunc, {postData: formData, headers: {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}});
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:
function doAddPost() {
var url = "moon.cfm";
var one = $("one").value;
var two = $("two").value;
var formData = 'one='+one+'&two='+two;
formData = encodeURI(formData);
Spry.Utils.loadURL('POST', url, true, resFunc, {postData: formData, headers: {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-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:
<cfsetting enablecfoutputonly=true>
<cfparam name="form.one" default="0">
<cfparam name="form.two" default="0">
<cfif isNumeric(form.one) and isNumeric(form.two)>
<cfoutput>#form.one+form.two#</cfoutput>
<cfelse>
<cfoutput>0</cfoutput>
</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:
function resFunc(request) {
var result = request.xhRequest.responseText;
$("result").innerHTML = "Result was: " + result;
}
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:
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;
}
formData = encodeURI(formdata);
Spry.Utils.loadURL('POST', url, true, resfunc, {postData: formdata, headers: {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}});
}
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:
<input type="button" value="Add3" onClick="doFormPost('moon.cfm', 'one,two',resFunc)">
As I said though this is just a first draft. Right now it assumes just text fields.