ColdFusion 8 date chooser image doesn't appear in CFDIV or CFWINDOW

I've been using the nifty date chooser widget in ColdFusion 8 and love it. Using the <cfform> tag and a <cfinput> tag you simply add the type="datefield" and mask="MM/DD/YYYY". You'll see a small image of a calendar appear next to your input form and when you click on it a nice calendar date chooser will appear.

 

My problems begain when I tried to use this same code inside a .cfm page and used the bind (cfdiv) or source (cfwindow) attribute to point to this separate page. The small calendar image would not appear. I thought this had something to do with the asynchronous nature of cfdivs and cfwindows.

 

But, I've descovered the problem.

 

1. I did not map the CFIDE directory and instead copied all the content of /CFIDE/scripts/ into a directory off the root called /js/cf8/. Then I used <cfajaximport scriptSrc="/js/cf8" tags="cfform,cfdiv,cfinput-datefield">. This SHOULD work. But it didn't. Thanks to the FireBug plug-in (Love this plug-in, if you don't have it running in Firefox 3 get it now). Firebug allowed me to see the source of my external.cfm file. I found the problem.

 

Here is the image tag for my main page calendar icon.

 

<img id="myDatemyForm_cf_button" src="/js/cf8/ajax/resources/cf/images/DateChooser.png"/>

 

And here is the image tag for my external page calendar icon.

 

<img id="myExternalDatemyExternalForm_cf_button" src="/CFIDE/scripts/ajax/resources/cf/images/DateChooser.png"/>

 

No good!

 

So, my solution. Create the directory "/CFIDE/scripts/ajax/resources/cf/images/" off my webroot and copy the image contents.

 

Voila! the calendar image appears and the date chooser works great.

Happy coding.

 

ColdFusion.setSubmitChecked Javascript Error

I recently encountered the error "ColdFusion.setSubmitChecked" when loading a page that contained a cfform inside a cfdiv. Below is an example of the code I was using.

 

<cfdiv>

<cfform>

<cfinput type="submit" name="thisButton" id="thisButton" value="submit">

</cfform>

</cfdiv>

 

I had recently updated to version 8.01 of ColdFusion. The thought of that update jogged my memory. This project is using copy of the "scripts" in the root directory. I was NOT pointing to the "scripts" directory under the CFIDE directory. I thought why not? So I archived my old ajax files and moved a fresh copy over from /CFIDE/scripts/. What do you know that solved the problem.

 

That's two bugs I've found AFTER they have been fixed. Guess I'm just lucky that way.

 

 

How to perform a cflocation when a session times out using a cfdiv

If you are using the cfform tag inside a cfdiv to submit the form without refreshing the page, then the short answer is you can't do a cflocation outside the cfdiv.

 

This problem cropped up on a recent project. The OnRequestStart function in application.cfc redirects to the login screen when a session times out. This works fine when submitting a form in the main page, but not when the cfform is inside a cfdiv and uses AJAX to refresh the contents of the cfdiv.

 

What does happen? The login screen appears inside the cfdiv. What I want to happen is to redirect the main page (which contains the cfdiv) to the login screen. How cfform functions inside the cfdiv tag is covered in a blog post by Ray Camden.

 

To sum up Ray's post, a cfform inside the cfdiv tag uses ajax to submit the form and return the results inside the cfdiv without reloading the container page. This feature is great and I'm using it extensively, but presents a challenge when using the OnRequestStart function to redirect.

 

The solution is to use javascript for your redirect instead of cflocation. You can download the example code. Below are the main points.

 

See a live example

 

Download the code

 

First you need to modify your application.cfc file.

 

application.cfc

<cffunction name="onRequestStart" returnType="boolean" output="false">
  <cfargument name="thePage" type="string" required="true">

  <cfset request.LogoutNow="false">
  <cfif session.login eq 0>
    <cfset request.LogoutNow = "true">

    <cfset CurrentPage=#gettoken(cgi.CF_TEMPLATE_PATH,listlen(cgi.CF_TEMPLATE_PATH,"/"),"/")#>
    <cfif listfindnocase("index.cfm", CurrentPage)>
      <cflocation url="login.cfm" addtoken="no">
    </cfif>
  </cfif>
  <cfreturn true>
</cffunction>

 

Next, you need to add a hidden form field called LogoutNow to your cfdiv page. You'll also add the AjaxOnLoad function. What does the AjaxOnLoad function do? It's very similar to the onLoad method which you put in the body tag. It fires the javascript function name passed as it's parameter. It only fires after the cfdiv contents are done loading.

 

mycfdiv.cfm

 

<cfparam name="LogoutNow" default="false">
<cfif isDefined('form.SubmitButton')>
  <cfset LogoutNow = "#request.LogoutNow#">
</cfif>

<cfform method="post" name="myForm" action="#cgi.SCRIPT_NAME#">
<p>
This form is a CFFORM inside a CFDIV tag.
</p>
<p>
It will submit asynchronously using AJAX.
</p>
<cfinput type="hidden" name="LogoutNow" id="LogoutNow" value="#LogoutNow#"/>
<cfinput type="submit" name="SubmitButton" value="Submit Form">
</cfform>

<cfset AjaxOnLoad("InitDiv")>

 

In the main page (index.cfm), my javascript function InitDiv is called when the cfdiv is done loading. The CheckLogout function is called and if LogoutNow is true, then reload the main page. This will fire the OnRequestStart function in application.cfc and redirect us to the login screen since our session is expired.

 

index.cfm

<script>
InitDiv = function() {
   CheckLogout();
}

CheckLogout = function() {
   if(document.getElementById('LogoutNow').value =='true') {
     window.location.href = 'index.cfm';
   }
}
</script>

 

Feedback, thoughts or suggestions always welcome.

 

 

Test the strength of a password with ColdFusion 8 / AJAX

I attended a session about securing your ColdFusion applications at MAX 2007 and decided to add password strength testing to one of my projects. It's a nifty trick. As the user types in their password, a message tells them if their password is weak, average or strong. I've seen this done with Javascript on the client side, but thought I'd take advantage of the new AJAX features of ColdFusion 8 to build mine.

 

Below is the code you'll add to your page.

<cfajaximport scriptsrc="/js/cf8" tags="cfdiv">

 

When using CF-8JAX (my new term), I often get javascript errors because I can't access the /CFIDE/scripts directory on the server. To remedy this, I've uploaded all the files from /CFIDE/scripts into a directory off my webroot called /js/cf8. Then I can import the javascript libraries I need using the CFAJAXIMPORT tag.

 

<form action="" method="POST" >
<div class="item">
   <div class="label">New Password:&nbsp;</div>
   <div class="field"><input type="password" name="NewPassword" value=""></div>
</div>

 

Nothing special above, just a password input field.

 

<cfdiv bind="cfc:remote.PasswordStrength(password={NewPassword.value@keyup})" />
</form>

 

Ok, here is where the magic happens. The function PasswordStrength is located in the file remote.cfc. I placed remote.cfc in the same directory, but you can place it anywhere. Just make sure you update the cfdiv tag to reflect the new location.

 

I pass the argument "password" into my function. I discovered the @keyup trick looking at some other blog posts. Now each time a new character is added the password strength is tested. Love this feature. You can also use @blur or @keypress. Along with the strength I give the user hints how to strengthen their password.

 

See an example or Download the code

 

Feedback always welcome. Let me know if you have improvement for my PasswordStrength function. Thanks!