Last updated by 5 years ago

Page: Draft_ModelTagLib, Version:1

ModelTagLib

Updated - now requires Grails 1.0

A work in progress taglib, which I hope will make it into Grails core in 1.1 after some discussion.

The Elevator Pitch

Currently to render fields that are aware of domain class constraints such as maximum field length, "inList" options in a select box etc, you have a fair bit of manual coding to do in your GSP pages.

You want tags that are constraint-aware, and also aware of the current values of fields, and able to display the errors of a field next to the field itself on the form. You also want to not have to do <label> tags manually everywhere, but you want the flexibility to control how fields and their labels are rendered. You also want labels that can be explicit or loaded from I18N bundles.

That's what this taglib does.

Usage example

<g:modelInput beanName="form" property="user.firstName" label="Name"/>

...will output, given a model containing a form object with a populated User domain class :-

<label for="user.firstName">Name</label> * <input id="user.firstName" 
name="user.firstName" value="Marc" maxlength="50" size="50"/>

To summarize:

  • It has generated a label
  • It has generated the field with HTML attributes set according to the constraints defined on the domain class
  • It has populated the value with the current value of the property on the bean
  • It has laid out the label and input field, and "required" indicator ("*" in this case) in a user-controllable way
If there are errors relating to the field it would output those also, according to a template you define. Any information used comes from constraints if they are available, or from "overrides" supplied via attributes to the tag.

Another example:

<g:modelSelect beanName="form" property="consumptionFrequency" 
  optionValue="${ { message(code:'consumptionFrequency.' + it ) } }" labelKey="form.label.consumptionFrequency" /><br />

The above will render a select drop-down with values shown using text from the I18N bundle, where the modelSelect tag has defined the list of keys as those specifed in the inList constraint of the property. The label is also rendered, with the label coming from a specific key in the I18N bundle.

Using the <g:modelParam/> tag you can set the templates used to render errors, "required" indicators, labels, and individual field types in relation to their labels and so on.

Currently the documentation for all the tags is in the comments in the taglib file. A full reference will be put together if/when it is decided that this, or a modified form of it, is to be pulled into Grails core.

Implementation notes

This taglib demonstrates some interesting patterns.

  1. Use of body of tag to specify reusable templates (closures) which are then used to render the content of tags themselves, to control the layout of elements within the tag's output (i.e. where should the <label> be in relation to the <input> etc)
  2. Use of a tag to set parameters for the taglib, which persist using copy-on-write semantics for the current request
  3. Internally, in code terms, using a pattern to reuse common tag functionality by taking a closure from the calling tags used to render the output portion after parsing common parameters etc.
The modelCountry tag for country code selection requires my embryonic I18NTagLib

Source

The source is available here.