Posted in ColdFusion | Posted on 10-04-2007 | 7,790 views
A user pinged me during MAX (what's wrong with you guys, didn't I warn you about questions??!? ;) with a problem. He wanted to use a CFDIV tag that bound to a form. The problem was - he didn't want to actually do anything until the form was complete. He was using bindings, and everytime the form changed, the div reloaded, even though the form wasn't complete. There are two simple solutions to this.
First off - one simple solution is to build the source file, and by source file I mean what your CFDIV is pointing to - build it such that it recognizes an incomplete form and simply doesn't do anything. So consider this form:
2Name <input type="text" id="name" name="name"><br>
3Age <input type="text" id="age" name="age"><br>
4</form>
You could simply check to see if name and age have values before you output a response. But that doesn't technically answer his question. He wants the CFIDV to do nothing at all until the form is done.
So the second option is to just use a submit handler or a button to run a JavaScript function. This function can check the form - and when happy, use ColdFusion.navigate, or ColdFusion.Ajax.submitForm. I tend to prefer navigate, so here is an example.
2function checkForm() {
3 var name = document.getElementById("name").value;
4 var age = document.getElementById("age").value;
5 //Employ Mr. T error handling
6 if(name == '') { alert('Enter a name, fool!'); return false; }
7 if(age == '') { alert('I pity the fool who doesn\'t have an age!'); return false; }
8 ColdFusion.navigate('div.cfm?name='+escape(name)+'&age='+escape(age),'resultdiv');
9 return false;
10}
11</script>
12
13<form id="myform">
14Name <input type="text" id="name" name="name"><br>
15Age <input type="text" id="age" name="age"><br>
16<input type="button" value="Test" onClick="checkForm()">
17</form>
18
19<cfdiv id="resultdiv" style="background-color:##fff271" />
As a quick FYI, div.cfm simply dumped the URL scope, and the background color on the div was just me being fancy.


Attribute validation error for tag CFDIV.
The tag requires the attribute(s): BIND.
even though the BIND attribute is not mandatory
8,0,0,176276
I did but I had an error and had to reverse back to the original installation. I will try to re-install it and see if it fixes the issue.
I had to re-install CF8 and now my V is like yours :)
Thanks
Thank you!
For example. You may have a CFDIV you use as a generic container to display messages from various feeds by stuffing a variety of CFM files into a singular ID:
ColdFusion.navigate('/feedOne.cfm','divGeneric');
ColdFusion.navigate('/feedTwo.cfm','divGeneric');
ColdFusion.navigate('/feedTwo.cfm?mode=hoohah','divGeneric');
If you needed to refresh 'divGeneric' with whatever was last used... would you use something like this...?
ColdFusion.navigate(document.getElementById("divGeneric").value,'divGeneric');
My guess is no, since the DOM doesn't know what CFM file was used to create the current content.
Hmm... keep a variable in the SESSION scope?
It would be extremely handy if the CFDIV remembered what last went into it so we had a ColdFusion.navigate.(last,'divGeneric');
Here is my code:
From the form:
<cfinput type="Text" name="Username" style="width:125px;" maxlength="25" required="Yes" message="You Must Enter a User Name" onFocus="this.value='';"><cfdiv id="AvailabilityDiv" /><cfajaxproxy bind="javascript:loadDiv({Username})"></div>
cfc call:
<script>
function loadDiv(value) {
// Change the contents of the CFDIV
ColdFusion.navigate('live-checkuseravailability.cfc?method=getData&UserAvail='+ value, 'AvailabilityDiv');
}
</script>
And my CFC:
<cfcomponent>
<cffunction name="getData" returnType="string" access="remote">
<cfargument name="UserAvail" type="string" />
<cfquery name="chkUsername" datasource="#application.DSNName#">
SELECT *
FROM UserAvail
WHERE Username = '#UserAvail#'
</cfquery>
<cfif chkUsername.RecordCount GTE 1>
<cfreturn "Username Already exists">
<cfelse>
<cfreturn "Username available to register">
</cfif>
</cffunction>
</cfcomponent>
Any help would be greatly appreciated.
<cfreturn "<span class='green'>Username available</span>">
This assumes you have a class for green (and red, etc) in your template.
But when I do that line of code like this:
<cfreturn "<span class='green'>Username available to register"</span>>
I get this error:
Error retrieving markup for element AvailabilityDiv : Invalid CFML construct found on line 14 at column 95. [Enable debugging by adding 'cfdebug' to your URL parameters to see more information]
<span class='green'>Username available to register</span> in the div area, not the "Username available to register" in green
ColdFusion.navigate('live-checkuseravailability.cfc?method=getData&UserAvail='+ value, 'AvailabilityDiv');
to
ColdFusion.navigate('live-checkuseravailability.cfc?method=getData&returnformat=plain&UserAvail='+ value, 'AvailabilityDiv');
"ColdFusion, I want you to navigate, ie, load, the result of calling this CFC method."
By default, when you run a CFC method remotely, it returns WDDX, an XML version of the result. If you were to open that URL in your browser and view source, you woulda seen an XML version of the string.
When I had you add "returnformat=plain", it was telling ColdFusion to not do ANYTHING with the result, but rather just return it as is.
This only works with simple results. You couldn't return an array like that.
You can stop reading now - what follows is sermon. ;)
Typically though you don't return layout in a CFC. I'd have called the CFC method and have it return 0 or 1, with 0 being the bad result, and 1 the good, and your front end code would handle displaying the appropriate message. Your CFC - typically - should be a black box of business logic: "If this username OK? YES OR NO - Period." Stuff like "what class do I use to render a good output" would be a concern of the front end.
End of Sermon.
I see what you are saying and I actually tried a few things and that seems to be what I got working. What I was struggling with was where I get the result, I guess what variable holds the result. I tried a few things and kept getting errors, so that Is when I did it the "wong" way, but it worked. I see what you are saying and that would be a lot better. I just did not know how to do it.
I have done CF for many years, but some areas I still have a ton to learn. Again, Thanks for your time.
1) If you want to stick with CF's Ajax stuff, you can look at cfajaxproxy. It allows you to turn a CFC into a JavaScript object. You would then be able to make calls on methods and work with the results directly.
2) Myself - I don't make use of CF's front end Ajax stuff. I use jQuery instead. I'd use jQuery's ability to run a HTTP request and work with the response.
Obviously I'm talking high level here.
I will have to do some studying on what you said. I appreciate the feedback and direction. Got some learning to do.
[Add Comment] [Subscribe to Comments]