CFWheels + jQuery Partial for Setting Form Focus
August 25, 2009 · Chris Peters
You've seen it before: you get to a login screen, and the cursor automatically jumps to the username box so you can just start typing. It's very convenient. But developers seem to screw this up regularly.
Update: I definitely recommend reading through this, but I was a little flawed in my implementation, as Stephen pointed out in the comments. Read my follow-up for more details.
You’ve seen it before: you get to a login screen, and the cursor automatically jumps to the username box so you can just start typing. It’s very convenient.
But developers seem to screw this up regularly. I’ve seen it implemented so poorly that it becomes highly unusable and opens potential security problems.
On my bank’s website, for example, the focus will jump to the username field if you’ve started typing the password before the page has fully loaded. (Sometimes the home page will load slowly, which happens from time to time, you know?) This causes me to expose part of my password to anyone who may be looking over my shoulder!
jQuery to the Rescue
The jQuery library provides a method called ready()
, which basically helps you to load events as soon as the page is ready for them.
So we can write this simple jQuery code:
$(document).ready(function(){ | |
$("#my-form-element").focus(); | |
}); |
This causes focus to jump to the form element with an id
of my-form-element
on page load.
This won’t cause cursor-jumping mishaps if the user starts typing before the page is ready. (Well, because the page will be ready before the user starts typing. Trippy…)
Making this Reusable in CFWheels
I have a couple layouts in my current CFWheels application that could use this functionality. So I created this partial that can be included in both layouts via includePartial()
.
This is the partial at views/_layout_focus.cfm:
<cfparam name="arguments.focus" type="string" default=""> | |
<cfif Len(arguments.focus)> | |
<cfoutput> | |
<script type="text/javascript"> | |
$(document).ready(function(){ | |
$("#arguments.focus#").focus(); | |
}); | |
</script> | |
</cfoutput> | |
</cfif> |
This allows me to put this line in the <head>
section of my layout files:
<!--- Note: This should be <cfparam>'ed earlier in the file, of course ---> | |
#includePartial(name="/layout_focus", focus=layout.focus)# |
Now whenever one of my views need to put focus on a particular form input, I can add this call to the view file:
<!--- Note: This should be <cfparam>'ed earlier in the file, of course ---> | |
#includePartial(name="/layout_focus", focus=layout.focus)# |
Pretty flexible and available whenever it’s needed.
Most of the time, the view template will set layout.focus
, but it’s also available when the controller needs to do the thinking. Sometimes the controller may need to make a decision like putting focus on the username field vs. the password field, for example. Maybe the username field is already filled in by a cookie or previous user input.
I hope this helps you better understand some of these jQuery and Wheels concepts. I’m trying to think of interesting real-world examples of where I’ve started to use this new stuff. I’ll keep trying until you guys start showering me with praise in the comments.