ColdFusioning: Pronunciation \kold-fy�-zhn-ing\ Noun: The action of one that writes ColdFusion.

ColdFusion and jQuery - Using AJAX to Call a CFC and Return JSON

I recently had a friend ask me about using jQuery to call a ColdFusion CFC via AJAX and return a value. It is actually quite easy and fun to do. It requires two files to be created. The two filenames I'm using for this example are: index.cfm and myCFC.cfc but you could easily use your own filenames.

The first file we're going to start out with is index.cfm:


<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
chkUsernameUnique = function(theUsername){
    $.getJSON("/assets/cfc/myCFC.cfc", {
        method: 'chkUsername',
        Username: theUsername,
        returnformat: 'json'
    }, function(isUsernameUnique){
    
        if (isUsernameUnique == true) {
            $("#theErrorDivID").html('Username is unique');
        }
        else {
            $("#theErrorDivID").html('Please select a new username');
        }
    });
};
</script>

<div id="theErrorDivID"></div>
<input type="text" name="username" id="username" onchange="chkUsernameUnique(this.value);" />

If you read through the code, it is self explanatory. We first include the jQuery library from the Google CDN (you could always point this at your web server if you are going to host the file instead). In the next set of lines, we create a function, setup our AJAX, specify the CFC (you can change the cfc path to match your web server), method and some variables. We then specify the return function to run once the data is returned from our cfc. Based on the data returned, we display a message to the user. The final lines outside the script tag are the DIV for displaying the message and the input.

The next set of code is the cfc we call (myCFC.cfc):


<cfcomponent>
<cffunction name="chkUsername" access="remote" returnformat="json" output="false">
        <cfargument name="Username" required="true">
            
        <cfquery name="chkUsername" datasource="YOURDATASOURCEHERE">
        SELECT ID FROM tb_user WHERE user_login = <cfqueryparam value="#arguments.Username#" cfsqltype="cf_sql_varchar" />
        </cfquery>
        
        <cfreturn yesNoFormat(chkUsername.recordCount) / />
    </cffunction>
</cfcomponent>

This set of code queries the database to check if the username is unique and returns true or false based on that result. This example could quickly be expanded to check for other variables or perform additional functions. If you are new to jQuery, I highly recommend you check it out and dive right into it. If you are looking for a book to learn jQuery, I recommend: Learning jQuery 1.3. It is a great book and walks you through step-by-step to teach you the library.



Comments
Muscle Might's Gravatar Really a educative and informative post, the post is good in all regards,I am glad to read this post
# Posted By Muscle Might | 10/29/09 3:56 AM
AD's Gravatar The recordcount for the query will always be 1 - if you use SELECT COUNT(*)....
# Posted By AD | 10/29/09 9:54 AM
James Brown's Gravatar If the "WHERE user_login =" didn't match the username that was passed to the CFC, the recordcount wouldn't be 1. It would be 0. This is a test to see if a username is unique or not.
# Posted By James Brown | 10/29/09 9:58 AM
AD's Gravatar If the where does not match the recordcount is still 1. The actual count is 0, but qryname.recordcount is still 1...I think
# Posted By AD | 10/29/09 10:18 AM
todd sharp's Gravatar Great demo! I'd suggest a few improvements to your function.

First - and most importantly, you should make sure that you var scope 'chkUsername'.

2 - I'd avoid touching the request scope within a cfc. Just stick to local variables.

3 - You could cut a few lines out by just doing this:

<cfreturn yesNoFormat(chkUsername.recordCount) />

Since any non zero value will return true and zero would return false.
# Posted By todd sharp | 10/29/09 11:11 AM
todd sharp's Gravatar Oh - and - i've heard that count(1) is more performant then count(*), but I don't have proof of that :)
# Posted By todd sharp | 10/29/09 11:12 AM
Andreas Schuldhaus's Gravatar I'm afraid checking for the recordcount would fail. As stated by AD. You could do a

SELECT count(*) as usercount where user_login = ...

and check if chkUsername.usercount eq 0, or do a

SELECT ID where user_login = ... (if ID is applicable)

and check for chkUsername.RecordCount

If there is no match, count(*) would be 0, thus returning 1 row with that info.
# Posted By Andreas Schuldhaus | 10/29/09 12:01 PM
James Brown's Gravatar Thanks everybody for the suggestions. I updated the cfc and it should be set now. I love the CF community!
# Posted By James Brown | 10/29/09 7:55 PM
Muscle Might's Gravatar Thanks for updating the cfs. This is an amazing tutorial, will definitely be helpful!
# Posted By Muscle Might | 11/14/09 7:52 AM
Alexa Dagostino's Gravatar This didn't work for me at all. I attempted to test the script and for some reason it didn't work at all. Any ideas why?
# Posted By Alexa Dagostino | 11/18/09 6:06 PM
James Brown's Gravatar Alexa,
If you want to email me your code, I'll take a look.

