jueves, julio 31, 2008

JT Dev » Blog Archive » Shorter Grails textField

Shorter Grails textField

Making textFields in Grails is a bit verbose, at least if you want error highlighting and returned values on errors. This post shows a quick solution.
Problem

A full textField would be:
view plaincopy to clipboardprint?

1.




Which clearly is very verbose; you have to specify “user” twice, and “name” even three times. This verbosity also makes the view less readable.

Googling for this problem resulted in: Smarter Grails Tags (a proposal). Funny that the writer exactly sees the same problem in it, also uses the “user” domain model, and also knows Stripes where you could just use something like
view plaincopy to clipboardprint?

1.




and specify the bean name in the form. (Stripes has a very good Quick Start Guide, which also shows error highlighting.)

One of the less verbose proposed formats of textField is:
view plaincopy to clipboardprint?

1.




Implemented Solution

I found that implementing a quick version of this is surprisingly easy in Grails, it only takes for a few statements. Here is the code:
view plaincopy to clipboardprint?

1.
import org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib
2.

3.
// file: project/grails-app/taglib/MyTagLib.groovy
4.
class MyTagLib {
5.
// tagname "myTextField" within the "g" namespace
6.
def myTextField = {attrs ->
7.
// If a controller returned the bean, and the field has an error,
8.
// then "errors" will be returned as HTML class, otherwise the class will be empty.
9.
attrs.class = hasErrors(bean:attrs.bean, field:attrs.field, 'errors')
10.
// Retrieves the field value of the given bean to be rendered in the view.
11.
// Note: specify the bean and not the bean name. So "${user}" instead of "user"
12.
attrs.value = fieldValue(bean:attrs.bean, field:attrs.field)
13.
// Required for textField taglib. attrs.name is a keyname of the params map
14.
attrs.name = attrs.field
15.
// renders the HTML tag
16.
out << new FormTagLib().textField(attrs)
17.
}
18.
}

import org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib

// file: project/grails-app/taglib/MyTagLib.groovy
class MyTagLib {
// tagname "myTextField" within the "g" namespace
def myTextField = {attrs ->
// If a controller returned the bean, and the field has an error,
// then "errors" will be returned as HTML class, otherwise the class will be empty.
attrs.class = hasErrors(bean:attrs.bean, field:attrs.field, 'errors')
// Retrieves the field value of the given bean to be rendered in the view.
// Note: specify the bean and not the bean name. So "${user}" instead of "user"
attrs.value = fieldValue(bean:attrs.bean, field:attrs.field)
// Required for textField taglib. attrs.name is a keyname of the params map
attrs.name = attrs.field
// renders the HTML tag
out << new FormTagLib().textField(attrs)
}
}

Usage
view plaincopy to clipboardprint?

1.




And ofcourse some CSS to highlight the error in a color. This can be put in the HTML head (or better, a seperate CSS file) :
view plaincopy to clipboardprint?

1.

No hay comentarios: