Search code examples
ruby-on-railsruby-on-rails-3html-listsformtasticfieldset

Formtastic: nested fieldsets produce unusable/invalid markup


I'm trying to group related attributes into a "Doublefield" by putting them into a form.inputs block:

<%= semantic_form_for MyModel.new do |f| %>
    <%= f.inputs 'Advanced' do %>
        <%= f.input :name %>
        <%= f.inputs 'Min/Max', class: 'doublefield' do %>
          <%= f.input :min %>
          <%= f.input :max %>
        <% end %>
        <%= f.inputs 'Zip/Place', class: 'doublefield' do %>
          <%= f.input :zip %>
          <%= f.input :place %>
        <% end %>
    <% end %> 
<% end %>

However, this produces a markup like that (omitted irrelevant markup):

<form accept-charset="UTF-8" action="my_model" class="formtastic" id="new_my_model" method="post" novalidate="novalidate">  
    <fieldset class="inputs">
        <ol>
                <li class="string input optional stringish" id="my_model_name_input">
                    ...
                </li>
                <li class="input">
                    <fieldset class="doublefield">
                        ...
                    </fieldset>
                </li>
                <fieldset class="doublefield">
                    ...
                </fieldset>
        </ol>
    </fieldset>
</form>

Only the first nested fieldset in the fieldset gets surrounded by the <li> tag, the others are just rendered as <fieldset> which leads to invalid markup (<fieldset> as direct child of <ol> is not allowed). This isn't just ugly but also makes it hard to apply styles to the form.

In my research I've stumbled upon some comments about this issue where it stated that this could have been an issue with formtastic itself, but I haven't found a workaround or suggestion up until now.

Any ideas?

Version Information:

  • rails (3.2.0.beta bd4bd3f)
  • formtastic (2.0.0.rc4 7d3bb2f)
  • ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]

Full markup:

<form accept-charset="UTF-8" action="my_model" class="formtastic" id="new_my_model" method="post" novalidate="novalidate">
<div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓">
    <input name="authenticity_token" type="hidden" value="zPm0lLyT6MM4M+LI1b7c9d7NqGQM2PiT+kHsjUnfTWM="></div>
    <fieldset class="inputs">
        <legend><span>Advanced</span></legend>
            <ol>
                <li class="string input optional stringish" id="my_model_name_input">
                    <label class=" label" for="my_model_name">Name</label>
                    <input id="my_model_name" maxlength="255" name="my_model[name]" type="text">
            </li>
                <li class="input">
                    <fieldset class="doublefield">
                        <legend><span>Min/Max</span></legend>
                    <ol>
                        <li class="number input optional stringish" id="my_model_min_input">
                            <label class=" label" for="my_model_roosts_min">Min</label>
                            <input id="my_model_min" maxlength="4" name="my_model[min]" step="any" type="number">
                        </li>
                        <li class="number input optional stringish" id="my_model_max_input">
                            <label class=" label" for="my_model_max">Max</label>
                            <input id="my_model_roosts_max" maxlength="4" name="my_model[max]" step="any" type="number">
                        </li>
                    </ol>
                </fieldset>
            </li>
                <fieldset class="doublefield">
                    <legend><span>Zip/Place</span></legend>
                    <ol>
                    <li class="string input optional stringish" id="my_model_zip_input">
                        <label class=" label" for="my_model_zip">Zip</label>
                        <input id="my_model_zip" maxlength="255" name="my_model[zip]" type="text">
                    </li>
                    <li class="string input optional stringish" id="my_model_place_input">
                        <label class=" label" for="my_model_place">Place</label>
                        <input id="my_model_place" maxlength="255" name="my_model[place]" type="text">
                    </li>
                </ol>
            </fieldset>
        </ol>
    </fieldset>
</div>


Solution

  • [EDIT] made the answer relevant to Formtastic 2

    This was a bug in formtastic, which has been fixed 3 days ago: https://github.com/justinfrench/formtastic/commit/4c5bf686b7fc5bbbc2e03c61cace101e713a51e0

    If you don't want to wait for the release (and you likely don't), use the version from git:

    gem 'formtastic', :git => 'git://github.com/justinfrench/formtastic.git'