Saturday, August 2, 2008

Grails with Multi Language Select Lists

Lets say you have a customer who has multiple languages spoken in their country. They need their system to support all three languages. The user will choose the language when they log in. This is easy to solved for labels by using the i18n message files.

It is not so straight forward when you need to support Select lists. In this example, I'm going to show how we can handle Address Type using i18n message files in Grails. This same concept can be applied to other type of data. E.g. Day of Week, Country.

Lets define my class. Notice, how the constraint for addressType has values of RESIDENTIAL or POSTAL. This corresponds to values in the messages.properties and messages_fr.properties(I want to support french for this application. Everyone knows the French hate speaking English).


class Address {
String addressType
String addressLine1
String addressLine2
String townCity
String postCode
String toString() {"${this.addressLine1+" "+ this.addressLine2+" "+ this.townCity}"}

static constraints = {
addressType(blank:false,inList: ['RESIDENTIAL','POSTAL'])
addressLine1(blank:false)
addressLine2()
townCity(blank:false)
postCode()
}
}


My message.properties...

address.addressType.RESIDENTIAL=Residential
address.addressType.POSTAL=Postal


My message_fr.properties...

address.addressType.RESIDENTIAL=RĂ©sidentieM
address.addressType.POSTAL=Postal


Now I need to change my gsp pages to reference the new entries in message.properties.

Firstly Create.gsp and Update.gsp, I've change the input to a select...

<tr class="prop">
<td valign="top" class="name">
<label for="addressType">Address Type:</label>
</td>
<td valign="top" class="value ${hasErrors(bean:address,field:'addressType','errors')}">
<g:select name="addressType" from="${['RESIDENTIAL','POSTAL']}" valueMessagePrefix="address.addressType" value="${fieldValue(bean:address,field:'addressType')}"/>
</td>
</tr>


Show.jsp also needs to be changed....

<tr class="prop">
<td valign="top" class="name">Address Type:</td&gt
<td valign="top" class="value"><g:message code="address.addressType.${fieldValue(bean:address, field:'addressType')}"/></td>
</tr>


And finally list.jsp...

<td><g:message code="address.addressType.${fieldValue(bean:address, field:'addressType')}"/></td>


Hope this solution helps. Comments appreciated.