feckless fieldset

28 views
Skip to first unread message

Bryan Larsen

unread,
Aug 5, 2009, 11:30:14 AM8/5/09
to Hobo Users
Hi all,

I've got a big demo set up for tomorrow. Hopefully after that I can
start getting caught up on hobousers again. In the meantime, here's
a tag and some css that I'll probably put into hobo-contrib. Please
try it out. Enjoy!


<!--- This tag is very similar to Rapid's `field-list`. However,
instead of rendering a table, it renders what [Anatoli Papirovski
calls "perfect form markup"](http://fecklessmind.com/2009/01/23/how-to-
reliable-css-forms/)

It takes the same attributes & parameters as [field-list](http://
cookbook.hobocentral.net/api_tag_defs/field-list), with the addition
of a `legend` parameter and a `required` attribute.

The `required` attribute is a list of methods. If the current field
is included in the list, the field div has the `required` class added
to it.

The accompanying css allows this fieldset to be rendered in three
different ways. You may trigger these by setting a class of
`horizontal`, `vertical` or `inline-vertical`. `inline-vertical`
fieldset's may also be nested inside of a `horizontal` fieldset.

### Example

Simple example:

<form>
<feckless-fieldset class="vertical"/>
</form>


And a more complicated one that you may actually want to steal:

<extend tag="signup-form" for="User">
<old-signup-form >
<field-list: replace>
<fieldset class="horizontal">
<legend>New Account Registration</legend>
<div class="field name-field">
<label class="name-label" for="user_name">Name</label>
<feckless-fieldset id="user_name" class="inline-
vertical" fields="salutation, first_name, last_name, suffix"
required="first_name, last_name" />
</div>
<div class="field contact-field">
<label class="contact-label" for="user_contact">Contact</
label>
<feckless-fieldset id="user_contact" class="inline-
vertical" fields="email_address, phone_number"
required="email_address" />
</div>
<div class="field passwords-field">
<label class="passwords-label"
for="user_contact">Password</label>
<feckless-fieldset id="user_passwords" class="inline-
vertical" fields="password, password_confirmation" required="password,
password_confirmation">
<password-label:></password-label:>
<password-confirmation-label:>Confirmation</password-
confirmation-label:>
</feckless-fieldset>
</div>
</fieldset>
</field-list:>
</old-signup-form>
</extend>

-->
<def tag="feckless-fieldset" attrs="tag, no-edit, required">
<% tag ||= scope.in_form ? "input" : "view"; no_edit ||= "skip" -%>
<% required ||= "" ; required = comma_split(required.gsub('-', '_'))
-%>
<fieldset class="feckless-fields" merge-attrs="&attributes -
attrs_for(:with_fields)">
<legend param if="&parameters[:legend]" />
<with-fields merge-attrs="&attributes & attrs_for(:with_fields)">
<% field_name = this_field_name
input_attrs = {:no_edit => no_edit} if tag == "input" &&
no_edit == "disable"
field_method = this_field.to_s.sub('?', '')
id_for_this = param_name_for_this.gsub('[', '_').gsub(']', '')
-%>
<div class="field #{field_method}-field #{'required' if
required.include?(field_method)} " unless="&tag == 'input' && no_edit
== 'skip' && !can_edit?">
<label for="&id_for_this" param="#{field_method}-label"
unless="&field_name.blank?">
<%= field_name %>
</label>
<do param="#{field_method}-view">
<do param="view"><call-tag tag="&tag" param="#{field_method}-
tag" merge-attrs="&input_attrs"/></do>
</do>
<span param="#{field_method}-help" class="input-help"
if="&tag.to_sym == :input && !this_field_help.blank?">
<%= this_field_help %>
</span>
</div>
</with-fields>
</fieldset>
</def>

css:

/* see: http://fecklessmind.com/2009/01/23/how-to-reliable-css-forms/
*/

/* put a class of 'vertical', 'horizontal' or 'inline-vertical' on
your fieldset to choose your layout. */

/* fieldset {clear: both;} */
legend {padding: 0 0 1.286em; font-size: 1.167em; font-weight: 700;}
fieldset fieldset legend {padding: 0 0 1.5em; font-size: 1em;}
* html legend {margin-left: -7px;} /* ie6 */
*+html legend {margin-left: -7px;} /* ie7 */

fieldset .field, fieldset .buttons {/* clear: both; */ margin: 0 0
1.0em;}
fieldset .field label, fieldset .field .input-help {display: block;}
fieldset ul.fields {margin: 0 0 1.0em; padding: 0;}
fieldset ul.fields li {list-style-type: none; margin: 0;}
fieldset ul.inline li, fieldset ul.inline label {display: inline;}
fieldset ul.inline li {padding: 0 .75em 0 0;}

input.radio, input.checkbox {vertical-align: top;}
label, button, input.submit, input.image {cursor: pointer;}
* html input.radio, * html input.checkbox {vertical-align: middle;} /*
ie6 */
*+html input.radio, *+html input.checkbox {vertical-align: middle;} /*
ie7 */


textarea {overflow: auto;}
input.text, input.string, input.email-address, input.password,
textarea, select {margin: 0; font: 1em/1.3 Helvetica, Arial,
"Liberation Sans", "Bitstream Vera Sans", sans-serif; vertical-align:
baseline;}
input.text, input.string, input.email-address, input.password,
textarea {border: 1px solid #444; padding: 2px;}

/* horizontal layout */
fieldset.horizontal .field {padding-left: 150px; }
fieldset.horizontal .field label {display: inline; float: left; width:
140px; margin-left: -150px; clear:none;}
fieldset.horizontal .input-help { display: inline; margin-left:
0.5em; }

/* inline vertical layout. We make sure to undue all the
fieldset.horizontal styles so that this can be nested inside a
fieldset.horizontal */
fieldset.inline-vertical .field {padding-left: 0; display: inline-
block; float: none; margin-left: 0; clear: none; height:1%;
*display:inline;}
fieldset.inline-vertical .field label {display: block; float: none;
width: 100%; margin-left: 0;}
fieldset.inline-vertical .input-help { display: block; margin-left:
0; }

fieldset .field.required {color: red; }

kevinpfromnm

unread,
Aug 5, 2009, 5:43:21 PM8/5/09
to Hobo Users
Nice, though I worry glancing at some of the css that it might be
somewhat brittle in different layouts. Then again, I haven't had to
deal with IE chicanery for awhile so maybe that's just me. :P

Bryan Larsen

unread,
Aug 5, 2009, 7:08:26 PM8/5/09
to hobo...@googlegroups.com
The CSS was mostly stolen from somebody who really knows his CSS.

OTOH, my modifications to the CSS haven't even been tested in IE yet. I
will do that before it hits hobo-contrib, though.

cheers,
Bryan

Tom Locke

unread,
Aug 13, 2009, 5:45:59 AM8/13/09
to hobo...@googlegroups.com
Looks good Bryan. I think this should become the default at some point.

The only thing I'm not that keen on is the 'vertical', 'horizontal'
and 'inline-vertical' CSS classes, which are presentational classes.
It would be nicer to be able to make this choice in the stylesheet,
but to do that and still be nice and declarative, we might need to use
a "better CSS" like LESS, that supports abstraction.

Tom

Owen

unread,
Aug 15, 2009, 2:19:50 PM8/15/09
to Hobo Users
Would be good to do a quick screen cast on this stuff :-)

Spiralis

unread,
Aug 21, 2009, 5:47:38 PM8/21/09
to Hobo Users
Great work Bryan.

I had to change the definition slightly to make the feckless-fieldset
legend parameter work as expected.

From:
<legend param if="&parameters[:legend]" />
to:
<legend param if="&all_parameters[:legend]" />


Thanks!
Reply all
Reply to author
Forward
0 new messages