Earlier today I blogged a simple example of using ColdFusion Ajax controls to load detail information based on a primary key. The reader who asked the question sent me a followup asking if it was possible to change the form to use a button instead of a keypress to load the data.
Using the second code sample from my previous entry, I added a button next to the ID field.
<cfform>
id: <cfinput type="text" name="artid" id="artid"> <cfinput type="button" name="mybutton" value="Lookup"><br/>
name: <cfinput type="text" name="artname" id="artname" readonly="true"><br/>
description: <cftextarea name="description" id="description" readonly="true"></cftextarea><br/>
price: <cfinput type="text" name="price" id="price" readonly="true"><br/>
</cfform>
Now for the weird part. It's easy enough to bind to a button. I'd just use {mybutton@click}. However, I still need the ID value. So in order to bind to the CFC, I'd have to use:
<cfajaxproxy bind="cfc:test.getData({artid@none},{mybutton@click})" onsuccess="showData">
Unfortunately, this then requires that the getData method have a second argument. I could just add a dummy argument to the method, but that felt wrong. I decided to take another approach.
The cfajaxproxy tag allows you to bind to JavaScript functions as well. I switched my tag to the following:
<cfajaxproxy bind="javascript:getData({mybutton@click})">
Next, I knew I still needed a way to communicate to the CFC. I added another cfajaxproxy:
<cfajaxproxy cfc="test" jsclassname="dataproxy">
The next change was to add the getData function:
function getData() {
var artid = ColdFusion.getElementValue("artid")
if(isNaN(artid)) return
dataService.getData(artid)
}
I have to get the artid value manually so I made use of ColdFusion.getElmentValue. As before, I check for a valid number. Lastly I make use of dataService. What is that? I've added these two lines of JavaScript that make use of the new cfajaxproxy tag I added:
var dataService = new dataproxy()
dataService.setCallbackHandler(showData)
Basically, dataService becomes a proxy to my remote methods in the CFC. This is probably a bit confusing now so let me paste in the entire template:
<cfajaxproxy bind="javascript:getData({mybutton@click})">
<cfajaxproxy cfc="test" jsclassname="dataproxy">
<script>
function getData() {
var artid = ColdFusion.getElementValue("artid")
if(isNaN(artid)) return
dataService.getData(artid)
}
function showData(d) {
//convert into a struct
var data = {}
for(var i=0; i < d.COLUMNS.length; i++) {
data[d.COLUMNS[i]] = d.DATA[0][i]
}
document.getElementById('artname').value = data["ARTNAME"]
document.getElementById('description').value = data["DESCRIPTION"]
document.getElementById('price').value = data["PRICE"]
}
var dataService = new dataproxy()
dataService.setCallbackHandler(showData)
</script>
<cfform>
id: <cfinput type="text" name="artid" id="artid"> <cfinput type="button" name="mybutton" value="Lookup"><br/>
name: <cfinput type="text" name="artname" id="artname" readonly="true"><br/>
description: <cftextarea name="description" id="description" readonly="true"></cftextarea><br/>
price: <cfinput type="text" name="price" id="price" readonly="true"><br/>
</cfform>
I hope this helps and shows yet another variation on the theme from earlier today.