Felipe Cypriano

You're about to read

Grails With ZK: Where Are My Controllers?

ZK’s zul pages works very differently compared to Grails’ gsp pages but they have one thing in common both have a class to control the page’s state, the behavior of each piece, the data that is showed or is being inserted by the user and this class is called Composer and Controller respectively. This is the second article about my work with ZK and Grails, read the first part before reading this one to get an overview: Grails with ZK Understanding Both Together.

A [grails] controller handles requests and creates or prepares the response. They can generate the response or delegate to a view.

This is the definition taken from grails website. In other words the controller receives a request do what it has to do and sends the response back.

ZK’s composers are a little different, they can do things that you’d need javascript to do using gsp and controllers. The main power of a controller is that you’ve full control of all components in the page without need to write any javascript code. You could add or remove any component dynamically from the page, register events and whatever more you java and groovy skills let’s you do.

Pages Shouldn’t Have Any Code

In both technologies you can embed code directly in the page, in gsp you can use scriptlets:

<% items.each {
    total = it.quantity * it.price
}%>

An in zul pages you can use zkscript tags:

<zkscript>
    items.each {
        total = it.quantity * it.price
    }
</zkscript>

It’s fairly easy to use code inside the pages and I really do believe you shouldn’t do this, it makes your code harder to read and a mess to maintain.

The only places where this kind of code is good is in tutorials and that’s why you’ll see lots of tutorials using it, but in your actual project the composer/controller should do this job always.

Your First Composer

To demonstrate what a composer does lets create a simple editable page. The page will show a text to the user an the user can click on some buttons to change the text. All the actions will happen without refresh and you won’t need to write any javascript.

Create a file named editable.zul in <your-project>/web-app/ with this content:

/web-app/editable.zul
1
2
3
4
5
6
7
8
9
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>

<window id="wndEditable" title="Editable Text" apply="${editableComposer}">
    <div id="divText"/>

    <button id="btnEdit" label="Edit"/>
    <button id="btnSave" label="Save" visible="false"/>
    <button id="btnCancel" label="Cancel" visible="false"/>
</window>

Pay attention to the id attribute it’s value will be used in the composer to get the java object corresponding to the component. We create an empty div called ‘divText’ just to make sure where the text will be in: at the top, before the buttons.

Now let’s go to the composer - hooray finally eh -. Create a new directory in grails-app folder called composers and inside this new directory create a file called EditableComposer.groovy.

grails-app/composers/EditableComposer.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import org.zkoss.zkgrails.GrailsComposer
import org.zkoss.zul.*
import org.zkforge.fckez.FCKeditor

class EditableComposer extends GrailsComposer {
    def divText
    def btnEdit
    Button btnSave
    def btnCancel

    FCKeditor editor
    String text

    def afterCompose = {
        // This is code execute just after all the components are created, so you can access them safely
        showText()
        viewMode true
    }

    void onClick_btnEdit() {
        if (!editor) {
            editor = new FCKeditor()
        }
        editor.value = text

        divText.children.clear()
        divText.appendChild editor

        viewMode false
    }

    void onClick_btnSave() {
        text = editor.value
        showText()
        viewMode true
    }

    void onClick_btnCancel() {
        showText()
        viewMode true
    }

    private def showText() {
        text = text ?: "This is my first Composer"

        divText.children.clear()
        divText.appendChild new Html(content: text)
    }

    private def viewMode = { isViewing ->
        btnEdit.visible = isViewing
        btnSave.visible = !btnEdit.visible
        btnCancel.visible = btnSave.visible
    }
}

The components in zul are injected in composer’s attributes with the same name as the id on zul file. On line 8 we use a specific type to declare the btnSave, this is just to show you that for each component in zul there’s a corresponding java class where you can access and/or change all the attributes. You don’t need to worry about thread safety here because for each accessed page a new composer is instantiated, this commonly known as prototype scope.

The afterCompose closure - lines 14 through 18 - is execute just after all the components declared in the zul are created and ready to use, here is the right place to put all your initialization code.

One of the features that I really like is how we can declare events to each component. As you can see in lines 20, 32 and 38 we’ve declared events to listen to the user clicks on the button for each of the 3 buttons. Basically this is how you declared all kinds events for all components:

public void onEventName_componentId(Event event)

Before the underscore character is the event name and after is the component id. You can set events even for components that you didn’t declared as composers attributes.

You don’t need to worry about javascript to change the state in the client-side ZK will handle it for you, just change the attributes values in your groovy code and you’re done. I highly recommend you give ZK a try and start playing with it, if the application you’re developing fits this desktop like model ZK is a great framework to boost your productivity.

See Also: