...
In this tutorial, we will following the guideline of developing a plugin to develop our Gantt Chart Userview Menu plugin. Please also refer to the very first tutorial วิธีการพัฒนา Bean Shell Hash Variable for more details steps.
1. What is the problem?
I want to display collected form data in a gantt chart view. I can choose to use Jasper Reports Userview Menu to achieve it but It does not look nice and lack of interactive control. Then, I found this Jquery Gantt Chart library developed by Tait Brown under MIT license which look nicer and work better than viewing a gantt chart using Jasper Report. I want to use it to display my collected form data.
2. What is your idea to solve the problem?
We can develop a Userview Menu Plugin to use the Jquery Gantt Chart library to display the collected form data.
3. What is the input needed for your plugin?
To develop a Gantt Chart Userview Menu plugin, we can consider to provide the following as input.
- Data Binder : We can reuse datalist binder to retrieve data
- Data Mapping : Map the retrieve data from datalist binder to the data format of the library
- Formatting options : Options to format and customise the gantt chart.
4. What is the output and expected outcome of your plugin?
By referring to the library demo, we can quickly come out a static HTML page like the picture below. As this is a Joget plugin tutorial, we will not go into the detail on coding the static HTML page. You can refer to static.zip. We will expect our userview page can display our collected data as the static HTML page.
5. Is there any resources/API that can be reuse?
If you are not familiar with FreeMaker syntax, you should have a look on their document before proceed.
6. Prepare your development environment
We need to always have our Joget Workflow Source Code ready and builded by following this guideline.
...
Open the maven project with your favourite IDE. I will be using NetBeans.
7. Just code it!
a. Extending the abstract class of a plugin type
Create a "GanttChartMenu" class under "org.joget.tutorial" package. Then, extend the class with org.joget.apps.userview.model.UserviewMenu abstract class. Please refer to Userview Menu Plugin.
b. Implement all the abstract methods
As usual, we have to implement all the abstract methods. We will using AppPluginUtil.getMessage method to support i18n and using constant variable MESSAGE_PATH for message resource bundle directory.
...
Now, for testing purpose, we can skip to c. Manage the dependency libraries of your plugin, d. Make your plugin internationalization (i18n) ready, e. Register your plugin to Felix Framework and f. Build it and testing then continue the below after testing it. You will get something similar to below in your userview.
...
Code Block |
---|
<link href="${request.contextPath}/plugin/org.joget.tutorial.GanttChartMenu/lib/jquery.gantt/css/style.css" rel="stylesheet" type="text/css" /> <script src="${request.contextPath}/plugin/org.joget.tutorial.GanttChartMenu/lib/jquery.gantt/js/jquery.fn.gantt.min.js"></script> <div class="gantt_chart_menu_body"> <#if element.properties.title?? ><h3>${element.properties.title!}</h3></#if> ${element.properties.customHeader!} <div class="gantt"></div> <script> $(function() { "use strict"; $(".gantt").gantt({ source: ${data!}, months: [@@userview.ganttChart.months.label@@], dow: [@@userview.ganttChart.dow.label@@], itemsPerPage: ${element.properties.itemsPerPage!}, navigate: "${element.properties.navigate!}", scale: "${element.properties.scale!}", maxScale: "${element.properties.maxScale!}", minScale: "${element.properties.minScale!}", waitText: "@@userview.ganttChart.waitText@@", onItemClick: function (data) { ${element.properties.onItemClick!} }, onAddClick: function(datetime, rowId) { ${element.properties.onAddClick!} }, onRender: function() { ${element.properties.onRender!} }, useCookie: <#if element.properties.useCookie! == 'true'>true<#else>false</#if>, scrollToToday: <#if element.properties.scrollToToday! == 'true'>true<#else>false</#if> }); }); </script> ${element.properties.customFooter!} </div> |
c. Manage the dependency libraries of your plugin
Our plugin is using some libraries, we have to add all of them to our POM file.
Code Block | ||
---|---|---|
| ||
<!-- Change plugin specific dependencies here --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20080701</version> </dependency> <dependency> <groupId>displaytag</groupId> <artifactId>displaytag</artifactId> <version>1.2</version> <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.slf4j</groupId> </exclusion> <exclusion> <artifactId>jcl104-over-slf4j</artifactId> <groupId>org.slf4j</groupId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <!-- End change plugin specific dependencies here --> |
d. Make your plugin internationalization (i18n) ready
We are using i18n message key in getLabel and getDescription method. We also used i18n message key in our properties options definition as well. So, we will need to create a message resource bundle properties file for our plugin.
...
Code Block |
---|
org.joget.tutorial.GanttChartMenu.pluginLabel=Gantt Chart Menu org.joget.tutorial.GanttChartMenu.pluginDesc=Display data in a Gantt Chart view userview.ganttchart.config=Configure Gantt Chart Menu userview.ganttchart.customId=Custom ID userview.ganttchart.invalidId=Only alpha-numeric and underscore characters allowed userview.ganttchart.label=Label userview.ganttchart.title=Page Title userview.ganttchart.binder=Data Binder userview.ganttchart.mapping=Column to Data Mappings userview.ganttchart.mapping.category=Category (column ID) userview.ganttchart.mapping.task=Task (column ID) userview.ganttchart.mapping.activity=Activity (column ID) userview.ganttchart.mapping.fromDate=Activity From Date (column ID) userview.ganttchart.mapping.toDate=Activity To Date (column ID) userview.ganttchart.mapping.dateFormat=Date format for Activity From/To Date userview.ganttchart.mapping.taskId=Task Id (column ID) userview.ganttchart.mapping.cssClass=Status (column ID, use as CSS class for styling) userview.ganttchart.advanced=Advanced userview.ganttchart.itemsPerPage=Item pre page userview.ganttchart.navigate=Navigator userview.ganttchart.navigate.buttons=Buttons userview.ganttchart.navigate.scroll=Scroll userview.ganttchart.scale=Default Scale userview.ganttchart.scale.hours=Hours userview.ganttchart.scale.days=Days userview.ganttchart.scale.weeks=Weeks userview.ganttchart.scale.months=Months userview.ganttchart.maxScale=Maximum Scale userview.ganttchart.minScale=Minimum Scale userview.ganttchart.useCookie=Use cookie for storing chart states userview.ganttchart.scrollToToday=Auto scroll to today after rendered userview.ganttchart.onItemClick=On Item Clicked Event (Javascript) userview.ganttchart.onAddClick=On Empty Space Clicked Event (Javascript) userview.ganttchart.onRender=On Rendered Event (Javascript) userview.ganttchart.customHeader=Custom Header (HTML) userview.ganttchart.customFooter=Custom Footer (HTML) userview.ganttChart.months.label="January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" userview.ganttChart.dow.label="S", "M", "T", "W", "T", "F", "S" userview.ganttChart.waitText=Loading... |
e. Register your plugin to Felix Framework
We will have to register our plugin class in Activator class (Auto generated in the same class package) to tell Felix Framework that this is a plugin.
Code Block | ||
---|---|---|
| ||
public void start(BundleContext context) { registrationList = new ArrayList<ServiceRegistration>(); //Register plugin here registrationList.add(context.registerService(GanttChartMenu.class.getName(), new GanttChartMenu(), null)); } |
f. Build it and testing
Let build our plugin. Once the building process is done, we will found a "gantt_chart_menu-5.0.0.jar" file is created under "gantt_chart_menu/target" directory.
...
Populate some data to the form for testing.
The end result.
8. Take a step further, share it or sell it
You can download the source code from gantt_chart_menu.zip.
...