Customizing Grails Scaffolding and Adding Accessibility with the Fields Plugin

One of the oft-touted benefits of Grails is that you can automatically generate a user interface for basic database operations such as creating a new entity, updating, deleting, and listing all entities.

While this looks really neat in demos, in most cases, you don’t want to use the scaffolded files as your real application’s production user interface. If you are editing a simple code table, such as a list of countries or states, then the scaffolded UI may be sufficient. In most cases, though, it won’t. Furthermore, scaffolded controller code puts the database operations directly in the controller, not in a transaction service where such code belongs.

The scaffolding is still useful especially during the early phases of a project, where the ability to generate a basic user interface from domain classes can really speed up your development. Recent versions of Grails have improved the generated interface, adding in HTML 5 features (of mixed blessing, alas) and a much, much better look. Even so, I have never used the Grails-generated styles as is in any real project. I’ve always had to adopt a look and feel for a particular company or application and that look and feel has rarely been close to the Grails interface.

That said, having a default user interface really helps as you flesh out the application. It provides a set of code that you can then customize and normally speeds up your work. And, this gets even better if you can generate a basic interface that comes closer to the final interface you want.

Grails has allowed you to customize the scaffolded templates for a long time. That is, you can customize how Grails generates a user interface from your domain classes, putting in the styles you want, the form layout you want, and the customized HTML you want. But that has been a sort of all or nothing approach, having to edit complex, daunting templates to get anything done. To help with this, you can use the fields plugin.

Described in one of the best talks at the 2012 GR8 US Conference, the fields plugin allows you to easily customize the scaffolded user interface in small chunks. You can customize one small piece without having to mess with the whole thing. With this, you can apply your organization’s look and feel directly when generating views. Even if you don’t use this code directly, it means you will have a lot less to customize to get to your final result.

To use the fields plugin you need to:

  • Add the plugin to your application
  • Install the fields templates, so you can change them

After that, you can customize the templates to get closer and closer to the real user interface you desire.

Go to http://www.grails.org/plugin/fields to see the details of the fields plugin. You can usually simply add the following line to your BuildConfig to include this plugin into your application:


plugins {
  // ...
 compile ":fields:1.3"

}

Obviously, change the version number when new versions of the fields plugin get released.

To download the plugin locally into your application, run a Grails command such as compile:

grails compile

Run the list-plugins command to confirm that the fields plugin is installed in your application:

grails list-plugins

Once the plugin is downloaded and installed into your application, install the plugin templates with the following command:

grails install-form-fields-templates

This command installs the fields plugin templates into src/templates/scaffolding/.

Take a look at these files. You’ll see individual templates for the common GSPs of create, edit, list, and show.

With the fields plugin, you can customize these four main templates (create, edit, list, and show), or you can customize individual elements, such as how to display dates or how to align elements in a form. There are a host of other overrides you can define, all documented very nicely at http://freeside.co/grails-fields/.

I also recommend looking over Rob Fletcher’s slides at https://github.com/sjurgemeyer/GR8-US-2012. And browse the demo code at https://github.com/robfletcher/fields-gr8conf-demo/. You’ll find a lot of information to jump start your work with the fields plugin.


Dynamic vs. Static Scaffolding

With Grails scaffolding, you normally have two choices: dynamic scaffolding creates the views on the fly from the current values in the domain class. Generated scaffolding (using the grails generate-all or grails generate-views commands) creates static views as a snapshot in time for whatever fields were in the domain class when you generated the views.

With the fields plugin, you’ll find even the statically-generated files become more dynamic. By default, the fields plugin puts in the f:all tag to generate an entire form:



<f:all bean="${propertyName}"/>

The f:all tag generates your form dynamically, one field at a time. The GSP then contains the HTML and tags that go before and after your form, such as displaying the list of errors as well as the submit button. The variable propertyName gets defined at scaffolding time, that is, when you create the views.

Making Nicer Views
The fields plugin really appealed to me because of how easy it was to create much better-looking views. At the 2012 GR8Conf US session, Rob Fletcher showed a number of different user interface styles, including a very nice example of using the styles from Twitter Bootstrap.

Twitter Bootstrap, at http://twitter.github.com/bootstrap/, provides a very nice set of CSS styles to help create good-looking Web pages, along with excellent documentation. To use Twitter Bootstrap in your Grails applications, you can install one of the Grails plugins based on Bootstrap, or just download and install bootstrap.css from the Twitter Bootstrap site.

You will probably want to create a Grails layout that uses the Bootstrap row or row-fluid classes to place the basic elements of your interface, such as headers, footers, and navigation areas. You’ll also want to add your organization’s look and feel here, defining the fonts, colors, and placements needed for your application.

Once you are using the bootstrap.css file, you can set up the scaffolded forms to use the Bootstrap style for form layout. To do this:

  • Add a CSS class of form-horizontal to each form (see the create.gsp and edit.gsp templates in the src/templates/scaffolding/ directory).
  • Customize how form elements are placed into the form.

In addition to the form-horizontal class in the create.gsp and edit.gsp templates, you probably also want to make use of the Bootstrap styles for buttons, such as btn (the basic class) and btn-primary or btn-success for a nice rounded-corner gradient button style on the submit buttons.

The fields plugin lays out each property on the form using the f:field tag. You can customize this tag’s template by creating the file views/_fields/default/_field.gsp and defining your own way to lay out form elements. Luckily, one of the examples from the talk does exactly that. Look at the branches in the demo code at https://github.com/robfletcher/fields-gr8conf-demo/. One of the branches shows how to integrate Twitter Bootstrap and shows what to put into the _field.gsp file:


<%@ page defaultCodec="html" %>
<div class="control-group ${invalid ? 'error' : ''}">
    <label class="control-label" for="${property}">${label}</label>
    <div class="controls">
      <%= widget %>
    </div>
</div>

This sets up a horizontal form layout using bootstrap styles, and pretty much comes from the Twitter Bootstrap branch from the GR8Conf US code.

Generating the Scaffolded Interface

With the fields plugin, your grails command remains the same. To generate a controller and views for a given domain class, use the existing command. For example:

grails generate-all com.foo.Person

This creates the standard operations of list all items, show one item, create a new item, and edit an item.

To just generate the views, use the command:

grails generate-views com.foo.Person

While the command remains the same, with the fields plugin you will notice one quirk. The grails command first generates the GSPs the old way and then the fields plugin takes over. You will see an extra set of prompts informing you that the file create.gsp already exists and do you want to overwrite it. You’ll see this for all of the GSPs generated. Just answer yes.

Warning

Grails (old code) generates a _form.gsp with the main body of the form. This GSP is normally used as a template by both create.gsp and edit.gsp, since the majority of the form is shared by both actions. Not with the fields plugin. The template is created by the older Grails code, and then ignored. By default, you’ll see an f:all tag called in both edit.gsp and create.gsp. This generates the form dynamically, and does not use the _form.gsp template. I was quite confused by this at first when trying to make changes.

When I work with the fields plugin, I run the generate-views command again and again as I incrementally tweak the templates. This approach gives you a good idea whether your changes are improving the look of your application.


Getting Rid of HTML5

Grails generates scaffolded views with some nice HTML 5 features such as placeholder text, required and pattern attributes, and so on.

I like HTML 5, I like it a lot. But, I’m left facing two problems that are just a pain in the rear end:

First, every project I have been on has to support the browser of Pure Evil(tm), Internet Explorer. IE just doesn’t like HTML 5, at least in the versions of IE I need to support.

Second, for browsers that do support HTML 5, the ability to customize things like the client-side validation is limited. For example, if the user doesn’t fill in a required field, a client-side error appears. I need to modify the message, colors, and other aspects of this validation. Browser support is just too early to allow the full customization I need. Because of this, I usually pull out required and pattern support from the HTML 5 generation.

Improving Accessibility

To improve accessibility, you can add the WAI ARIA attribute aria-required on required fields.

To do this for String types, create the file views/_fields/string/_input.gsp. Fill in _input.gsp with:


<input class="span5" title="${label}" maxlength="${constraints.maxSize}" name="${property}" type="text" value="${value}" />

In addition to adding aria-required, I also put in a default span5 CSS class from Twitter Bootstrap to make the input widget look better.

Grails helps with accessibility by providing a * for required fields, but unfortunately, Grails puts the asterisk in the wrong place, after the label and not before. (The asterisk prior to the label sounds better when using assistive technologies like screen readers.) For example, for a prompt of a required field for the person’s First Name, the form should display:

* First Name

To change this, edit views/_fields/default/_field.gsp again and change the label section to:


<label class="control-label" for="${property}">${required? '*' : '' } ${label}</label>

Further Improving the Look

You can customize the scaffolded interface for items by type, such as string and date, or by name if needed.

In general, _display.gsp is the template used when displaying the item for the show.gsp, and _input.gsp is used in input forms. So, to customizes dates, create _input.gsp and display.gsp in the directory views/fields/date.

One quirk I noticed is that _display.gsp gets the date value passed as a String, not as a Date. The _input.gsp template gets the value as a Date. In general, I prefer to display dates in a friendlier format than the default, which includes the time down to seconds.

An important thing to remember is that you are editing what will become a Grails GSP. So, you need to escape any dollar sign ($) expressions that you want to pass through to the created template. Any ${} expressions used in the template will get resolved. Any escaped expressions will appear in the resulting template. This goes beyond Grails code, too. For example, if you use jQuery functions within your templates, you need to escape the jQuery $() function as the templating code will interpret this as an incorrect Grails expression in the format of ${expression} instead of jQuery’s $(selector).function(). For example, for the document ready function, do something like the following:

$(document).ready(function() {
 // ...
});

Note the initial backslash prior to $(document).ready(). If you don’t escape the dollar signs, the fields plugin will throw an exception when trying to generate views.

I’ve found that the fields plugin gets me very, very close to the final user interface I need, with the project-specific look, page layout, and accessibility concerns, all with just a small amount of customization.

You can find a lot more information on the excellent fields plugin at http://freeside.co/grails-fields/.

One thought on “Customizing Grails Scaffolding and Adding Accessibility with the Fields Plugin

  1. JulieChi says:

    Thanks Eric for the straightforward and very helpful info. -Julie

  2. Philip says:

    Thanks for this, I found it really helpful. The docs aren’t bad, but to be honest I would recommend that the author also link to this article. It cleared up some questions I had and got me up and running faster.

  3. grailsuser says:

    With this in my _field.gsp under _fields folder

    ${label}

    The input tags are getting escaped and hence showing up as Strings instead of being rendered as html components.

    I tried unescaping them using widget.decodeHTML() but doesnt seem to make a difference.

    Is there any other configuration I am missing to make this work?

    1. grailsuser says:

      Here is the correct code

      ${required? ‘*’ : ” }${label}

      ${widget.decodeHTML()}

  4. Lavanya says:

    This is one of the way of customizing ui when you have a template , For steps please follow

    http://www.evoketechnologies.com/blog/create-custom-ui-template-grails/

  5. I’m trying to use the field plugin to generate a search form based on my domain classes. Problem is, by default, several fields are required. I plan on providing my own custom template to handle each field so I’ve created my grails-app/views/_fields/default/_field.gsp file. But it’s never used, even when I stop and start the app (which is a simple, barebones test app).

Leave a Reply

Your email address will not be published. Required fields are marked *

*

*