Ask a Jedi: AjaxProxy example

Mike asks:

I'm trying to do someting i think may be simple, but its method is eluding me. I want to get to grips with using the cfajaxproxy tag to allow me to have a cfselect that when selecting values will auto populate some information into other fields, having pulled the info from the db.

I’ve blogged about cfajaxproxy before and it’s truly one of the most amazing tags ever added to the language. I quickly built up an example of what I think Mike was talking about. I first started with related selects that spoke to the cfartgallery demo datasource. I started with this since Forta had already written the code. ;) Here is what I began with:

<cfform name="main"> <b>Media:</b> <cfselect bind="cfc:art.getMedia()" bindonload="true" value="mediaid" display="mediatype" name="media" /> <b>Art:</b> <cfselect bind="cfc:art.getArt({media})" bindonload="true" value="artid" display="artname" name="art" />

Nothing too complex here. You select media and you get art populated in the second drop down. Now this is where I want to demonstrate the use of cfajaxproxy. I added a few form fields and other content:

<p> <b>Description:</b> <cftextarea name="desc" id="desc" /><br> <b>Price:</b> <cfinput name="price" id="price" /><br> <span id="img"></span> </cfform>

I have 3 areas now. The first two, description and price, I want to populate with the description and price of the art. The span, img, will be populated with the art image.

The first thing I want to do is bind to the art drop down. This will let me say, “When the art drop down changes, do something.”

<cfajaxproxy bind="cfc:art.getArtDetail({art.value})" onSuccess="showDetail">

In this example, I’ve bound to the Art drop down, and I’ve called a CFC (the same CFC as before) to get more information about the art piece. I’ve then told the tag to run showDetail when done. That JavaScript function is rather trivial:

<script> function showDetail(r) { document.getElementById("desc").value = r.DESCRIPTION; document.getElementById("price").value = r.PRICE; var newbod = "<img src='http://localhost/cfdocs/images/artgallery/" + r.LARGEIMAGE + "'>"; document.getElementById("img").innerHTML = newbod; } </script>

Since my CFC method returns a struct, I can treat it in JavaScript pretty much the same way I treat it in ColdFusion.

Here is the complete CFC code:

<cfcomponent output="false">

<cfset variables.dsn=”cfartgallery”>

<!— Get array of media types —> <cffunction name=”getMedia” access=”remote” returnType=”query”> <!— Define variables —> <cfset var data=”“>

 &lt;!--- Get data ---&gt;
 &lt;cfquery name="data" datasource="#variables.dsn#"&gt;
 SELECT mediaid, mediatype
 FROM media
 ORDER BY mediatype

 &lt;!--- And return it ---&gt;
 &lt;cfreturn data&gt;   &lt;/cffunction&gt;

<!— Get art by media type —> <cffunction name=”getArt” access=”remote” returnType=”query”> <cfargument name=”mediaid” type=”numeric” required=”true”>

 &lt;!--- Define variables ---&gt;
 &lt;cfset var data=""&gt;

 &lt;!--- Get data ---&gt;
 &lt;cfquery name="data" datasource="#variables.dsn#"&gt;
 SELECT artid, artname
 FROM art
 WHERE mediaid = &lt;cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.mediaid#"&gt;
 ORDER BY artname

 &lt;!--- And return it ---&gt;
 &lt;cfreturn data&gt;   &lt;/cffunction&gt;

<cffunction name=”getArtDetail” access=”remote” returnType=”struct”> <cfargument name=”artid” type=”numeric” required=”true”> <cfset var data=”“> <cfset var c = ““> <cfset var s = structNew()>

 &lt;!--- Get data ---&gt;
 &lt;cfquery name="data" datasource="#variables.dsn#"&gt;
 FROM art
 WHERE artid = &lt;cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.artid#"&gt;

 &lt;cfloop list="#data.columnlist#" index="c"&gt;
	 &lt;cfset s[c] = data[c][1]&gt;
 &lt;!--- And return it ---&gt;
 &lt;cfreturn s&gt;   &lt;/cffunction&gt;

</cfcomponent> </code>

There isn’t anything really complex here. Now here is the complete test document I used:

<cfajaxproxy bind="cfc:art.getArtDetail({art.value})" onSuccess="showDetail">

<script> function showDetail(r) { document.getElementById(“desc”).value = r.DESCRIPTION; document.getElementById(“price”).value = r.PRICE; var newbod = “<img src=’http://localhost/cfdocs/images/artgallery/” + r.LARGEIMAGE + “‘>”; document.getElementById(“img”).innerHTML = newbod; } </script>

<cfform name=”main”> <b>Media:</b> <cfselect bind=”cfc:art.getMedia()” bindonload=”true” value=”mediaid” display=”mediatype” name=”media” /> <b>Art:</b> <cfselect bind=”cfc:art.getArt({media})” bindonload=”true” value=”artid” display=”artname” name=”art” /> <p> <b>Description:</b> <cftextarea name=”desc” id=”desc” /><br> <b>Price:</b> <cfinput name=”price” id=”price” /><br> <span id=”img”></span>

</cfform> </code>

Pay special attention to how simple the code is here. The only JavaScript isn’t really that complex.

I hope this example helps.

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA