Felipe Cypriano You are about to read it

4Mar/100

Grails with ZK: How To Create Components in Runtime with The Builder

ZKGrails plugin has an extremely nice feature which make easier than ever to create ZK components in runtime.

First lets see how is the usual way to create components in runtime using Java. This is the zul representation of what we’re trying to achieve:

<div>
  <toolbarbutton label="Clickable Item" href="#" />
  <toolbarbutton image="edit.png" if="${userHasAccess}" />
  <toolbarbutton image="delete.png" if="${userHasAccess}" />
</div>

And the java code to do the same:

Div div = new Div();
Toolbarbutton tbb = new Toolbarbutton("Clickable Item");
tbb.setHref("#");
tbb.setParent(div);
if (userHasAccess) {
    Toolbarbutton tbbEdit = new Toolbarbutton();
    tbbEdit.setImage("edit.png");
    tbbEdit.setParent(div);
    Toolbarbutton tbbDelete = new Toolbarbutton();
    tbbDelete.setImage("delete.png");
    tbbDelete.setParent(div);
}

As you can easily see the java code is pretty verbose. Using ZKBuilder the code will be easier to understand and smaller, take a look:

Div div = new Div();
div.append {
    toolbarbutton(label: "Clickable Item", href: "#")
    if (userHasAccess) {
        toolbarbutton(image: "edit.png")
        toolbarbutton(image: "delete.png")
    }
}

Which one do your prefer? :) If you want more continue reading to see how to use the builder as a template to a list of items.

Using ZKBuilder as a Template

15Jan/103

Handling events on ZK macro components

One of the great features of ZK is the possibility to create a new component based only on other existing components using the declarative language ZUML - the same you've been using in you zul files. Those are called Macro Components. The beauty of macro components is that it's very easy to make a new one and hence avoid code duplication on your pages.

Talk about how to implement a macro component isn't the scope of this post, so I suggest you to read the documentation before continue reading.

We'll work on a very simple macro component. But, don't hesitate when you need to make a very complex one. Our macro component is this: WEB-INF/mymacro.zul

<hbox>
    <label id="myLabel" value="Click the button"/>
    <button id="myButton" label="The Button"/>
</hbox>

Now that you already knows what is and how to make a macro component, let's start talking about what you may think it'll work but actually it doesn't.

Automatically Forward Event Doesn't Work

The standard way to register events on ZK's component, using MVC, is to use the "autowire" feature of GenericForwardComposer. Like this:

WEB-INF/index.zul

<?xml version="1.0" encoding="UTF-8"?>
<zk>
    <window apply="com.felipecypriano.IndexComposer">
        <label id="lblOutside"/>
        <button id="btnOutside" label="Not In Macro"/>
    </window>
</zk>

src/com/felipecypriano/IndexComposer.java

package com.felipecypriano;

import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Label;

public class IndexComposer extends GenericForwardComposer {
    private Label lblOutside;

    public void onClick$btnOutside() {
        lblOutside.setValue("Button 'not in macro' clicked");
    }
}

The button 'btnOutside' belongs to the window component and therefore its composer can automatically access and configure btnOutside events. When the Composer is initializing it detects the method onClick$btnOutside() and sets this method as a 'btnOutside' onClick event listener, in other words when the component is clicked this method is executed.

Knowing this we can think that add an event to 'myButton', which belongs to 'mymacro', is pretty much the same. Don't we? Let's add the macro in the index.zul and create a new method to handle onClick event of 'myButton':

WEB-INF/index.zul

<?xml version="1.0" encoding="UTF-8"?>
<?component name="mymacro" macroURI="/mymacro.zul" ?>
<zk>
    <window apply="com.felipecypriano.IndexComposer">
        <label id="lblOutside"/>
        <button id="btnOutside" label="Not In Macro"/>
        <separator bar="true"/>
        <mymacro/>
    </window>
</zk>

Just before <zk> tag is the macro component definition (line 2), this directive tells to ZK where is the file that contains the component - macroURI="/mymacro.zul" -  and what's the tag name we'll use - name="mymacro" - to reference our component (line 8).

Adding the onClick event on 'myButton' cannot be done by just adding this method to IndexComposer:

src/com/felipecypriano/IndexComposer.java

    public void onClick$myButton() {
        lblOutside.setValue("Button 'myButton' clicked");
    }

So, if this doesn't work what should I do?

Using a Speciliazed Class

To take care of mymacro's behavior we need to write some code. We need to create a class to specifically handle our component's needs. The purpose of mymacro component is to update the label when the button is clicked, this will not affect any of the components that doesn't belong to mymacro so it makes sense to put the event in a specialized class that can be used to all pages.

The two components inside the macro - label and button - will be accessed using getFellow(string) method and the event will be dynamically added to the button using addEventListener method.

src/com/felipecypriano/MyMacro.java

package com.felipecypriano;

import org.zkoss.zk.ui.HtmlMacroComponent;
import org.zkoss.zk.ui.event.*;
import org.zkoss.zul.*;

public class MyMacro extends HtmlMacroComponent {
    private Label myLabel;

    @Override
    public void afterCompose() {
        super.afterCompose(); // DON'T forget this
        Button myButton = (Button) getFellow("myButton");
        myLabel = (Label) getFellow("myLabel");

        myButton.addEventListener(Events.ON_CLICK, new EventListener() {
            public void onEvent(Event event) throws Exception {
                myLabel.setValue("Hooray! 'myButton' was clicked.");
            }
        });
    }
}

Now change the component's definition to point to MyMacro.java as the component's class:

<?component name="mymacro" macroURI="/mymacro.zul" class="com.felipecypriano.MyMacro" ?>

Voilà.

Global Component Definition

There's a DRY principle violation and we must solve it. The main reason to use a macro component is to share a set of components between multiple pages, to avoid code duplication. The macro itself does this, but if you pay attention you'll see that the component's definition must be at the very beginning of each page which wants to use the component and this, definitely, isn't a good a thing.

For instance, supposing that you have 25 pages that are currently using the macro component, and in each one of them has the component's definition. Some months later, for some reason, you must change yours component's class. Instead of changing just one simple place you'll have to update 24 more places. Keep your code simple and don't repeat anything.

In order to make the component's definition global we need to create a new xml file called lang-addon.xml:

WEB-INF/lang-addon.xml

<language-addon>
    <addon-name>myaddon</addon-name>
    <language-name>xul/html</language-name>
    <component>
        <component-name>mymacro</component-name>
        <component-class>com.felipecypriano.MyMacro</component-class>
        <macro-uri>/mymacro.zul</macro-uri>
    </component>
</language-addon>

WEB-INF/zml.xml

<zk>
    <language-config>
        <addon-uri>/WEB-INF/lang-addon.xml</addon-uri>
    </language-config>
</zk>

And at last, remove <? component ?> directive from index.zul. From now on mymacro component is available to all zul pages in your application.

Making the macro component shout to the world

Just one more detail to learn, the component can handle its own components events, but how do the page that has the macro component knows what's going on? We need to make the macro component send events to the page, or any listener. And this is the our final step.

To keep it simple the macro component will respond just to onClick event, that's when the button is clicked 'myLabel' will be update as usual and the macro component will send the onClick event to all its listeners. Replace myButton EventListener with the following code:

src/com/felipecypriano/MyMacro.java

myButton.addEventListener(Events.ON_CLICK, new EventListener() {
    public void onEvent(Event event) throws Exception {
        myLabel.setValue("Hooray! 'myButton' was clicked.");

        if (isListenerAvailable("onClick", true)) {
            Event clicked = new Event(Events.ON_CLICK, getParent());

            Iterator listeners = getListenerIterator(Events.ON_CLICK);
            while (listeners.hasNext()) {
                EventListener listener = (EventListener) listeners.next();
                listener.onEvent(clicked);
            }
        }
    }
});

The code between lines 5 and 13 is responsible to send the event to the listeners. But we need a couple more changes, like make IndexComposer listen to mymacro. First put an id in mymacro:

WEB-INF/index.zul

<mymacro id="mymacro"/>

And register the event using the standard way in IndexComposer:

    public void onClick$mymacro() {
        lblOutside.setValue("I can hear you 'mymacro'!");
    }

With all this it's possible to do complex and incredible powerful macro components. Go ahead and try.

Tagged as: , 3 Comments
10Dec/0920

Grails with ZK: Embedding ZUL in GSP

How about zk pages and gsp were so friends that we could use both together? Imagine the possibility to use Sitemesh to decorate your page or use UrlMapping to choose what the URL will be. Or you could move your project to ZK painlessly, you could update the pages one by one and the new code will work side by side.

ZKGrails plugin 0.7.6 has been released with this great new feature, you can use two simple tags to include any zul page in your GSP. To include the necessary css and javascript into head use <z:head/> and to insert the content anywhre you want in the body of your gsp you'll use <z:body/>.

To see it in practice let's change Grails Quick Start. Follow the steps described there and after you complete all the steps, go back here to update the list.gsp to use ZK Grid component. Don't forget to use Grails 1.1.2 and ZKGrails 0.7.6 at least.

Embedding ZK in GSP

Firstly create this file: grails-app/conf/BuildConfig.groovy and configure ZKGrails repository:

grails.plugin.repos.discovery.zkgrails = "http://zkgrails.googlecode.com/svn/plugins"
grails.plugin.repos.resolveOrder = ['zkgrails','default','core']

Now you can install ZKGrails version 0.7.6 by executing grails install-plugin zk 0.7.6. After installing ZK plugin, create the zul page we'll use: web-app/book/list.zul. You can let this file blank for now, before editing it we need to change automatic scaffolding by creating the the gsp pages  executing this command:

grails generate-views Book

The command will create 4 gsp files in grails-app/views/book: create.gsp, edit.gsp, list.gsp and show.gsp. We will change the list.gsp to instead of use simple HTML table we'll use ZK components. Now let's get back to our web-app/book/list.zul, the objective is to create a grid using zk components and to add a new functionality to delete all selected books. Open list.zul file and put the following code in it:

<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="./wnd"?>
<zk xmlns:n="http://www.zkoss.org/2005/zk/native">
    <window id="wnd" apply="${bookListComposer}">
        <listbox id="listBoxBooks" model="@{wnd$composer.booksModel}" checkmark="true" multiple="true"
                 fixedLayout="true" width="500px">
            <listhead>
                <listheader label="ID" sort="auto(id)" width="50px"/>
                <listheader label="Author" sort="auto(author)" width="225px"/>
                <listheader label="Title" sort="auto(title)" width="225px"/>
            </listhead>
            <listitem self="@{each=book}" value="@{book}">
                <listcell label="@{book.id}"/>
                <listcell label="@{book.author}"/>
                <listcell label="@{book.title}"/>
            </listitem>
        </listbox>
        <n:span class="buttons">
            <button id="btnDelete" sclass="delete" mold="os" label="Delete Selected"/>
        </n:span>
    </window>
</zk>

Next step is create the composer for this list.zul page, the composer is the thing that controls the page's behavior, just like a controller. Create a BookListComposer.groovy file in grails-app/composers, and this is the content:

import org.zkoss.zkgrails.*
import org.zkoss.zkplus.databind.BindingListModelList

class BookListComposer extends GrailsComposer {

    def wnd
    def listBoxBooks
    def booksModel
    def binder

    def afterCompose = {
        booksModel = new BindingListModelList([], true)
        reloadBooks()
        binder = wnd.getVariable("binder", true)
    }

    public void onClick_btnDelete() {
        if (listBoxBooks.selectedCount > 0) {
            listBoxBooks.selectedItems.each { listItem ->
                def book = listItem.value
                book.delete(flush: true)
            }
            reloadBooks()
        }
    }

    private def reloadBooks() {
        def books = Book.list()
        booksModel.clear()
        booksModel.addAll(books)
        binder?.loadAll()
    }

}

Now we only need to put the zul page in the list.gsp replacing the HTML <table> tag to <z:body />, the final code is this:

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <meta name="layout" content="main" />
        <z:head />
        <title>Book List</title>
    </head>
    <body>
        <div class="nav">
            <span class="menuButton"><a class="home" href="${resource(dir:'')}">Home</a></span>
            <span class="menuButton"><g:link class="create" action="create">New Book</g:link></span>
        </div>
        <div class="body">
            <h1>Book List</h1>
            <g:if test="${flash.message}">
            <div class="message">${flash.message}</div>
            </g:if>

            <z:body />
        </div>
    </body>
</html>

As you can see - lines 5 and 19 - we only need to put the tags where we want it's content to be in the page. But you might be wondering where is the path to list.zul file? By default the same convention used by Grails' view, so for our example both tags - head and body - automatically resolves to /book/list.zul. And if you need to specify the files you want you can by setting the attribute zul, like:

<z:body zul="/path/to/file.zul" />

Now we can mashup our both favorite frameworks to make our projects look and behave even better.

# Update 1

Fixed a missing namespace on zul file; and the binder call on BookListComposer. Thanks André.

# Update 2

GitHub repository with full source code used to made this post: http://github.com/fmcypriano/embedding-zul-gsp

Tagged as: , , , 20 Comments
19Nov/090

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:

<your-project>/web-app/editable.zul

<?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

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:

Tagged as: , , No Comments
7Nov/092

Grails with ZK Understanding Both Together

You may already know both technologies but I'll briefly introduce them. Grails is the best web framework that I ever work with, it uses Groovy and convention over configuration to simplify our development efforts. To name a few this is what you've out-of-the-box: persistence layer to save your entities to a relational database, dependency injection, lots and lots of great plugins and GSP to build the view.

If Grails is so complete why do I need another framework and why ZK? I'm building an enterprise web app which means it will be used by users of a company to do daily tasks, I needed a more responsiveness app without refresh and without increase the effort of getting it done. Searching for a solution I consider mainly this two frameworks: ExtJS, beautiful interface and a bunch of built-in components but you've to deal with javascript; GWT clever javascript compilation from Java code, but only a few built-in components and build interfaces using only java code isn't a pleasant work for me.

ZK Direct RIA is bundled with lots of very useful built-in components, you can build your pages using a declarative syntax like XHTML or using Java code, since we'll use Grails we can use Groovy to simplify the java code. Your code is processed on the server and because of this you can use your classes without any modifications, all your classes groovy or java will work as is in ZK no modification is need.

ZK will be responsible to render and process the events of the view layer (the pages), the main difference compared to standard Grails is that instead of use Controllers and gsp files you'll use Composers and zul files. It doesn't mean that you can't use Controllers nor gsp anymore you can mix both without problems. From a gsp page you can go to a zul page, and there is no secret just link one to another with an <a> tag, for example. And it's possible to share objects between the pages as well, using Services, zkgrails plugin's Facade or with your own spring bean.

This is the first of a series of articles I'll write about my experience working with Grails and ZK. Now I'll show a very simple example of how to start using both and what we gain using both in the same project. First of all create a new grails project and install zk plugin:

26Oct/095

Tweak ZK to make event processing call groovy’s invokeMethod

My current project needs a very dynamic and fast pages without refreshs, or using the buzz word ajax, to accomplish this requirement I'm using ZK Direct RIA. As ZK heavily uses ajax requests with unpredictable url I need another way to protect the controller's actions (composer's method) instead of url. Using @Secured and groovy's invokeMethod I was able to protect each method of any class (please read the post to get a better picture of what I'll discuss) which works fines if the method call is from a groovy code, ZK is fully implemented in java though.

When a user clicks on a button, or does anything that generates events, zk process it and call the corresponding method in the composer class. ZK events processing executes this code when it find the method to call:

mtd.invoke(controller, new Object[] {evt});

This uses Java Reflection API and completely bypass groovy's invokeMethod, what we need to do is use groovy's InvokerHelper class instead of direct calling the method using reflection.

InvokerHelper.invokeMethod(controller, mtd.getName(), new Object[] {params});

Now that we know how to do it for any kind of java code let's dig into the problem with ZK event and find out where we should use InvokerHelper.