[Grails] Creating a weekly view of a calendar

Lately, I’ve been trying to learn Grails and started a little project as part of the learning exercise. I started off by creating weekly view of a calendar. The code for rendering this calendar can be found from my Github repository. Note: if you just want to use a calendar in Grail, you should check out the Full Calendar plugin.

The calendar is simply a table and is contained in _weekly.gsp:

<table class="calendar">
            <%-- Empty header for the time column --%>
            <g:each in="${0..<7}">
                    <g:formatDate format="E dd/mm" date="${startDate + it}" />
        <%-- Add row for each hour of the day.  --%>
        <g:each in="${(0 .. (24 * 60 * 60 * 1000) - 1).step(30 * 60 * 1000)}">

            <%-- Determine if time is a full hour. This will determine the class of the cells
            in each of the rows. --%>
            <g:set var="isHour" value="${it % (60 * 60 * 1000) == 0}" />

                <td class="${isHour ? "time-hour" : "time-half-hour"}">
                    <g:if test="${isHour}">
                       <g:formatDate format="HH:mm" date="${new Date(startTime + it)}" />

                <g:each in="${0..<7}">
                    <td class="${isHour ? "entry-hour" : "entry-half-hour"}">
                        <%-- Place holder --%>

The first <g:each> (at line 15) in the table’s body loops over each hour of the day in 30 minute increments. Time is provided in units of milliseconds, so the calculation 24 * 60 * 60 * 1000 determines the number of milliseconds in a day (24 hours in day, 60 minutes in an hour, 60 seconds in a minute and 1,000 milliseconds in a second) and 30 * 60 * 1000 is converting 30 minutes into milliseconds. Each iteration adds a row to represent the time slot. The parameters to the view are <startDate> (at line 8) and <startTime> (at line 24). Respectively, they provide the date represented by the first column and time of the first row in the table and is provided through the weekly tag in CalendarTagLib.

def weekly = { start ->
    // Figure out the time offset.
    def calendar = Calendar.getInstance()
    calendar.set(Calendar.HOUR_OF_DAY, 0)
    calendar.set(Calendar.MINUTE, 0)
    calendar.set(Calendar.SECOND, 0)
    calendar.set(Calendar.MILLISECOND, 0)
    out << render(template: "weekly", model: [startDate: start['start'], startTime: calendar.getTimeInMillis()])

The tag takes in the date of the first day to display in the calendar (the start parameter), calculates the time of the first row and renders the _weekly template. Now the tag can be used to draw the calendar:

<g:weekly start="${new Date()}" />

The resulting calendar should look something like this:


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: