jQuery-style Enterprise Application Development with ZK and Grails

DZone 's Guide to

jQuery-style Enterprise Application Development with ZK and Grails

· Java Zone ·
Free Resource


Grails is a modern web application framework with the powerful plugin architecture. To make Grails better fit requirements for developing enterprise Rich Internet Applications (RIA), the ZK plugin for Grails (aka ZKGrails) comes to fill this gap. For the user-interface part, ZK provides a huge set of enterprise-ready compoments, called ZUL, to let us develop an RIA quickly. While Grails serves as a rock-solid framework for back-end as it features seamless Spring integration and the powerful GORM layer based on Hibernate.

In this article, I'll introduce a new set of APIs, which is based on the familiar jQuery-style, in ZKGrails 2. As required by law, I am demonstrating the use of this new APIs via a Todo application.

Getting Started 

We start by creating a new Grails application, name it as todo.

$ grails create-app todo
$ cd todo

To install the ZK plugin for Grails, add line compile ":zk:2.0.4" into the plugins block in grails-app/conf/BuildConfig.groovy, like this (your plugins configuration may vary):

plugins {

    runtime ":hibernate:$grailsVersion"
    // other plugins go here

    compile ":zk:2.0.4"


We then create a domain class to be our task entry, namely todo.Task, using the following command:

$ grails create-domain-class task
Inside grails-app/domain/todo/Task.groovy, we add two properties, subject for storing the task's subject and done for storing completion status.
package todo

class Task {

    String  subject
    Boolean done = false

    static constraints = {


ZUL Markups 

Next, we create a ZUL and a Composer using the create-zul command.

$ grails create-zul todo 

The above command gives us a ZUL page, todo.zul, and TodoComposer.groovy (under directory grails-app/composers/todo/). The following is todo.zul, which can be found under directory grails-app/zul:

<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>

<zk xmlns="http://www.zkoss.org/2005/zul"
    xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd">

        .strike {
            text-decoration: line-through;

    <window apply="todo.TodoComposer">

        <hbox align="center">
            <image src="${z.resource(dir:'images', file:'zkpowered_s.png')}"/>
            <image src="${z.resource(dir:'images', file:'grails_logo.png')}"/>
            <hbox align="center">
                <textbox id="txtAddTask"/>
                <button  id="btnAddTask">Add Task</button>
            <vbox id="list"/>



In todo.zul, the real UI starts from line 22. At line 27, we have tag <vbox id="list"/> to hold the todo list. Tag <textbox id="txtAddTask"/> at line 24 is for entering a new task subject, which of course will be stored into the subject of a Task object.


Let's see inside the TodoComposer how we will create UIs for each task entry.

package todo

import org.zkoss.zk.grails.composer.*

class TodoComposer extends GrailsComposer {

    def afterCompose = { window ->
            .on('ok', {
                addTask $(it).text()

        $('#btnAddTask').on('click', {
            addTask $('#txtAddTask').text()

    def addTask(subject) {

        def task = new Task(subject: subject).save()
        def id   = task.id

        $('#list').append {
            hbox(id:"task${id}") {
                textbox(inplace: true, value: subject)
        $("#task${id}").link(task, [
            done:    'checkbox',
            subject: 'textbox'
        $("#task${id} > checkbox").on('check', {
        $("#task${id} > textbox").on('change', {

A composer is basically the "C" in the MVC pattern. TodoComposer is responsible for manipulating the UI, read/write data from the model layer, which is GORM of the Grails framework.

In TodoComposer, we have "afterCompose" at line 7, which is a closure similar to jQuery's $(document).ready(). We start binding event handlers here. In ZK, an "onOK" event will be fired when we press the enter key on a textbox. In ZKGrails 2, we can bind to this event similarly to what we can do in jQuery, as shown at line 8-11. Note that we use .on('ok', {...}).

Every time we enter a new subject string, the event handler will call method addTask (line 19). Please note that at line 10 and 15, I intended to write calls to method addTask without parentheses, as permitted by Groovy.

Method addTask, starting at line 19, is responsible to create a new Task object, set its subject and save to the database, via GORM. This is simply done by a single line of code at line 22.

We create a UI block for a task entry at line 25-30. Calling $('#list') is, of course, to select the <vbox id="#list"/> in the above ZUL file. The built-in builder implementation, ZKBuilder, works here at line 25 after calling method append. A horizontal box (hbox), a checkbox and a textbox are created for the task entry. All of them are ZK's UI components similar to ZUL tags.

A coolest part of this article is the data-binding feature at line 31. ZKGrails 2 uses the ZK's data-binding facilities to directly bind domain objects to UI elements via method link. The syntax here is similar to the jQuery's link plugin. We bind each property of the Task object, done and subject, to a "checkbox" and a "textbox", respectively. The syntax of CSS3 selector is used here for selecting a certain UI element.

Next, we bind event handlers to save the Task object to the database, every time the checkbox is checked/unchecked as well as when the Task's subject is changed. You can see that there's some familar feature for changing a CSS attribute too, at line 37.


To conclude, ZKGrails 2 brings a set of jQuery-like APIs to enterprise by making it works seamlessly with the Grails ORM layer. Combining a familar syntax of jQuery and the powerful Grails stack lets you boost productivity when developing an enterprise application to another level. Try it yourself!


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}