Home > Allgemein > Visual Indicating Constraints in Grails View Generation

Visual Indicating Constraints in Grails View Generation

September 17th, 2009 Leave a comment Go to comments

There was thread in the gr8forum recently regarding assigning css classes on property input fields depending on associated constraints. I think this is a nice idea and played around a bit and it turned out that this is quite simple. Here is my solution without changing grails source code.

At first you have to install Artifact and Scaffolding Templates using:

grails install-templates

This will install the templates that will be used for static scaffolding to src\templates.
Now you can customize them by simply editing the appropriate file, e.g., \src\templates\scaffolding\Controller.groovy if you want to change the Controller template.

At first I define for which Constraints I care, e.g.,

def iCareAbout = [org.codehaus.groovy.grails.validation.ConstrainedProperty.BLANK_CONSTRAINT, org.codehaus.groovy.grails.validation.ConstrainedProperty.NULLABLE_CONSTRAINT]

A property with constraints applied is represented as ConstrainedProperty. There is a method name called getAppliedConstraints where you get a Map of applied constraints to that property. Then you need to filter out the ones you care about.

Base class for all Constraints is AbstractConstraint but there are subclasses for special constraints like AbstractVetoingConstraint for nullable and blank and AbstractPersistentConstraint for unique constraint that may need access to database (for generating id on some databases).

Alltogether this looks like:

cp.getAppliedConstraints().findAll{i -> iCareAbout.contains(i.name) }.each { it.each { print it.constraintParameter?" " + it.name:" not" + it.name } }

This iterates over the constraints you care about and looks at the constraintParameter, which is a Boolean (at least for blank and nullable), is set. If it is set it prints the name of the constraint, if not it prints “not” + the name.

This enables you to style the elements later through css classes.

<tr class="prop<% cp.getAppliedConstraints().findAll{i -> iCareAbout.contains(i.name) }.each { it.each { print it.constraintParameter?" " + it.name:" not" + it.name } } %>">
	...
</tr> 

The full file can be downloaded here.

For a Domain class like

class Book {
	String name
	Boolean inLibrary
	
	static constraints = {
		name(blank: false, matches:"[a-zA-Z]+") 
		inLibrary(nullable: false)
		}
		
}

The output would look like:

<tr class="prop notblank notnullable">
	<td valign="top" class="name">
		<label for="name">Name:</label>
	</td>
	...
</tr> 

<tr class="prop notnullable">
	<td valign="top" class="name">
		<label for="inLibrary">In Library:</label>
	</td>
	...
</tr> 

Notice the not nullable constraints applied automatically and the matches constraint is not taken into account.

BTW: There is also a open issue in the JIRA about that http://jira.codehaus.org/browse/GRAILS-270 so if you are interested then you can watch and vote it.

Categories: Allgemein Tags:
  1. No comments yet.
  1. No trackbacks yet.

CommentLuv badge