Integrate ZK with dhtmlxGantt"

From Documentation
m (correct highlight (via JWB))
 
(23 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
 
 
 
 
 
{{Template:UnderConstruction}}
 
 
{{Template:Smalltalk_Author|
 
{{Template:Smalltalk_Author|
 
|author=Vincent Jian, Engineer, Potix Corporation
 
|author=Vincent Jian, Engineer, Potix Corporation
|date=October 7, 2014
+
|date=October 30, 2014
 
|version=ZK 7.0.3, dhtmlxGantt v.3.0.0 Standard
 
|version=ZK 7.0.3, dhtmlxGantt v.3.0.0 Standard
 
}}
 
}}
  
 
= Introduction =
 
= Introduction =
[http://dhtmlx.com/docs/products/dhtmlxGantt/ dhtmlxGantt] is an open source '''JavaScript Gantt chart''' that helps you visualize a project schedule in a nice-looking chart. It can show the dependencies between tasks as lines and allows you to set up '''different relationships between tasks''' (finish-to-start, start-to-start, end-to-end).
+
[http://dhtmlx.com/docs/products/dhtmlxGantt/ dhtmlxGantt] is an open source '''JavaScript Gantt chart''' that helps you visualize a project schedule in a nice-looking chart. It can show the dependencies between tasks as lines and allows you to set up '''different relationship between tasks''' (finish-to-start, start-to-start, end-to-end).
This smalltalk will introduce how you can integrate dhtmlxGantt into an ZK web application, and also demonstrates how easy it is to integrate ZK with any other 3rd party JavaScript library following the same method.
+
This smalltalk will guide you on how to integrate dhtmlxGantt into a ZK web application, step by step. By following this example you should be able to get an overview on how 3rd party integration in ZK is done and start to integrate any 3rd JS party libraries with ZK as you wish.
 +
 
 +
= Demo =
 +
 
 +
Here is a demo of the resulting sample:
 +
 
 +
<gflash width="895" height="535">GanttChartDemo.swf</gflash>
  
 
= Prerequisites =
 
= Prerequisites =
  
Since dhtmlxGantt is a javascript library, here I will use the technical described in the following articles to integrated with ZK:
+
Since dhtmlxGantt is a javascript library, here I will use the techniques described in the following articles to integrated with ZK:
 
* [[Small_Talks/2012/November/Integrate_3rd_Party_Javascript_Libraries_In_ZK | Integrate 3rd Party Javascript Libraries In ZK]]
 
* [[Small_Talks/2012/November/Integrate_3rd_Party_Javascript_Libraries_In_ZK | Integrate 3rd Party Javascript Libraries In ZK]]
 
* [[Small_Talks/2013/February/Integrate_3rd_Party_Javascript_Libraries_In_ZK_Using_Clientside_Controller | Integrate 3rd Party Javascript Libraries In ZK Using Clientside Controller]]
 
* [[Small_Talks/2013/February/Integrate_3rd_Party_Javascript_Libraries_In_ZK_Using_Clientside_Controller | Integrate 3rd Party Javascript Libraries In ZK Using Clientside Controller]]
  
Before you start to integrate a 3rd party library, it is suggested to read the above two articles to understand the life cycle of ZK client widget.
+
Before you start to integrate a 3rd party library, it is recommended that you read the above two articles first to understand the life cycle of ZK client widget.
 +
 
 +
= Steps to integrate dhtmlxGantt =
 +
The basic flow to integrate any JavaScript library is:
 +
Include library source
 +
--> Setup basic components
 +
--> Prepare data for library
 +
--> Initialize/Configure library
 +
--> Load/Send data between ZK and the 3rd party library.
  
= Step to integrate dhtmlxGantt =
+
In the following sections I will describe how each step is done.
  
 
== Create ZK Project and Prepare Necessary Libraries ==
 
== Create ZK Project and Prepare Necessary Libraries ==
 
1. Create a ZK project by maven, refer to our [[ZK_Installation_Guide/Quick_Start/Create_and_Run_Your_First_ZK_Application_with_Eclipse_and_Maven | installation guide]].
 
1. Create a ZK project by maven, refer to our [[ZK_Installation_Guide/Quick_Start/Create_and_Run_Your_First_ZK_Application_with_Eclipse_and_Maven | installation guide]].
  
2. Download dhtmlxGantt library from [http://dhtmlx.com/docs/products/dhtmlxGantt/ its official site], here I download the version 3.0 standard edition (GNU GPL v2 license).  
+
2. Download dhtmlxGantt library from [http://dhtmlx.com/docs/products/dhtmlxGantt/ its official site], I use version 3.0 standard edition (GNU GPL v2 license) for this small talk.  
  
 
* Extract the zip file and put dhtmlxgantt.js and dhtmlxgantt.css files under the project's "webapp/gantt" folder.
 
* Extract the zip file and put dhtmlxgantt.js and dhtmlxgantt.css files under the project's "webapp/gantt" folder.
  
 
== Load the library source and setup basic component ==
 
== Load the library source and setup basic component ==
To load the dhtmlxgantt library, we can use script xml processing instructions such as <?link?> and <?script?> on the zul page. According to dhtmlxgantt [http://docs.dhtmlx.com/gantt/desktop__how_to_start.html#step3initializedhtmlxgantt online document], a simple div element is enough to initialize Gantt chart. Therefore, we add a div component on the zul page as follows.
+
To load the dhtmlxgantt library, we can use script xml processing instructions such as <?link?> and <?script?> on the zul page. According to dhtmlxgantt [http://docs.dhtmlx.com/gantt/desktop__how_to_start.html#step3initializedhtmlxgantt online document], a simple div element is enough to initialize the Gantt chart. Therefore, we add a div component on the zul page as follows.
<source lang="xml" high="1,2,5">
+
<source lang="xml" highlight="1,2,5">
 
<?link rel="stylesheet" type="text/css" href="/gantt/dhtmlxgantt.css"?>
 
<?link rel="stylesheet" type="text/css" href="/gantt/dhtmlxgantt.css"?>
 
<?script type="text/javascript" src="/gantt/dhtmlxgantt.js"?>
 
<?script type="text/javascript" src="/gantt/dhtmlxgantt.js"?>
Line 48: Line 55:
  
 
== Prepare data for Gantt Chart ==
 
== Prepare data for Gantt Chart ==
Normally, a Gantt Chart need gantt tasks and gantt dependency links, and from dhtmlxGantt's [http://docs.dhtmlx.com/gantt/desktop__how_to_start.html#step4loaddatatotheganttchart online document], we can see a list of available properties for gantt task and gantt link. Based on which, we need to create two Java Objects as follows:
+
Normally, a Gantt Chart need gantt tasks and gantt dependency links. From dhtmlxGantt's [http://docs.dhtmlx.com/gantt/desktop__how_to_start.html#step4loaddatatotheganttchart online document], we can see a list of available properties for gantt tasks and gantt links. Based on which, we will create two Java Objects as follows:
<source lang="java" high="1">
+
<source lang="java" highlight="1">
 
public class GanttTask implements JSONAware {
 
public class GanttTask implements JSONAware {
  
Line 78: Line 85:
 
}
 
}
 
</source>
 
</source>
<source lang="java" high="1">
+
<source lang="java" highlight="1">
 
public class GanttLink implements JSONAware {
 
public class GanttLink implements JSONAware {
  
Line 99: Line 106:
 
</source>
 
</source>
  
As dhtmlxGantt supports load JSON format objects, here we implement <javadoc>org.zkoss.json.JSONAware</javadoc>.
+
As dhtmlxGantt supports the loading of JSON format objects, here we implement <javadoc>org.zkoss.json.JSONAware</javadoc>.
  
 
== Wrap dhtmlxgantt library with ZK Client Widget ==
 
== Wrap dhtmlxgantt library with ZK Client Widget ==
  
Before we load the real data, we will create a new widget that extends div widget and use bind_ life-cycle to register Gantt Event. And we prepare extra APIs such as "_init", "_attachGanttEvent" and "_detachGanttEvent" that are only used for Gantt Chart.
+
Before we load the real data, we will create a new widget that extends the div widget and use bind_ life-cycle to register Gantt Event. We also prepare extra APIs such as "_init", "_attachGanttEvent" and "_detachGanttEvent" that are only used for the Gantt Chart.
<source lang="javascript" high="2, 6, 12, 16, 19">
+
<source lang="javascript" highlight="2, 6, 12, 16, 19">
 
zk.afterLoad('zul.wgt', function() {
 
zk.afterLoad('zul.wgt', function() {
 
     zul.wgt.GanttDiv = zk.$extends(zul.wgt.Div, {
 
     zul.wgt.GanttDiv = zk.$extends(zul.wgt.Div, {
Line 129: Line 136:
 
});
 
});
 
</source>
 
</source>
* Line 2: Create GanttDiv widget that extends Div widget.
+
* Line 2: Create GanttDiv widget that extends the Div widget.
 
* Line 6: Attach Gantt Event.
 
* Line 6: Attach Gantt Event.
 
* Line 12: "_init" API that will be used for initializing Gantt chart from server side.
 
* Line 12: "_init" API that will be used for initializing Gantt chart from server side.
Line 135: Line 142:
  
 
Then we apply this widget by client widget attribute "use" in zul page we created earlier as follows:
 
Then we apply this widget by client widget attribute "use" in zul page we created earlier as follows:
<source lang="xml" start="3" high="3, 5">
+
<source lang="xml" start="3" highlight="3, 5">
 
<zk xmlns:w="client">
 
<zk xmlns:w="client">
 
     <window title="Dhtml Gantt Integration" border="normal" vflex="1">
 
     <window title="Dhtml Gantt Integration" border="normal" vflex="1">
Line 147: Line 154:
 
== Loading data from server to dhtmlxGantt library ==
 
== Loading data from server to dhtmlxGantt library ==
  
Here we use MVC pattern to load data from server side as follows:
+
Here we use the MVC pattern to load data from the server side as follows:
  
 
1. Apply GanttComposer to window component.
 
1. Apply GanttComposer to window component.
Line 156: Line 163:
 
</source>
 
</source>
  
2. Here we create some dummy tasks and links and call the GanttDiv widget's init function we added in previous section by <javadoc method="response(org.zkoss.zk.au.AuResponse)">org.zkoss.zk.ui.util.Clients</javadoc> API. With which dhtmlxgantt library parses the tasks and draws gantt chart.
+
2. Here we create some dummy tasks and links and call the GanttDiv widget's init function we have added previously by <javadoc method="response(org.zkoss.zk.au.AuResponse)">org.zkoss.zk.ui.util.Clients</javadoc> API. With which dhtmlxgantt library parses the tasks and draws the gantt chart.
<source lang="java" high="14, 16, 17, 18">
+
<source lang="java" highlight="14, 16, 17, 18">
 
public class GanttComposer extends SelectorComposer<Component> {
 
public class GanttComposer extends SelectorComposer<Component> {
  
Line 200: Line 207:
  
 
== Send dhtmlxGantt event back to server ==
 
== Send dhtmlxGantt event back to server ==
dhtmlxGantt library provides great UI to add other tasks and links and provide correspond event to register, such as onAfterTaskAdd and onAfterLinkAdd, refer to the its online [http://docs.dhtmlx.com/gantt/api__refs__gantt_events.html document] for complete event list. This section will show how to register these events and send the events back to server.
+
dhtmlxGantt library provides great UI to add other tasks and links to provide corresponding events to register, such as onAfterTaskAdd and onAfterLinkAdd, refer to its online [http://docs.dhtmlx.com/gantt/api__refs__gantt_events.html document] for the complete event list. This section will show how to register these events and send the events back to the server.
  
First, we register gantt task and link related events in the GanttDiv widget and new a ZK event to send the updated task and link to server as follows:
+
First, we register gantt task and link related events in the GanttDiv widget and a new ZK event to send the updated task and link to the server as follows:
<source lang="javascript" start="16" high="19">
+
<source lang="javascript" start="16" highlight="19">
 
_attachGanttEvent: function() {
 
_attachGanttEvent: function() {
 
     var self = this;
 
     var self = this;
Line 227: Line 234:
 
}
 
}
 
</source>
 
</source>
* Line 19: new ZK event with option "toServer: true" to make sure this event will send to server side, then send the event by zAu.send() API.
+
* Line 19: new ZK event with option "toServer: true" to make sure this event will send to the server side, then send the event by zAu.send() API.
  
Then, we listen onTaskAdd event in our composer to receive the event as follows:
+
Then, we listen to onTaskAdd event in our composer to receive the event as follows:
 
<source lang="java">
 
<source lang="java">
 
public class GanttComposer extends SelectorComposer<Component> {
 
public class GanttComposer extends SelectorComposer<Component> {
Line 246: Line 253:
  
 
= Conclusion =
 
= Conclusion =
DhmltxGantt library is a powerful tool to add/edit/delete gantt chart intuitively, and this article also showed how to easily integrate this powerful tool in ZK application to provide an highly interactive web site.
+
This article takes dhtmlxGantt chart as an example to demonstrate how easy it is to integrate a fancy 3rd party library with ZK. By applying the same methods you should be able to integrate any 3rd party libraries as you wish!
  
 
= Download =
 
= Download =
 
You can fork the project from [http://github.com/VincentJian/gantt github].
 
You can fork the project from [http://github.com/VincentJian/gantt github].
Note that the purpose of this article is to demonstrate how you can integrate a 3rd party library with ZK. If you wish to use the resulting integration, you will need to consult with the 3rd party provider (i.e. DHTMLX) to obtain appropriate license.
+
Note that the purpose of this article is to demonstrate how you can integrate a 3rd party library with ZK. If you wish to use the resulting integration, you will need to consult with the 3rd party provider (i.e. DHTMLX) to obtain the appropriate license.
  
 
{{Template:CommentedSmalltalk_Footer_new|
 
{{Template:CommentedSmalltalk_Footer_new|

Latest revision as of 04:21, 20 January 2022

DocumentationSmall Talks2014OctoberIntegrate ZK with dhtmlxGantt
Integrate ZK with dhtmlxGantt

Author
Vincent Jian, Engineer, Potix Corporation
Date
October 30, 2014
Version
ZK 7.0.3, dhtmlxGantt v.3.0.0 Standard

Introduction

dhtmlxGantt is an open source JavaScript Gantt chart that helps you visualize a project schedule in a nice-looking chart. It can show the dependencies between tasks as lines and allows you to set up different relationship between tasks (finish-to-start, start-to-start, end-to-end). This smalltalk will guide you on how to integrate dhtmlxGantt into a ZK web application, step by step. By following this example you should be able to get an overview on how 3rd party integration in ZK is done and start to integrate any 3rd JS party libraries with ZK as you wish.

Demo

Here is a demo of the resulting sample:

Prerequisites

Since dhtmlxGantt is a javascript library, here I will use the techniques described in the following articles to integrated with ZK:

Before you start to integrate a 3rd party library, it is recommended that you read the above two articles first to understand the life cycle of ZK client widget.

Steps to integrate dhtmlxGantt

The basic flow to integrate any JavaScript library is: Include library source --> Setup basic components --> Prepare data for library --> Initialize/Configure library --> Load/Send data between ZK and the 3rd party library.

In the following sections I will describe how each step is done.

Create ZK Project and Prepare Necessary Libraries

1. Create a ZK project by maven, refer to our installation guide.

2. Download dhtmlxGantt library from its official site, I use version 3.0 standard edition (GNU GPL v2 license) for this small talk.

  • Extract the zip file and put dhtmlxgantt.js and dhtmlxgantt.css files under the project's "webapp/gantt" folder.

Load the library source and setup basic component

To load the dhtmlxgantt library, we can use script xml processing instructions such as <?link?> and <?script?> on the zul page. According to dhtmlxgantt online document, a simple div element is enough to initialize the Gantt chart. Therefore, we add a div component on the zul page as follows.

<?link rel="stylesheet" type="text/css" href="/gantt/dhtmlxgantt.css"?>
<?script type="text/javascript" src="/gantt/dhtmlxgantt.js"?>
<zk>
    <window title="Dhtml Gantt Integration" border="normal" vflex="1">
        <div id="gantt" />
    </window>
</zk>
  • Line 1,2: Load dhtmlxgantt library
  • Line 5: Add div component to generate Gantt Chart.

Prepare data for Gantt Chart

Normally, a Gantt Chart need gantt tasks and gantt dependency links. From dhtmlxGantt's online document, we can see a list of available properties for gantt tasks and gantt links. Based on which, we will create two Java Objects as follows:

public class GanttTask implements JSONAware {

    private long id;
    private Date startDate;
    private int duration;
    private String description;
    private double progress;
    private int sortOrder;
    private GanttTask parent;
    private boolean open;

    public String toJSONString() {
        DateFormat dft = new SimpleDateFormat("dd-MM-yyyy");
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", id);
        map.put("start_date", dft.format(startDate));
        map.put("duration", duration);
        map.put("text", description);
        map.put("progress", progress);
        map.put("sortorder", sortOrder);
        map.put("parent", parent == null ? 0 : parent.getId());
        map.put("open", open);
        return JSONObject.toJSONString(map);
    }

    /* getter and setter omitted */
}
public class GanttLink implements JSONAware {

    private long id;
    private GanttTask source;
    private GanttTask target;
    private int type;

    public String toJSONString() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", id);
        map.put("source", source.getId());
        map.put("target", target.getId());
        map.put("type", type);
        return JSONObject.toJSONString(map);
    }

    /* getter and setter omitted */
}

As dhtmlxGantt supports the loading of JSON format objects, here we implement JSONAware.

Wrap dhtmlxgantt library with ZK Client Widget

Before we load the real data, we will create a new widget that extends the div widget and use bind_ life-cycle to register Gantt Event. We also prepare extra APIs such as "_init", "_attachGanttEvent" and "_detachGanttEvent" that are only used for the Gantt Chart.

zk.afterLoad('zul.wgt', function() {
    zul.wgt.GanttDiv = zk.$extends(zul.wgt.Div, {
        bind_: function() {
            this.$supers('bind_', arguments);
            // attach gantt event
            this._attachGanttEvent();
        },
        unbind_: function() {
            this._detachGanttEvent();
            this.$supers('unbind_', arguments);
        },
        _init: function(task) {
            gantt.init(this.uuid); //let dhmltxGantt library know where to render Gantt Chart
            gantt.parse(task);  //parse task and render Gantt Chart
        }
        _attachGanttEvent: function() {
            // attach Gantt Event here
        },
        _detachGanttEvent: function() {
            // detach Gantt Event here
        }
    }
});
  • Line 2: Create GanttDiv widget that extends the Div widget.
  • Line 6: Attach Gantt Event.
  • Line 12: "_init" API that will be used for initializing Gantt chart from server side.
  • Line 16, 19: Attach and detach Gantt Event for communication between client and server.

Then we apply this widget by client widget attribute "use" in zul page we created earlier as follows:

<zk xmlns:w="client">
    <window title="Dhtml Gantt Integration" border="normal" vflex="1">
        <div id="gantt" w:use="zul.wgt.GanttDiv" />
    </window>
<zk>
  • Line 3: Define the name space prefix "w" for client widget attribute.
  • Line 5: Apply GanttDiv widget to the div component.

Loading data from server to dhtmlxGantt library

Here we use the MVC pattern to load data from the server side as follows:

1. Apply GanttComposer to window component.

<window title="Dhtml Gantt Integration" border="normal" vflex="1" apply="org.zkoss.sample.GanttComposer">
    <div id="gantt" w:use="zul.wgt.GanttDiv" />
</window>

2. Here we create some dummy tasks and links and call the GanttDiv widget's init function we have added previously by Clients.response(AuResponse) API. With which dhtmlxgantt library parses the tasks and draws the gantt chart.

public class GanttComposer extends SelectorComposer<Component> {

    @Wire
    private Div gantt;

    private List<GanttTask> taskList;
    private List<GanttLink> linkList;
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

    public void doAfterCompose(Component comp) throws Exception {
        super.doAfterCompose(comp);
        taskList = new ArrayList<GanttTask>();
        linkList = new ArrayList<GanttLink>();
        String[] ganttJSONString = initGanttTasks();

        Clients.response(new AuInvoke(gantt, "_init",
                "{\"data\": [" + ganttJSONString[0] + "], " +
                "\"collections\": {\"links\": [" + ganttJSONString[1] + "]}}"));
    }

    private String[] initGanttTasks() {
        Calendar cal = Calendar.getInstance();
        
        cal.set(2013, 3, 1);
        GanttTask parent = new GanttTask(1L, cal.getTime(), 5, "Project #1", 0.8, 20, null, true);
        taskList.add(parent);
        String taskJSONString = parent.toJSONString();
        // omitted other tasks
        
        GanttLink link1 = new GanttLink(1L, parent, task1, 0);
        linkList.add(link1);
        String linkJSONString = link1.toJSONString();
        // omitted other links
        
        return new String[]{taskJSONString, linkJSONString};
    }
}
  • Line 14: Create dummy tasks and links.
  • Line 16-18: Execute GanttDiv widget's _init function to parse tasks and draw gantt chart.

Send dhtmlxGantt event back to server

dhtmlxGantt library provides great UI to add other tasks and links to provide corresponding events to register, such as onAfterTaskAdd and onAfterLinkAdd, refer to its online document for the complete event list. This section will show how to register these events and send the events back to the server.

First, we register gantt task and link related events in the GanttDiv widget and a new ZK event to send the updated task and link to the server as follows:

_attachGanttEvent: function() {
    var self = this;
    gantt.attachEvent('onAfterTaskAdd', function(id, item) {
        zAu.send(new zk.Event(self, "onTaskAdd", {'' : item}, {toServer:true}));
    });
    gantt.attachEvent('onAfterTaskUpdate', function(id, item) {
        zAu.send(new zk.Event(self, "onTaskUpdate", {'' : item}, {toServer:true}));
    });
        gantt.attachEvent('onAfterTaskDelete', function(id, item) {
        zAu.send(new zk.Event(self, "onTaskDelete", {'' : item}, {toServer:true}));
    });

    gantt.attachEvent('onAfterLinkAdd', function(id, item) {
        zAu.send(new zk.Event(self, 'onLinkAdd', {'' : item}, {toServer:true}));
    });
    gantt.attachEvent('onAfterLinkDelete', function(id, item) {
        zAu.send(new zk.Event(self, 'onLinkDelete', {'' : item}, {toServer:true}));
    });
},
_detachGanttEvent: function() {
    gantt.detachAllEvents();
}
  • Line 19: new ZK event with option "toServer: true" to make sure this event will send to the server side, then send the event by zAu.send() API.

Then, we listen to onTaskAdd event in our composer to receive the event as follows:

public class GanttComposer extends SelectorComposer<Component> {
    @Listen("onTaskAdd = #gantt")
    public void addTask(Event evt) throws ParseException {
        JSONObject obj = (JSONObject) evt.getData();
        GanttTask task = new GanttTask();
        // parse obj to task
        task.setId((Long) obj.get("id"));
        // omit other fields
        // add task to list/DB
        taskList.add(task);
    }
}

Conclusion

This article takes dhtmlxGantt chart as an example to demonstrate how easy it is to integrate a fancy 3rd party library with ZK. By applying the same methods you should be able to integrate any 3rd party libraries as you wish!

Download

You can fork the project from github. Note that the purpose of this article is to demonstrate how you can integrate a 3rd party library with ZK. If you wish to use the resulting integration, you will need to consult with the 3rd party provider (i.e. DHTMLX) to obtain the appropriate license.


Comments



Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.