Home > Java, Web > Maxlength HTML attribute for domain objects

Maxlength HTML attribute for domain objects

by paul on March 6, 2008

With Grails domain classes, constraints can be specified – including the maximum size of a String. For example:

class Book {
    String title

    static def constraints = {
        title(maxSize:20)
    }
}

When using ‘grails generate-all’ to create scaffolding, you’ll notice that create.gsp and add.gsp hardcode the maxlength attribute:

<input type="text" maxlength="20" id="title" name="title"
        value="${fieldValue(bean:book,field:'title')}"/>

It is possible to directly reference the constraint, meaning that the maxlength attribute is not hardcoded – and thus only defined once (in the domain object):

<input type="text" maxlength="${Book.constraints.title.getMaxSize()}"
       id="title" name="title"
       value="${fieldValue(bean:book,field:'title')}"/>

In fact, we can go even further and create a tag where we pass in the object itself, and the name (which matches the property name) and we can dynamically generate the maxlength and value attributes.

So when editing a book with the title set to ‘my new book’, the following code:

<jttext:textField object="${book}" name="title"/>

produces the following HTML:

<input type="text" name="title" maxlength="20" value="my new book"
        id="title" />

The tag library to produce this is as follows:

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

class TextTagLib extends FormTagLib {
    static namespace = "jttext"

    def textField = {attrs ->
        attrs.type = "text"
        attrs.tagName = "textField"

        def object = attrs.remove('object')
        def maxlength = object.constraints."${attrs.name}".getMaxSize()
        if(maxlength) {
            attrs.put('maxlength', maxlength)
        }
        attrs.put('value', fieldValue(bean:object,field:attrs.name))

        def result = field(attrs)
        if (result) {
            out << result
        }
    }
}

It makes sense to me that the tag does all of the work – it reduces duplication and makes the code more readable.

What do you think?

{ 6 comments… read them below or add one }

David Marko March 6, 2008 at 11:04 pm

It makes absolute sense. Especially when one is using command objects with some specific settings. using this aproach one can avoid inconsistency . is it working with Command Objects as well?

David

paul March 7, 2008 at 1:49 am

David, I’m not sure what you mean here – it makes sense with Domain objects since they are populated with constraints such as maxSize. What do you mean by command objects?

David Marko March 7, 2008 at 10:28 pm

I mean this Grails feature
http://grails.org/doc/1.0.x/guide/6.%20The%20Web%20Layer.html#6.1.9%20Command%20Objects

Its like the domain object except it serves as form. Details are in docs.

paul March 7, 2008 at 11:37 pm

Ah, thanks. I expect it will work with command objects since constraints are defined in exactly the same way.

David Marko March 7, 2008 at 11:52 pm

‘Command Objects’ is very unusual naming. :-) They should call it Forms or something.

Nitin December 5, 2011 at 11:00 pm

Thanks for showcasing this example. But, I guess this doesn’t works for nested level fields.
For ex.
Class A has a instance of Class B as a field b, which in turn has field String title. Then in that case following line will not work, until ‘b’ is already initialized
maxlength=”${A.b.constraints.title.getMaxSize()}”

Leave a Comment

Previous post:

Next post: