Formtastic is pretty killer when it comes to creating nice looking forms very quickly. I love the short syntax compared to the default Rails form helpers, but sometimes I find the black box helpers a bit restricting when it comes to customizing the forms. Usually modifying the CSS is enough to get desired results, but I ran into a case today where it would have been an ugly hack to make it work with CSS.
Problem
I need to add HTML inside the <li> tag that is produced by the formtastic input helper. The helper produces HTML that looks like this:
I want to insert a link in betweent the input field and the inline hints. This is not possible, since the formtastic input helper outputs this entire HTML snippet. You can customize plenty of things within the helper, but I did not see a way to add more html content.
Solution
As I started to dig through the formtastic source I noticed that all of the input elements are using a wrapper module that produces the content inside the <li> tag. Take a look at this module:
All of the Formtastic input classes (StringInput, TextInput, HiddenInput,etc..) pass a block to the input_wrapping method inside their to_html method. The content_tag method takes the element name, content and element options as arguments. See here for more info: http://apidock.com/rails/ActionView/Helpers/TagHelper/content_tag
In order to add my content, I will need to add a String element (my HTML) to this array:
As you can see in the code above, it is just an array of strings that are joined together by carriage returns and marked as safe using the Rails String core_ext html_safe. So I will have to insert my HTML code in the desired position of this array. In my scenario, it makes sense to put the extra HTML between the input tag and the error html. I decided to monkey patch this method (oops, maybe dangerous if I ever upgrade formtastic for this app). I added this code to /app/config/initializers/formtastic_monkey_patch.rb:
The first thing I needed to patch was the Html module. 3 methods were added to this module to allow me to pass :extra_html and :extra_html_class to the formtastic input helper. This was pretty much a copy/paste from “Formtastic::Inputs::Base::Hints”. Then I just had to add the “extra_html” to the array inside the “input_wrapping” method. Now I can do this in my form:
This will output:
I can take this a step further by adding another option for the order that the extra html will appear inside the <li> tag. New monkey patch:
I added one method inside the Html class to set a default extra_html_position within the options hash. Then I modified “input wrapping” so it inserts the extra_html into the specified position. Here is the new formtastic input call in my view:
By passing the :extra_html_position option with a value of zero, formtastic will now insert the extra_html before the input tag. So there ya go… monkey-patched and ready to roll.




#1 by Hugh Evans on September 12, 2011 - 6:55 pm
Quote
Maybe it would be better if the input method took a block like the inputs method?
That way you would not need to jam all your html in one line.
Thanks though, this was very helpful.
#2 by Eric Peters on December 3, 2011 - 12:05 pm
Quote
+1, I tried adding in a random button_to after an input and the formatting got all hosed, I like this solution, but can you modify it to use a block instead?
#3 by Eric Peters on December 3, 2011 - 2:08 pm
Quote
Does this work with the latest formtastic/etc
I tried this approach but noticed now my
{ :disable_with => ‘Please wait …’} %>
is getting placed outside of the for some weird reason, if I back out the config initializer for this monkey patch and leave the same HTML inplace it works fine
:phones, :action=> :send_auth, :id => f.object.id },
:remote => true,
:form_class => “resend” %>
“SMS Auth Code”, :as=>:string, :hint=>”This was TXTed to #{f.object.number}”, :extra_html=>resend_button%>
#4 by Eric Peters on December 6, 2011 - 4:34 pm
Quote
*Edit* can you kill my 2nd comment I realized that the issue is I can’t have a button_to because it creates a form tag inside a form tag which causes havoc
#5 by cowboycoded on December 6, 2011 - 5:08 pm
Quote
Sorry for the late reply. So this is working for you now? I have not tested with the latest versions of Rails and formastic, so I am not sure if this is still a working patch. Honestly I would not recommend using this in the long term, since newer versions could break it.