Joget DX 8 Stable Released
The stable release for Joget DX 8 is now available, with a focus on UX and Governance.
...
ฉันต้องการแสดงข้อมูลแบบฟอร์มที่เก็บรวบรวมในมุมมองแผนภูมิแกนต์ คุณสามารถเลือกใช้ Jasper Reports Userview Menu เพื่อให้มันสำเร็จได้ แต่มนัดูไม่สวยงาม 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.
We can develop a Userview Menu Plugin to use the Jquery Gantt Chart library to display the collected form data.
To develop a Gantt Chart Userview Menu plugin, we can consider to provide the following as input.
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.
If you are not familiar with FreeMaker syntax, you should have a look on their document before proceed.
We need to always have our Joget Workflow Source Code ready and builded by following this guideline.
ภายใต้ใบอนุญาต MIT ซึ่งดูดีกว่าและทำงานได้ดีกว่าการดูแผนภูมิแกนต์โดยใช้ Jasper Report. ฉันต้องการใช้มันเพื่อแสดงข้อมูลในแบบฟอร์มที่รวบรวมไว้ของฉัน
เราสามารถพัฒนาปลั๊กอิน Userview Menu Plugin โดยใช้ Jquery Gantt Chart library เพื่อแสดงข้อมูลในแบบฟอร์มที่รวบรวมไว้ของฉัน
ในการพัฒนาปลั๊กอินเมนู Userview Gantt เราสามารถพิจารณาให้สิ่งต่อไปนี้เป็นอินพุต
โดยอ้างอิงถึง library demo,เราสามารถออกแบบหน้า HTML แบบคงที่ได้อย่างรวดเร็วเช่นภาพด้านล่าง เช่นเคยในบทเรียน Joget plugin. เราจะไม่เข้าไปดูรายละเอียดเกี่ยวกับการเขียนโค้ดหน้า HTML แบบคงที่ คุณสามารถอ้างถึง static.zip. เราคาดว่าหน้า Userview ของเราสามารถแสดงข้อมูลที่รวบรวมได้เป็นหน้า HTML คงที่
ถ้าคุณไม่คุ้นเคย FreeMaker syntax, คุณควรดูเอกสารก่อนดำเนินการต่อ
เราจำเป็นต้องให้ซอร์สโค้ด Joget Workflow ของเราพร้อมและสร้างโดยทำตาม this guideline.
บทช่วยสอนต่อไปนี้จัดทำขึ้นด้วย Macbook Pro และ The following of this tutorial is prepared with a Macbook Pro and Joget Source Code version 5.0.0. Please refer to แนวทางสำหรับการพัฒนาปลั๊กอิน for other platform command.0. โปรดอ้างอิงถึง แนวทางสำหรับการพัฒนาปลั๊กอิน เพื่อคำสั่งในแพลตฟอร์มอื่นๆ
ให้กล่าวว่าไดเรกทอรีโฟลเดอร์ของเราดังต่อไปนี้Let said our folder directory as following.
Code Block |
---|
- Home - joget - plugins - jw-community -5.0.0 |
The ไดเรกทอรี "plugins" directory is the folder we will create and store all our plugins and the ปลั๊กอิน" คือโฟลเดอร์ที่เราจะสร้างและจัดเก็บปลั๊กอินทั้งหมดของเราและไดเรกทอรี "jw-community" directory is where the เป็นที่เก็บซอร์สโค้ด Joget Workflow Source code stored.
เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างโครงการ maven ในไดเรกทอรี "ปลั๊กอิน"Run the following command to create a maven project in "plugins" directory.
Code Block | ||
---|---|---|
| ||
cd joget/plugins/ ~/joget/jw-community/5.0.0/wflow-plugin-archetype/create-plugin.sh org.joget.tutorial gantt_chart_menu 5.0.0 |
Then, the shell script will ask us to key in a version for your plugin and ask us for confirmation before generate the maven project.จากนั้นเชลล์สคริปต์จะขอให้เราใส่ปลั๊กอินสำหรับรุ่นของคุณและขอให้เรายืนยันก่อนที่จะสร้างโครงการ Maven
Code Block | ||
---|---|---|
| ||
Define value for property 'version': 1.0-SNAPSHOT: : 5.0.0 [INFO] Using property: package = org.joget.tutorial Confirm properties configuration: groupId: org.joget.tutorial artifactId: gantt_chart_menu version: 5.0.0 package: org.joget.tutorial Y: : y |
We should get เราควรได้รับข้อความ "BUILD SUCCESS" message shown in our terminal and a ที่แสดงในเครื่องของเราและโฟลเดอร์ "gantt_chart_menu" folder created in ที่สร้างในโฟลเดอร์ "pluginsปลั๊กอิน" folder.
Open the maven project with your favourite IDE. I will be using เปิดโครงการ maven ด้วย IDE ที่คุณชื่นชอบ เราแนะนำให้ใช้ NetBeans.
...
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.
As usual, we have to implement all the เช่นเคยเราจะต้องใช้ abstract methods ของเราทั้งหมด. We will using เราจะใช้ AppPluginUtil.getMessage method to support i18n and using constant variable เพื่อสนับสนุน i18n และใช้ตัวแปรคงที่ MESSAGE_PATH for สำหรับ message resource bundle directory.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
package org.joget.tutorial; import org.joget.apps.app.service.AppPluginUtil; import org.joget.apps.userview.model.UserviewMenu; public class GanttChartMenu extends UserviewMenu { private final static String MESSAGE_PATH = "messages/GanttChartMenu"; public String getName() { return "Gantt Chart Menu"; } public String getVersion() { return "5.0.0"; } public String getClassName() { return getClass().getName(); } public String getLabel() { //support i18n return AppPluginUtil.getMessage("org.joget.tutorial.GanttChartMenu.pluginLabel", getClassName(), MESSAGE_PATH); } public String getDescription() { //support i18n return AppPluginUtil.getMessage("org.joget.tutorial.GanttChartMenu.pluginDesc", getClassName(), MESSAGE_PATH); } public String getPropertyOptions() { return AppUtil.readPluginResource(getClassName(), "/properties/ganttChartMenu.json", null, true, MESSAGE_PATH); } @Override public String getCategory() { return "Marketplace"; } @Override public String getIcon() { //sorry, i am reuse the icon of other plugin here return "/plugin/org.joget.apps.userview.lib.HtmlPage/images/grid_icon.gif"; } @Override public boolean isHomePageSupported() { return true; // Can use as first page of the userview } @Override public String getDecoratedMenu() { return null; // using default } @Override public String getRenderPage() { throw new UnsupportedOperationException("Not supported yet."); } } |
Then, we have to do a UI for admin user to provide inputs for our plugin. In getPropertyOptions method, we have already specifed our ตัวเลือกคุณสมบัติปลั๊กอิน definition file is locate at จากนั้นเราต้องทำ UI สำหรับผู้ใช้ผู้ดูแลระบบเพื่อให้อินพุตสำหรับปลั๊กอินของเรา. ใน getPropertyOptions method, เราได้ระบุไฟล์ ตัวเลือกคุณสมบัติปลั๊กอิน ไว้ที่ "/properties/ganttChartMenu.json". Let us create a ให้เราสร้าง directory "resources/properties" under ภายใต้ "gantt_chart_menu/src/main" directory. After create the หลังจากสร้าง directory, create a file named สร้างไฟล์ชื่อ "ganttChartMenu.json" in the ในโฟลเดอร์ "properties" folder.
ในไฟล์ตัวเลือกคุณสมบัติ เราจะต้องเตรียมตัวเลือกตามนี้. โปรดทราบว่าเราสามารถใช้ In the properties definition options file, we will need to provide options as below. Please note that we can use "@@message.key@@" syntax to support i18n in our properties options.เพื่อสนับสนุน i18n ในตัวเลือกของเรา
Code Block | ||
---|---|---|
| ||
[{ title : '@@userview.ganttchart.config@@', properties : [{ name : 'id', label : 'Id', type : 'hidden' }, { name : 'customId', label : '@@userview.ganttchart.customId@@', type : 'textfield', regex_validation : '^[a-zA-Z0-9_]+$', validation_message : '@@userview.ganttchart.invalidId@@' }, { name : 'label', label : '@@userview.ganttchart.label@@', type : 'textfield', required : 'True' }, { name : 'title', label : '@@userview.ganttchart.title@@', type : 'textfield' }, { name : 'binder', label : '@@userview.ganttchart.binder@@', type : 'elementselect', required : 'True', options_ajax : '[CONTEXT_PATH]/web/property/json/getElements?classname=org.joget.apps.datalist.model.DataListBinderDefault', url : '[CONTEXT_PATH]/web/property/json[APP_PATH]/getPropertyOptions' }, { label : '@@userview.ganttchart.mapping@@', type : 'header' }, { name : 'category', label : '@@userview.ganttchart.mapping.category@@', type : 'textfield', required : 'True' }, { name : 'task', label : '@@userview.ganttchart.mapping.task@@', type : 'textfield', required : 'True' }, { name : 'activity', label : '@@userview.ganttchart.mapping.activity@@', type : 'textfield', required : 'True' }, { name : 'fromDate', label : '@@userview.ganttchart.mapping.fromDate@@', type : 'textfield', required : 'True' }, { name : 'toDate', label : '@@userview.ganttchart.mapping.toDate@@', type : 'textfield', required : 'True' }, { name : 'dateFormat', label : '@@userview.ganttchart.mapping.dateFormat@@', type : 'textfield', required : 'True', value : 'yyyy-MM-dd' }, { name : 'taskId', label : '@@userview.ganttchart.mapping.taskId@@', type : 'textfield' }, { name : 'cssClass', label : '@@userview.ganttchart.mapping.cssClass@@', type : 'textfield' }] }, { title : '@@userview.ganttchart.advanced@@', properties : [ { name : 'itemsPerPage', label : '@@userview.ganttchart.itemsPerPage@@', type : 'textfield', required : 'True', value : '20' }, { name : 'navigate', label : '@@userview.ganttchart.navigate@@', type : 'selectbox', required : 'True', value : 'scroll', options : [{ value : 'buttons', label : '@@userview.ganttchart.navigate.buttons@@' }, { value : 'scroll', label : '@@userview.ganttchart.navigate.scroll@@' }] }, { name : 'scale', label : '@@userview.ganttchart.scale@@', type : 'selectbox', required : 'True', value : 'days', options : [{ value : 'hours', label : '@@userview.ganttchart.scale.hours@@' }, { value : 'days', label : '@@userview.ganttchart.scale.days@@' }, { value : 'weeks', label : '@@userview.ganttchart.scale.weeks@@' }, { value : 'months', label : '@@userview.ganttchart.scale.months@@' }] }, { name : 'maxScale', label : '@@userview.ganttchart.maxScale@@', type : 'selectbox', required : 'True', value : 'months', options : [{ value : 'hours', label : '@@userview.ganttchart.scale.hours@@' }, { value : 'days', label : '@@userview.ganttchart.scale.days@@' }, { value : 'weeks', label : '@@userview.ganttchart.scale.weeks@@' }, { value : 'months', label : '@@userview.ganttchart.scale.months@@' }] }, { name : 'minScale', label : '@@userview.ganttchart.minScale@@', type : 'selectbox', required : 'True', value : 'hours', options : [{ value : 'hours', label : '@@userview.ganttchart.scale.hours@@' }, { value : 'days', label : '@@userview.ganttchart.scale.days@@' }, { value : 'weeks', label : '@@userview.ganttchart.scale.weeks@@' }, { value : 'months', label : '@@userview.ganttchart.scale.months@@' }] }, { name : 'useCookie', label : '@@userview.ganttchart.useCookie@@', type : 'checkbox', options : [{ value : 'true', label : '' }] }, { name : 'scrollToToday', label : '@@userview.ganttchart.scrollToToday@@', type : 'checkbox', options : [{ value : 'true', label : '' }] }, { name : 'onItemClick', label : '@@userview.ganttchart.onItemClick@@', type : 'codeeditor', mode : 'javascript', value : '//console.log(data); //data obj hold all the columns value of a row' }, { name : 'onAddClick', label : '@@userview.ganttchart.onAddClick@@', type : 'codeeditor', mode : 'javascript', value : '//console.log(datetime); //the DateTime in ms for the clicked Cell\n//console.log(rowId); //the row ID of clicked Cell' }, { name : 'onRender', label : '@@userview.ganttchart.onRender@@', type : 'codeeditor', mode : 'javascript', value : '//console.log("chart rendered");' }, { name : 'customHeader', label : '@@userview.ganttchart.customHeader@@', type : 'codeeditor', mode : 'html' }, { name : 'customFooter', label : '@@userview.ganttchart.customFooter@@', type : 'codeeditor', mode : 'html' }] }] |
After done the properties option to collect input, we can work on the main method of the plugin which is getRenderPage method. Normally, what I will do before go into detail to populate the data to the view, I will first put the static content for the getRenderPage to build and test the plugin first. It everything is fine, then only we try to add data to the view.หลังจากเตรียมตัวเลือกคุณสมบัติเสร็จ, เราสามารถทำงานกับวิธีการหลักของปลั๊กอินซึ่งเป็นวิธี getRenderPage. โดยปกติเราจะทำอะไรก่อนลงรายละเอียดเพื่อเติมข้อมูลลงในมุมมอง เราจะใส่เนื้อหาแบบคงที่สำหรับ getRenderPage ก่อนเพื่อสร้างและทดสอบปลั๊กอินก่อน มันทุกอย่างเรียบร้อยแล้วเราแค่พยายามเพิ่มข้อมูลลงในมุมมอง
Code Block | ||
---|---|---|
| ||
@Override public String getRenderPage() { Map model = new HashMap(); model.put("request", getRequestParameters()); model.put("element", this); PluginManager pluginManager = (PluginManager)AppUtil.getApplicationContext().getBean("pluginManager"); String content = pluginManager.getPluginFreeMarkerTemplate(model, getClass().getName(), "/templates/ganttChart.ftl", null); return content; } |
Then, let us create a template file locate at จากนั้นให้เราสร้างไฟล์เทมเพลตค้นหาที่ "/templates/ganttChart.ftl" . Let us create a directory ให้เราสร้างไดเรกทอรี "resources / templates" under ภายใต้ไดเรกทอรี "gantt_chart_menu / src / main" directory. After create the directory, create a file named หลังจากสร้างไดเรกทอรีให้สร้างไฟล์ชื่อ "ganttChartMenu.json" in the ในโฟลเดอร์ "templatestemplate" folder.
Put the static HTML we create previously into the template file as below. Remember to put all the dependencies javascript library and images under ใส่ HTML แบบคงที่ที่เราสร้างไว้ก่อนหน้านี้ลงในไฟล์ template ดังต่อไปนี้. อย่าลืมใส่ javascript library และ images ทั้งหมดไว้ภายใต้ "gantt_chart_menu/src/main/resources/resources" and change the url as below accordingly. You project directory should look like the image below now. และเปลี่ยน URL ตามด้านล่าง ไดเรกทอรีโครงการของคุณควรดูเหมือนภาพด้านล่างนี้
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"> <h3>Plugin Development</h3> <div class="gantt"></div> <script> $(function() { "use strict"; $(".gantt").gantt({ source: [{ name: "Sprint 0", desc: "Analysis", values: [{ from: "/Date(1320192000000)/", to: "/Date(1322401600000)/", label: "Requirement Gathering", customClass: "ganttRed" }] },{ name: " ", desc: "Scoping", values: [{ from: "/Date(1322611200000)/", to: "/Date(1323302400000)/", label: "Scoping", customClass: "ganttRed" }] },{ name: "Sprint 1", desc: "Development", values: [{ from: "/Date(1323802400000)/", to: "/Date(1325685200000)/", label: "Development", customClass: "ganttGreen" }] },{ name: " ", desc: "Showcasing", values: [{ from: "/Date(1325685200000)/", to: "/Date(1325695200000)/", label: "Showcasing", customClass: "ganttBlue" }] },{ name: "Sprint 2", desc: "Development", values: [{ from: "/Date(1326785200000)/", to: "/Date(1325785200000)/", label: "Development", customClass: "ganttGreen" }] },{ name: " ", desc: "Showcasing", values: [{ from: "/Date(1328785200000)/", to: "/Date(1328905200000)/", label: "Showcasing", customClass: "ganttBlue" }] },{ name: "Release Stage", desc: "Training", values: [{ from: "/Date(1330011200000)/", to: "/Date(1336611200000)/", label: "Training", customClass: "ganttOrange" }] },{ name: " ", desc: "Deployment", values: [{ from: "/Date(1336611200000)/", to: "/Date(1338711200000)/", label: "Deployment", customClass: "ganttOrange" }] },{ name: " ", desc: "Warranty Period", values: [{ from: "/Date(1336611200000)/", to: "/Date(1349711200000)/", label: "Warranty Period", customClass: "ganttOrange" }] }], navigate: "scroll", maxScale: "hours", itemsPerPage: 10 }); }); </script> </div> |
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.
จากนั้นดำเนินการต่อด้านล่างหลังจากทดสอบ คุณจะได้รับสิ่งที่คล้ายกับด้านล่างในมุมมองของเรา
หลังจากตรวจสอบว่า HTML แบบคงที่ทำงานในปลั๊กอินของเราเราสามารถปรับปรุงให้ดีขึ้นได้โดยการเพิ่มข้อมูลลงในมุมมอง ตอนนี้แก้ไขเมธอด getRenderPage และ templates ganttChart.ftl ดังนี้After verify the static HTML is working in our plugin, we can further enhance it by adding data to the view. Now, modify your getRenderPage method and ganttChart.ftl template as below.
Code Block | ||
---|---|---|
| ||
@Override public String getRenderPage() { Map model = new HashMap(); model.put("request", getRequestParameters()); model.put("element", this); //populate data in JSON format model.put("data", getData()); PluginManager pluginManager = (PluginManager)AppUtil.getApplicationContext().getBean("pluginManager"); String content = pluginManager.getPluginFreeMarkerTemplate(model, getClass().getName(), "/templates/ganttChart.ftl", MESSAGE_PATH); return content; } protected String getData() { String json = "[]"; try { DataListCollection data = null; String idColumn = getPropertyString("taskId"); //get the binder Object binderData = getProperty("binder"); if (binderData != null && binderData instanceof Map) { Map bdMap = (Map) binderData; if (bdMap != null && bdMap.containsKey("className") && !bdMap.get("className").toString().isEmpty()) { PluginManager pluginManager = (PluginManager) AppUtil.getApplicationContext().getBean("pluginManager"); DataListBinder binder = (DataListBinder) pluginManager.getPlugin(bdMap.get("className").toString()); if (binder != null) { Map bdProps = (Map) bdMap.get("properties"); binder.setProperties(bdProps); data = binder.getData(null, bdProps, new DataListFilterQueryObject[0], null, null, null, null); if (idColumn.isEmpty()) { idColumn = binder.getPrimaryKeyColumnName(); } } } } JSONArray dataArry = new JSONArray(); String dateFormat = getPropertyString("dateFormat"); SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); if (data != null && !data.isEmpty()) { String currentCategory = null; int cat_count = 0; String currentTask = null; int task_count = 0; int act_count = 0; JSONObject taskObj = null; JSONArray taskValuesArray = null; for (Object r : data) { String id = getValue(r, idColumn); String cat = getValue(r, getPropertyString("category")); String task = getValue(r, getPropertyString("task")); String act = getValue(r, getPropertyString("activity")); String formDate = getValue(r, getPropertyString("fromDate")); String toDate = getValue(r, getPropertyString("toDate")); String status = getValue(r, getPropertyString("cssClass")); if (currentTask == null || !currentTask.equals(task) || (currentTask.equals(task) && !cat.equals(currentCategory))) { currentTask = task; if (taskObj != null) { taskObj.put("values", taskValuesArray); dataArry.put(taskObj); } taskObj = new JSONObject(); taskValuesArray = new JSONArray(); taskObj.put("desc", task); taskObj.put("id", id); task_count++; } if (currentCategory == null || !currentCategory.equals(cat)) { currentCategory = cat; taskObj.put("name", cat); cat_count++; } JSONObject valueObj = new JSONObject(); JSONObject actObj = new JSONObject(); act_count++; actObj.put("taskId", id); actObj.put("category", cat); actObj.put("task", task); actObj.put("activity", act); actObj.put("formDate", formDate); actObj.put("toDate", toDate); actObj.put("status", status); valueObj.put("dataObj", actObj); valueObj.put("label", act); valueObj.put("from", "/Date("+sdf.parse(formDate).getTime()+")/"); valueObj.put("to", "/Date("+sdf.parse(toDate).getTime()+")/"); valueObj.put("customClass", "cat_"+cat_count+" task_"+task_count+" act_"+act_count+" "+status.replace(" ", "_")); taskValuesArray.put(valueObj); } if (taskObj != null) { taskObj.put("values", taskValuesArray); dataArry.put(taskObj); } } return dataArry.toString(); } catch (Exception e) { LogUtil.error(GanttChartMenu.class.getName(), e, json); } return json; } protected String getValue(Object o, String name) { String value = ""; try { Object v = LookupUtil.getBeanProperty(o, name); if (v != null) { return v.toString(); } } catch (Exception e) { LogUtil.error(GanttChartMenu.class.getName(), e, name); } return value; } |
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> |
...
...
ปลั๊กอินของเราใช้บาง libraries, เราต้องเพิ่มไปไหนไฟล์ POM ของเรา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 --> |
...
...
We are using เรากำลังใช้ i18n message key in ใน getLabel and และ getDescription method. We also used i18n เรายังใช้ 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.สำหรับปลั๊กอินของเรา
สร้าง Create directory "resources/messages" under ภายใต้ "gantt_chart_menu/src/main" directory. Then, create a จากนั้นสร้างไฟล์ "GanttChartMenu.properties" file in the folder. In the properties file, let add all the message keys and its label as belowในโฟลเดอร์, ให้เราเพิ่ม message keys แะs label ดังต่อไปนี้.
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... |
...
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)); } |
...
ให้สร้างปล๊กอิน. หลังจากสร้างปลั๊กอินเสร็จ, เราจะเจอไฟล์ 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.
Then, let upload the plugin jar to จากนั้นอัพโหลดปลั๊กอิน Manage Plugins. After upload the jar file, double check the plugin is uploaded and activated correctly.หลังจากอัพโหลดให้ตรวจสอบอีกครั้งเพื่อดูว่าสามารถใช้ปลั๊กอินได้ไหม
Open a userview, you will see the new plugin is added under เปิด userview คุณจะเห็นปลั๊กอินใหม่ถูกเพิ่มภายใต้ "Marketplace" . Drag it to one of your Userview Category.ลากไปยังหมวดหมู่ Userview ของคุณ
Edit the properties of the Gantt Chart Menu.แก้ไขคุณสมบัติของเมนูแผนภูมิแกนต์
I selected "Form Data Binder" as "Data Binder" for testing. Fill all the mappings to corresponding Field Id/Column Id.
...