Rails custom FormBuilder made way, way easy
Published by stephan November 21st, 2008 in programming
I wanted to give my Ruby on Rails app a simple jQuery driven custom boolean field, styled as a lock for security purposes. You know, click on the lock and it opens, click on it again and it closes. Just like the lock there to the right - go ahead, click on it :).
I especially wanted to use it like the other Form Builder tags within a form_for block, just the same as I would use a checkbox, like this:
form_for(current_user, :builder => IconFormBuilder) do |f|
f.privacy_field :share_this
end
It turns out this isn’t a difficult thing to do, but I couldn’t find any blog posts that show just how easy it is, so I struggled for a while. Hopefully, I’ll save you the trouble. Most of the posts I found weren’t trying to do anything this simple.
This article at Aldenta shows how to use metaprogramming to insert your new form method into the existing form tags. The only practical use I can see for all that trouble is to save you the trouble of adding :builder to your form_for tag… and I don’t really mind using :builder to be specific with my intent.
Several sources, including Advanced Rails Recipes and an article at OnRails, show how to wrap all of the existing form elements in the builder, again using metaprogramming. Nice, but not what I was looking for.
Both of these articles hint at the solution, but no one had cut it down to the essence. I finally came up with this. Make a file called “icon_form_builder.rb” in app/helpers. Name it whatever you want - just so the class name and the file name match. I always get so confused figuring out where to put new things in Rails, but this seems like the right spot.
class IconFormBuilder < ActionView::Helpers::FormBuilder
def lock_icon(value)
if value
"function_icon_set/lock_open_48.png"
else
"function_icon_set/lock_48.png"
end
end
def privacy_field(method, options={})
retString = hidden_field(method, options)
retString += @template.image_tag(
lock_icon(@object[method]),
:onclick => ("h=$('##{object_name}_#{method}');"+
"if(h.val()=='t'){h.val('f');$(this).attr({src:'/images/#{lock_icon(false)}'})}"+
"else {h.val('t');$(this).attr({src:'/images/#{lock_icon(true)}'})}"))
return retString
end
end
lock_icon is just a convenience to DRY up the selection of an image (my working version is drier all round). The javascript just uses jQuery to toggle the image and the hidden field. I’m using a lovely free icon set by Function Design & Development Studio.
Note that we’re defining a new field tag - but you can just as easily redefine an existing one. Just change “privacy_field” to, say, “check_box” and all of the checkboxes on your page will be redefined as locks! I didn’t want to do that here, but it’s that easy.
There a bit more to know for getting fancy - but this should get you started!











No Responses to “Rails custom FormBuilder made way, way easy”
Please Wait
Leave a Reply
You must log in to post a comment.