Simple example of a Form post to ColdFusion with jQuery
Following up on my earlier post demonstrating loading ColdFusion query data via jQuery, I've decided to do a few more simple jQuery+ColdFusion examples to give folks a taste of how easy it is to work with them both at the same time. For today's entry I'm going to show a very simple form post. This is as about as trivial as you can get, but I'm going to follow it up the next few days with a few more examples that will build upon it. So with that in mind, let's take a quick look at the code.
First I'll show the form. Notice that for this example I will not be doing any form validation. I want to keep things as nice and simple as possible.
2 Name: <input type="text" name="name"><br/>
3 Email: <input type="text" name="email"><br/>
4 Gender:
5 <select name="gender">
6 <option value="M">Male</option>
7 <option value="F">Female</option>
8 </select><br/>
9 <input type="submit" value="Save" />
10</form>
The form contains 3 fields: name, email, and gender. Notice I did not supply an action for the form. I'm going to let jQuery do everything. Now for the JavaScript.
2<script>
3$(document).ready(function() {
4 $("#testForm").submit(sendForm)
5});
6
7function sendForm() {
8 $.post('post.cfm',$("#testForm").serialize(),function(data,status){
9 $("#result").html(data)
10 });
11 return false
12}
13
14</script>
The first block of code simply says: When the page loads, I want you to bind the submit action of the form caleld testForm to a function called sendForm. This basically takes over the submit action. sendForm is a grand total of two lines. jQuery provides multiple ways to do Ajax calls. I'm using post for this example. The post function lets me specify a URL, some data, and a callback function. If callback functions confuse you (they were for me at first), just think of it as me telling jQuery: "Hey pal, when you are done sending the data, please run this function with the result."
How do I get the data? In the old days I might have used document.getElementById() on all the form fields. Luckily jQuery provides not one but two functions to handle this task for me. I can use serializeAray() to turn a form into a javaScript object. It will go throughout all the fields and create a name/value pair. It will be smart enough to know what to do for textfields, checkboxes, drop downs, you name it. An alternative to this is the serialize() function. This creates a string (think query string) version of the form data. The post() function will use either of these.
My callback function simply takes the result, trims it (don't forget how much ColdFusion likes whitespace!), and displays it within a div.
The ColdFusion side isn't doing much here. Let's take a look:
2<cfparam name="form.email" default="">
3<cfparam name="form.gender" default="">
4
5<cfoutput>
6Thanks for writing,
7<cfif form.gender is "m">Mr<cfelse>Ms</cfif> #form.name#.
8I've sent a subscription email to #form.email#.
9</cfoutput>
I do some basic validation on top and then simply output the result. I mention sending a subscription email, but don't really do it. (How many people think quite a few web apps lie like this?)
You can demo this here: http://www.coldfusionjedi.com/demos/jqform/test2.html
Ok, so pretty simple, but there are some things to think about it.
First, if I just wanted to load the result of posting the form into the div, I could have used the jQuery load function instead. I wanted to show a bit more... control over the process, so I used post() instead. I've said this before, but please remember - like ColdFusion, jQuery almost always provides more than one way to do somrthing.
Second, my form does zero error handling. Since I'm just dumping the result in a div, I could have done error handling in ColdFusion. What about errors in general? You can see I have access to a status variable. But as the docs say, this always returns true. This seems like a bug in jQuery, and it seems like it should be something simple to fix, so I'm assuming the issue is a bit more complex. In my testing, when I forced an error in the ColdFusion side, I still got 'success' for a status.
Third, just showing a message as the result is the simplest way to handle the result of the post. I could have also hidden the form. I could have done anything number of things really. What's nice though is how jQuery makes it easy to package up and wrap the logic all within a few lines. jQuery FTW!
Lastly, I mentioned I was going to skip client side validation in this post. I skipped it not because it was difficult, but because I wanted to create a simple example. I wrote a few blog entries on the topic and you should definitely check it out. (An introduction to jQuery and Form Validation)
As always, comments from the jQuery experts are welcome (well, any comments are welcome). My general plan for followups to this entry include: jQuery and a Login Form demo. jQuery and a Search Form demo. jQuery and a CAPTCHA demo where you can reload the CAPTCHA.

~Todd
You kind of touched on it a bit in your post but I'm still confused as to what seasoned jQuery developers are using in comparison to CF's setErrorHandler and setCallbackHandler functions. I totally see where you're building the callback into the one line submitter but how would this work if we were doing something more advanced than a form submit. For instance, calling a function that lives in a cfc to check for the existence of a conflicting primary key before we decided to even do the form submit.
Thanks for posting this, I may soon step outside of my comfort zone with CF's Ajax set and learn jQuery. I haven't been convinced yet and the jQuery team may have to call me and sing "If you don't know me by now" before I'll climb aboard.
@Andy: So as I said, you can't really handle the error with .post. You _always_ get success back. You could return data that means something. By that I mean, instead of just a string like I did, I could have returned 0, which would mean 'bad', or 1, which would mean 'good'. Using the ajax() method gives you more fine grained control.
I'm still learning this stuff myself, so please keep that in mind. I'm not the expert here. ;)
* form ( http://www.malsup.com/jquery/form/ )
* metadata ( http://plugins.jquery.com/project/metadata )
* validate (you discussed previously - http://docs.jquery.com/Plugins/Validation)
* uiblock ( http://www.malsup.com/jquery/block/ )
That's about it. None of my project begin without me copying these base plug-ins and putting them in place.
You could also return a json object that has a success flag (0/1 or T/F), a message string, and the form values.
I am using CFAJAXPROXY to bind to a CFC like this:
<cfajaxproxy cfc="aqs3.contacts" jsclassname="CM">
Now, what I would like to do is access different methods of this CFC with information from several forms on the page. I know I can use the XXX.SetForm("formname") syntax to bind ALL of the values on the form to the method using named attributes. But what if I only wanted to call a method with a few of the form values? I can use JQuery (or simple JS) to get the values I need, but I can;t find a way to pass them as named attributes.
Since the SetForm command seems to figure out a way to do this, it must be possible, but for the life of me I can;t figure out how.
Any ideas?
--Sean
For my web forms I've been using these guys:
http://www.formmailhosting.com
They do the form to email processing for me, but I like the example you came up with.
ERIC
<input type="text" name="title">
<input type="file" name="uploadfile">
Any advice? Thanks
@Travis: You can't do file uploads via Ajax. Period. You can only do it with iframe type hacks (which, for all intents and purposes ends up looking like normal Ajax). Please search my blog as I did an entry on this a few months ago.
I would like to add error checking to a form that I've created using this method. I have placed the error checking on the page that holds the form code (index.cfm) and have the form results post to another page (consultationPost.cfm). However, no matter where I place the form validation code, it isn't processed and the form results simply post without being validated.
Do I need to use jquery validation in this instance or am I just doing something wrong.
Thanks for any help,
Adam
I've removed all error checking and have two forms. One is similar to your test2.html:
<cfoutput>
<cfform id="consultationForm">
<div id="consultations">
<!--- Our form submission flag. --->
<input type="hidden" name="submitted" value="1" />
<fieldset>
<legend>Consultations</legend>
<label for="client name">Client Username
<cfinput id="clientID"
name="clientID"
type="text"
value=""
maxlength="8"
<!---
onClick="ColdFusion.Window.show('userWin')"
bind="{clientLookup.client}"--->
/>
</label>
<label for="consultation date">Consultation Date
<input name="consultationDate" type="text" id="datepicker" />
</label>
<label for="consultation type">Consultation Type<br />
<select name="consultationType">
<option value="">– select –</option>
<option value="phone">Phone</option>
<option value="email">Email</option>
<option value="faceToFace">Face To Face</option>
<option value="online">Online</option>
</select>
</label>
<div class="clearer"></div>
<label for="Instructional Technology">Instructional Technology
<select id="instructionalTechnology" name="instructionalTechnology">
<option value="">– select –</option>
<option value="Oncourse">Oncourse</option>
<option value="Eportfolio">Eportfolio</option>
<option value="Web conferencing">Web conferencing</option>
<option value="Podcasting">Podcasting</option>
<option value="Video">Video</option>
<option value="Audio">Audio</option>
<option value="Turnitin">Turnitin</option>
<option value="Learning Objects">Learning Objects</option>
<option value="Web Development">Web Development</option>
<option value="Student Response Systems">Student Response Systems</option>
<option value="Collaborative web technology">Collaborative web technology</option>
<option value="Technology (other)">Technology (other)</option>
</select>
</label>
<label for="Instructional Design">Instructional Design
<select id="instructionalDesign" name="instructionalDesign">
<option value="">– select –</option>
<option value="Classroom Observations">Classroom Observations</option>
<option value="SGID">SGID</option>
<option value="Course Design">Course Design</option>
<option value="Syllabi">Syllabi</option>
<option value="Teaching Portfolio Development">Teaching Portfolio Development</option>
<option value="Assessment of Student Learning">Assessment of Student Learning</option>
<option value="SoTL ">SoTL</option>
<option value="Classroom Management Issues">Classroom Management Issues</option>
<option value="Academic Integrity">Academic Integrity</option>
<option value="Inclusive Teaching">Inclusive Teaching</option>
</select>
</label>
<div class="clearer"></div>
<label for="tags">Tags
<input id="tag1" name="tag1" type="text" maxlength="50" value="" tabindex="8"/>
<br />
<input id="tag2" name="tag2" type="text" maxlength="50" value="" tabindex="8"/>
<br />
<input id="tag3" name="tag3" type="text" maxlength="50" value="" tabindex="8"/>
<br />
<input id="tag4" name="tag4" type="text" maxlength="50" value="" tabindex="8"/>
</label>
<label for="internal notes">Internal Notes<br />
<textarea name="internalNotes" cols="20" rows="10" tabindex="7"></textarea>
</label>
<label for="notes to client">Notes to Client<br />
<textarea name="clientNotes" cols="20" rows="10" tabindex="9"></textarea>
</label>
<input type="hidden" value="#Now()#" />
<input class="submit"type="submit" value="Submit" /> <input class="reset" type="reset" value="Reset">
<div id="clearer"></div>
<div id="result"></div>
</fieldset>
</div>
</cfform>
My post.cfm is consultationPost.cfm and currently includes:
<cfoutput>
<cfquery name="qAddConsultation" datasource="myDSN">
INSERT INTO TEMPconsultations (submitDate,
transID,
weekOfYear,
username,
clientID,
consultationDate,
consultationType)
VALUES ('#DateFormat(now(), "mm/dd/yyyy")#',
'#transID#',
'#theWeek#',
'#trim(session.username)#',
'#trim(clientID)#',
'#trim(consultationDate)#',
'#trim(consultationType)#')
</cfquery>
<strong>Client</strong>: #form.clientID#<br />
<strong>Consultation Date</strong>: #form.consultationDate#<br />
<strong>Consultation Type</strong>: #form.consultationType#<br />
<strong>Instructional Technology</strong>: #form.instructionalTechnology#<br />
<strong>Instructional Design</strong>: #form.instructionalDesign#<br />
<strong>Tags</strong>: #form.tag1#, #form.tag2#, #form.tag3#, #form.tag4#<br />
<strong>Internal Notes</strong>: #form.internalNotes#<br />
<strong>Notes to Client</strong>: #form.clientNotes#
</cfoutput>
All works well until I include the query to write to the database.
I did not see an error window in Firefox and I'm not too familiar with the feature. This conversation tells me I need to.
Thank you.
<script src="/jquery/jquery-1.4.4.min.js"></script>
<form id="testForm">
<input type="hidden" name="formaction" id="formaction" value="noaction">
Name: <input type="text" name="name"><br/>
Email: <input type="text" name="email"><br/>
Gender:
<select name="gender">
<option value="M">Male</option>
<option value="F">Female</option>
</select><br/>
<input type="submit" value="Save" onClick="document.getElementById('formaction').value = 'saverecord';" />
<input type="submit" value="Delete" onClick="document.getElementById('formaction').value = 'deleterecord';" />
</form>
<script>
$(document).ready(function() {
$("#testForm").submit(sendForm)
});
function sendForm() {
$.post('testform.cfm',$("#testForm").serialize(),function(data,status){
$("#result").html(data)
});
return false
}
</script>
Thanks,
No more iframes! yay!
$.post('http://www.mysite/post.cfm', - does not work
$.post('post.cfm', - works
Why?
http://www.raymondcamden.com/index.cfm/2013/5/2/Re...
I assume you know how to use the Chrome console to help you debug this. :)
May 15 07:45:41 Phone-of-Ides kbd[50] <Warning>: -[TIXPCDataTransport _handleForPurpose:withReplyBlock:] couldn't get data source for purpose=__TIRDTAB
May 15 07:45:45 Phone-of-Ides kernel[0] <Debug>: launchd[13840] Builtin profile: PasteBoard (sandbox)
May 15 07:45:51 Phone-of-Ides TestApp[13838] <Warning>: Resetting plugins due to page load.
May 15 07:45:51 Phone-of-Ides TestApp[13838] <Warning>: ERROR whitelist rejection: url='http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/...'
May 15 07:45:51 Phone-of-Ides TestApp[13838] <Warning>: ERROR whitelist rejection: url='http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/...'
May 15 07:45:51 Phone-of-Ides TestApp[13838] <Warning>: ERROR whitelist rejection: url='http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/...'
May 15 07:45:51 Phone-of-Ides TestApp[13838] <Warning>: Finished load of: file:///var/mobile/Applications/DA9CE3B1-92AC-455B-BBB1-AB942F34F03C/TestApp.app/www/index.html?name=Test&email=Test@email.com&gender=M
Second comment. Ah, whitelist rejection. You need to add your domain to the whitelist.
http://docs.phonegap.com/en/2.7.0/guide_whitelist_...
The last line in the log happens because your Ajax portion failed and the form handler than returned to just submitting itself. Hence your app reloaded w/ form data. You can ignore that.
I've combined the post on this page and the other I just referenced to get my first phonegap build app up and running (albeit hello worldish). Thank you much. There are so many details and the documentation isn't the best on the Phonegap site. I may just need to put some help docs out there somewhere for beginners like myself. Anyway... cheers.
<div data-role="page" id="descriptions">
<div data-role="header">
<h1>Descriptions</h1>
</div>
<div data-role="content" data-theme="c">
Results here please
</div>
<div data-role="footer">
<h4>© MySite - 2013</h4>
</div>
</div>
So let's say I want the form post results to end up inside the descriptions div... how do I do that?