In this post I am going to show you how you can write a custom tag to use the JQuery UI datepicker instead of the <g:datePicker> tag provided by Grails out of the box.
How <g:datePicker> tag works
When you have a Date field in your Grails domain class and have generated the default views for that domain you will notice that the date field(s) will be defaulted to three drop down boxes (year, month, day). Upon submit four request parameters will be sent as part of the <g:datePicker> tag. Say that our date field in our domain is declared as orderDate. The request parameters associated with that request would have the following naming convention:
orderDate
orderDate_day
orderDate_month
orderDate_year
All these parameters are necessary for grails to do the appropriate binding to the orderDate field and to successfully save to the database.
What if I do not want to use Grails default date picker?
While this is good, since Grails provided it for free without writing a single line of code, it is not very efficient for the end user to have to select three drop downs. I usually use the JQuery UI framework a lot in my Grails and Spring apps for widgets and DOM Scripting. Do as follows:
- Download your favorite Jquery theme.
- Unpack it, look at the demos (Specially at the path structure for js, css, and themes)
- Bring that into your Grails web-app folder
- Copy the themes folder from the download straight out of web-app folder.
- Create a jquery folder under js.
- Put jquery-1.4.4.min.js under jquery folder created in previous step.
- Copy the ui folder from the download to the jquery folder created in step 2.
That should give you the proper setup for you to start adding jQuery and jQuery UI components to your application.
Next I will show how to bind a Jquery date picker to a grails date field in a domain class in two different ways. They are as follows:
- Without writing a Grails custom tag
- Writing a Grails custom tag
Using Jquery date picker without using Grails custom tags
Step 1: Enter the following in head of your create.gsp
Image may be NSFW.
Clik here to view.
Step 2: Replace the g:datePicker tag with
Step 3: Create the following Javascript file coche.js. This is responsible for populating the hidden fields once a date has been selected. The code is as follows:
$(document).ready(function() { $( "#orderDate" ).datepicker({ onClose: function(dateText, inst) { $("#orderDate_month").attr("value",new Date(dateText).getMonth() +1); $("#orderDate_day").attr("value",new Date(dateText).getDate()); $("#orderDate_year").attr("value",new Date(dateText).getFullYear()); } }); });
Step 4: Run your grails application go to the create.gsp select a date through the calendar and click on create. You should have your custom orderDate field successfully binded in the domain orderDate field just like if you would have used the default <g:datePicker> grails tag.
A jQuery Date Picker Grails Custom Tag
There is nothing wrong with the first approach but it has a couple of disadvantages:
- For every jquery date picker that I want to add to the form I have to remember to add three extra hidden input fields with the naming convention dateDomainFieldName_year, dateDomainFieldName_month, dateDomainFieldName_day.
- For every jquery date picker field that I have in a single page I will have to add about 8 lines of code of Javascript to populate the hidden fields once a date has been selected.
So my goal is to write a Grails Custom tag that will be responsible for doing the two things above. Additionally it will work for as many date fields you want in your form.
Step 1: Create a Grails Tag Lib as folllows:
Image may be NSFW.
Clik here to view.
Step 2: Replace your input orderDate and associated hidden fields for this:
Image may be NSFW.
Clik here to view. Step 3: Delete the coche.js
Step 4: Remove the coche.js reference from the head tag in your create.gsp
You should be able to add many jQuery calendars without having to do DOM scripting to populate hidden fields as the custom tag is already doing it for you.
Conclusions
The grails tag for the jQuery UI date picker widget has the advantages as follows
- It creates three hidden input fields dateField_day, dateField_month, dateField_year.
- It’s responsible for populating these hidden input fields when a date has been selected from the calendar.
- Supports having multiple date fields in the same form without any conflict.
The Code
The code can be found at this github repository https://github.com/dariopardo/JQueryDatePickerGrailsTag