Tuesday, March 17, 2009

Nullable vs blank constraints, want feedback from you?

So a few people asked me about my comment i made on my new javascript validation grails plugin about blank vs nullable constraints.

Well the problem i have is. In javascript validation on strings "blank" and "nullable" checks are the same thing. By default grails adds nullable constraints to all attributes of a domain object. So:

When I generate javascript validation checks based on these default constraints I generate a "required" check for each attribute. So the "nullable" constraint maps to a "required" check in javascript.

The problem is the "blank" constraint also maps to a "required" check. So a string attribute has a nullable=false constraint (which it has by default) AND a blank=false constraint then the use will end up seeing TWO message: Eg

You must enter a name (nullable message)
You must enter a name (blank message)

To the user this is duplicate messages.

I have this idea:
When processing the constraints and generating the javascript validation. The nullable constraint is ignored for String attributes and the blank contstraint is used instead. This would mean if you want to have a javascript required check for a string you must use the blank constraint.

What do you think ?

Monday, March 16, 2009

Creating your own grails plugin and eating your own dog food

So as you may have seen in my last few posts. I spent most of the weekend creating my first grails plugin. My lovely wife is away for 3 weeks on holiday so I am blasting out all the little projects that I have wanted to do.

So I thought I would just write a little piece about my experience of writing the plugin. First thing i would like to say is what a pleasure it was to write and as how easy it was. So how did it come about.

Well I have been building my own application in grails for the last few months and one thing I really missed was client side javascript. I was quite suprised to find that there was no direct support for this in grails. In my day job we use the valang library that has greate support for generating client side javascript so I had gotten used to it. One thing I did find was this disbandond tag lib that sits in the grails core validate tag. So i looked at the source code for this tag and figured out what is was trying todo. It turns out that is was using the javascript support of the commons validation libarary.

So after some experimentation I realised I could resurect this and put it together as plugin to support client side javascript. So after some complicated things like getting access to the constraints object of command objects and generating i18n messages for the errors I finally put together the plugin in 4 releases over a weekend.

So things i found hard to do and never really managed to do it in a nice way was to mock out the grailsattributes object and grails application etc. My tag needs these to get access to domain and command objects but it is very complicated to mock them out.

Eating your own dog food.

So before i actually realeased the plugin i installed it in my own application and started using it in a real app. This turned out to be essential for testing. I found several issues that it did not handle. Things like: grails auto generating nullable constraints for all attributes of a domain class but not for command objects was tricky as you ended up with unecessary validation generated. So after a few rounds of tuning and robusting i realesed it.

Grails plugin release process.
It is so easy to release and re-release a grails plugin that you have to create one just to see that work. Auto tagging and versioning is handled so smoothly. But i guess i would not expect anything less from grails.

So to conclude if you have any greate ideas for a plugin then build them. There is nothing stopping you.

Remember someone once said that the saddest words of tongue or pen are these: "it might have been".

Ps. Version 0.4 is out now :)

Enjoy

Sunday, March 15, 2009

Posted version 0.3 of the javascript-validator grails plugin

Hi All

I just posted version 0.3 of the javascript-validator plugin. This update adds support for validating data type conversions. Only numeric (integer and decimal) are supported at the moment.

So if you try set a non numeric value on a field that is an interger then you will get the standard error.

thanks

Saturday, March 14, 2009

Added documentation for the Javascript Validation plugin

Hi All

OK I got some sleep and I have added some documentation for the new Javascript Validation plugin:

This can be found here.

http://www.grails.org/JavascriptValidator+Plugin

Please give me have feed back.

Friday, March 13, 2009

New: Client Side Javascript Validation plugin for Grails

So I created a grails plugin and i think it will be useful to everyone on a grails project.

So what does it do?

Well it is a client side javascript validator plugin that works with your existing constraints object. All you have to do is install it then put single tag on your page and you get instant javascript validation for your existing forms.

To install:

grails install-plugin javascript-validator