james at gulftobaytech dot com
# Posted By James Brown | 12/28/09 12:31 PM
Monique's Gravatar All of the code works for me up to displaying the message to the user. Not sure what is wrong...

Here is my code:

jquery

chkUsernameUnique = function(theUsername){
$.getJSON("cfc/beauty.cfc", {
method: 'chkUsername',
userName: theUsername,
returnformat: 'json'
}, function(isUsernameUnique){

if (isUsernameUnique == true) {
$("#theErrorDivID").html('Username is unique');
}
else {
$("#theErrorDivID").html('Please select a new username');
}
});
};


form field

<div id="theErrorDivID"></div><cfinput type="text" name="username" value="#form.username#" onchange="chkUsernameUnique(this.value);" class="required" id="username">


CFC

<cffunction name="chkUsername" access="remote" returnformat="json">
<cfargument name="userName" type="string" required="true">
<cfquery datasource="beauty" name="chkUsername">
select userName from contestants where userName = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.userName#">
</cfquery>
<cfreturn yesNoFormat(chkUsername.recordCount) />
</cffunction>
# Posted By Monique | 3/31/10 12:23 AM
Andreas Schuldhaus's Gravatar @ monique

The problem seems to exist in your callback function. replace your parameter "isUsernameUniqe" with "data" which represents what you get back from getJSON call.

This worked (at least for me - you only have to strip out the debugging alerts()) :

   chkUsernameUnique = function(theUsername){
    $.getJSON("cfc/beauty.cfc", {
    method: 'chkUsername',
    Username: theUsername,
    returnformat: 'json'
    }, function(data){
         alert(data);
         if (data == false) {
    $("#theErrorDivID").html('Username is unique');
            alert("Username is unique");
    }
    else {
    $("#theErrorDivID").html('Username exists - please select another');
            alert("Username exists!");
    }
    });
   };

Since your beauty.cfc doesn't return a complex datatype, all you receive is a simple string and not JSON Format.
# Posted By Andreas Schuldhaus | 3/31/10 6:50 AM
Monique's Gravatar The call and response works well. It's the displaying of the message that isn't working.

I added your version and still don't get the alerts.
# Posted By Monique | 3/31/10 7:27 AM
Andreas Schuldhaus's Gravatar @monique hmmm sounds odd. Any typos? Casesensitive issues? I set up a short demo here: http://www.atginfotech.com/ajaxtest/ Maybe you want to take a look. No problem here, filling the div with appropriate text
# Posted By Andreas Schuldhaus | 3/31/10 7:57 AM
Andreas Schuldhaus's Gravatar Just found out, that my online example works well in Firefox and Safari, but fails in IE 8 and Opera :-(
# Posted By Andreas Schuldhaus | 3/31/10 8:07 AM
Clay's Gravatar I am trying this and it does not seem to be working. Here is my cfc code...

<cfcomponent>
<cffunction name="chkUsername" access="remote" returnformat="json" output="false">
<cfargument name="Username" required="true">

<cfquery name="chkUsername" datasource="resumeimages">
SELECT id FROM customer WHERE username = <cfqueryparam value="#arguments.Username#" cfsqltype="cf_sql_varchar" />
</cfquery>

<cfreturn yesNoFormat(chkUsername.recordCount) />
</cffunction>
</cfcomponent>

Here is my cfm page code...

<script type="text/javascript">
chkUsernameUnique = function(theUsername){
$.getJSON("cfc/chkuser.cfc", {
method: 'chkUsername',
Username: theUsername,
returnformat: 'json'
}, function(data){
alert(data);
if (data == false) {
$("#theErrorDivID").html('Username is unique');
alert("Username is unique");
}
else {
$("#theErrorDivID").html('Username exists - please select another');
alert("Username exists!");
}
});
};</script>

And my form element...

<div id="theErrorDivID"></div><cfinput type="text" name="username" id="username" value="" size="32" onChange="chkUsernameUnique(this.value);" />

Thoughts?
# Posted By Clay | 5/5/10 3:03 AM
James Brown's Gravatar yesNoFormat literally returns the string "Yes" or "No". Try returning "true" or "false" and see if that works.
# Posted By James Brown | 5/5/10 10:30 AM