Next simply add this tag to your form page. This will show the errors as an alert box.

<jv:generate domain="book" form="bookForm" display="alert" />


Finally you then need to add an onsubmit event to your form. I may make this optional in the next release. But you need it for now.

<form action="/save" method="post" name="bookForm" id="bookForm" onsubmit="return validateForm(this);" >
...
</form>




If you want the error messages to show as list on the page do this:

<jv:generate domain="book" form="signUpForm" display="list" container="errors"/>



If you want validation on command objects then do this:


<jv:generate command="signUpCommand" controller="signUp" form="signUpForm" display="alert" />


<jv:generate command="signUpCommand" controller="signUp" form="signUpForm" display="list" container="errors"/>


That should get you going.

I need to write up the full documentation but will try to do that at the weekend. For now i am off to sleep.

Enjoy...

Tuesday, March 10, 2009

Groovy Meta programing to help with names in grails

So in my new app I have several places where a user can enter a persons name. In most places they enter a first name and surname. But on one form they enter a full name. Now ideally i would like to have the first letter of the first name and surname capitalised. As you can't rely on users to do this and not wanting to punish them for not doing it then i decided to implement my own conversion.

Now in java i can imagine some crazy ways to do it. However probably the simplest in java would be to use the commons lang libs that have support for doing just that. (capitalize)

However i want to solve this in a "groovy way".

So after reading the groovy programming book I got some inpiration to use groovy meta-programming to solve the problem.

Groovy allows you to effectivly add new methods to java classes. In this case String. So on String i want to add two new methods: capitalizeFirstLetter and capitalizeAllFirstLetters. So to do this i just do this:

String.metaClass.capitalizeFirstLetter = {
return ("" == delegate) ? delegate : delegate[0].toUpperCase() + delegate[1..<(delegate.length())]
}

String.metaClass.capitalizeAllFirstLetters = {
return ("" == delegate) ? delegate : delegate.split(" ").collect{it[0].toUpperCase() + it[1..<(it.length())] }.join(" ")
}



Then when I want to use them i just do this:

assert "".capitalizeFirstLetter() == ""
assert "peter".capitalizeFirstLetter() == "Peter"
assert "peter delahunty".capitalizeAllFirstLetters() == "Peter Delahunty"



In Grails you just pop the metaClass definitions into your boostrap.groovy and they will be available all throughout grails.

Schweet...

Grails 1.1 is out.... yeah (this has some major awesome new features.

So i just heard on the twitter vine that Grails 1.1 is officially released.

Release notes

This update has some major awesome updates: My favorites:

  • Batch fetching
  • Improved dynamic finders
  • Read only loads
  • New plugin architecture (this is a big one)
  • Integrated test plugin
  • Maven integration
  • New Webflow
I am off to download now.

Monday, March 9, 2009

Hell with vista and ipv6 and hosts file

hmmm

Just had an amazing amount of time wasted whilst building a grails app. Still not exactly sure what they hell happened here. I think maybe and auto update on vista. Anyway I have had a problem for the last 2 hours with my grails apps suddenly not being able to connect to my local mysql instance. So i knocked up a small java app that just connected to the db and it had the same problem.

I could connect just find from the command line with mysql client but not java. Anyway after much much digging it seems to have been maybe a change to my hosts file.

it did say this:

#############
::1 localhost

and when i tried to connect via java to url jdbc:mysql://localhost/test then i got a nasty connection refused.

However when i changed this to

#############
127.0.0.1 localhost

Now it all seems to work.

It seems from searching around that the ::1 setup is for ipv6. Anyway jus thought i would document this ask it was painful to fix.

Maybe i should move back to ubuntu. See if they have fixed the rendering in java on linux finally.

Thursday, March 5, 2009

Available very soon, me !!!

So it seems my latest contract is coming to an end at the end of the month (march 2009). So the what to do next???

Well I have a big backlog of my own good ideas that I want to put some quality time into. Before releasing into the wild to see which ones float and which ones sink. I should imagine I would give myself a solid month of work to get them off the ground. My aim is to get these ideas developed and shipped as quick as possible so I will of course be using Grails. Which brings me to my next question, then what ?

Developing my own ideas is my first choice at the moment unless some awesome gig comes up :)

So I ask: Is there anyone out there ???

Is anyone planning on building anything cool in Grails using Agile development. A funded starup maybe? Are you looking for a new lead Grails developer. I would really like to get into something exciting and really have my skills pushed to the limits and beyond.

Basically if you can dream it I can build it. So challenge me ?

Drop me an email peter.delahunty@gmail.com

Monday, March 2, 2009

Top 10 Tips for Grails Developer: Redux (extra bonus tips)

Ok so in my last post about Grails Top 10 Tips i realised I did not really give that many actual grails specific tips :)

So i had long think about the way I use grails and I think I have some more tips. These tips are for when you are doing serious development and not just some throwaway prototype.


1) Follow domain driven development.

This is very very easy to do in grails and is practically common sense to do so (ha ha although in my experience there is no such thing as common sense). So what i mean by this is to follow test driven development starting with your domain first (tddd i guess). Create your domain objects first using the grails macros "grails create-domain". This will also then generate your unit tests for you (how easy is that). Then start fleshing out the unit tests. To make life easy use this plugin (installed default in grails 1.1)

Testing plugin

Now if you can delay gratification and fully develop your domain model first just using unit tests then this will pay off later. You will see as i explain below.

However if you can't wait and you need to see the app come to life then create a controller using "grails create-controller" and use the lovely grails scaffold to have your crud pages generated for you.

Section 16 of the grails docs

However once you are happy with the domain from the view point of the webpages. Then delete the new scaffold controller because the real deal is about to be generated below.

So by now in some shape or form you should have developed your domain model. Or more specifically the parts that you need right now to meet the stories (features) you are building (sorry i have my agile hat on here).

So now you can pull one of the grails gems out of the bag "grails generate-all" or one step better you can install the xtemplates plugin

xtemplate plugin

Then using this plugin you can use "grails uber-xgenerate" and this will create controllers, views and unit tests for all CRUD operations of your new domain model.

This now basically gives you a working app. All you have to do is skin it how you want.


2) Change your default development datasource settings

Once you are building a serious grails app you are going to want to change from the default hsql in- memory database. I actually prefer to use mysql as my deployment db as i can query it easily from the commandline.

Edit datasource.groovy to something like this:

dataSource {
pooled = true
driverClassName = "com.mysql.jdbc.Driver"
username = "testuser"
password = "testuser"
}
hibernate {
cache.use_second_level_cache=false
cache.use_query_cache=false
cache.provider_class='com.opensymphony.oscache.hibernate.OSCacheProvider'

}
// environment specific settings
environments {
development {
dataSource {
println "IN DEVELOPMENT"
dbCreate = "create-drop" // one of 'create', 'create-drop','update'
url = "jdbc:mysql://localhost/testdb"
dialect = "org.hibernate.dialect.MySQL5Dialect"

}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:hsqldb:mem:testDb"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:hsqldb:file:prodDb;shutdown=true"
}
}
}



3) Use bootstrap.groovy
This is a very important file. It allows you to populate your database with with your domain model. Here you can create test data and save it to the database.


4) Use command objects
I find these little guys are very useful in some circumstances. Sometimes you want to capture user data using a form that does not exactly map to the way you want to store you info in your domain object or perhaps the information does not even get saved. Examples would be an advanced search form or a file upload form. The great thing about Command objects is they still allow you to specify validation constraints. Here is an example:

class DemoFormCommand {

String email;
String name;

static constraints = {
name(blank: false)
email(blank: false, email: true)
}
}



Then in my controller i can add an action like this:

def upload = {DemoFormCommand demoFormCommand ->

if (demoFormCommand.hasErrors()) {
....

}