Hi,
We would like to add workflow/wizard functionality into our existing SmartGWT based application. I have searched forum and found those threads requesting workflow examples, but not a single line of working example code:
So, I would like to share what I have learned so far.
I have created a simple flow starting with fetching process state data from client-only DataSource.
Next node is a script task which logs data.
Then, there is a user task which displays a form in the window and allows user to enter data.
Modified data is processed by a gateway, which compares to specified criteria.
Then it goes to error flow and back to user form or, if data matches criteria (field1='value1')), to node saving data and finishing process.
Here is index.html js example code:
and MainEntryPoint.java gwt example code:
Data file for client-only ds test.data.xml:
I have been working with SmartClient 12.1d dated 2019.12.01.
Comments welcome.
MichalG
We would like to add workflow/wizard functionality into our existing SmartGWT based application. I have searched forum and found those threads requesting workflow examples, but not a single line of working example code:
- https://forums.smartclient.com/forum...amples-missing
- https://forums.smartclient.com/forum...rkflow-example
- https://forums.smartclient.com/forum...-by-sponsoring
- https://forums.smartclient.com/forum...orkflow-widget
- https://forums.smartclient.com/forum...rkflow-example
- https://forums.smartclient.com/forum...rkflow-feature
- https://forums.smartclient.com/forum...bpm-or-similar
So, I would like to share what I have learned so far.
I have created a simple flow starting with fetching process state data from client-only DataSource.
Next node is a script task which logs data.
Then, there is a user task which displays a form in the window and allows user to enter data.
Modified data is processed by a gateway, which compares to specified criteria.
Then it goes to error flow and back to user form or, if data matches criteria (field1='value1')), to node saving data and finishing process.
Here is index.html js example code:
Code:
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Client</title> </head> <body> <script type="text/javascript"> var isomorphicDir = "isomorphic/"; </script> <script src="isomorphic/system/modules-debug/ISC_Core.js"> </script> <script src="isomorphic/system/modules-debug/ISC_Foundation.js"> </script> <script src="isomorphic/system/modules-debug/ISC_Containers.js"> </script> <script src="isomorphic/system/modules-debug/ISC_Grids.js"> </script> <script src="isomorphic/system/modules-debug/ISC_Forms.js"> </script> <script src="isomorphic/system/modules-debug/ISC_RichTextEditor.js"></script> <script src="isomorphic/system/modules-debug/ISC_Calendar.js"> </script> <script src="isomorphic/system/modules-debug/ISC_DataBinding.js"> </script> <script src="isomorphic/system/modules-debug/ISC_Workflow.js"> </script> <script src="isomorphic/skins/Graphite/load_skin.js"></script> <script type="text/javascript"> var ds = isc.DataSource.create({ ID: "Test", dataURL: "test.data.xml", dataFormat: "xml", dataProtocol: "postXML", fields: [ {name: "id", type: "text", primaryKey: true}, {name: "field1", type: "text"}, {name: "field2", type: "text"}, ], clientOnly: true }); var process = isc.Process.create({ //state: {field1: "valueA", field2: "valueB"}, elements : [ isc.ServiceTask.create({ ID: "data", dataSource: ds, outputFieldList: ["id", "field1", "field2"], operationType: "fetch", criteria: {field1: "valueA"}, nextElement: "script" }), isc.ScriptTask.create({ ID: "script", inputFieldList: ["id", "field1", "field2"], execute: function(input, inputRecord) { isc.logEcho(inputRecord, "ScriptTask"); }, nextElement: "form" }), isc.UserTask.create({ ID: "form", inputFieldList: ["id", "field1", "field2"], outputFieldList: ["id", "field1", "field2"], targetView: isc.Window.create({ ID: "wnd", width: 300, height: 120, items: [isc.DynamicForm.create({ ID: "df", fields:[ {name:"id", type:"text", hidden: true}, {name:"field1", type:"text"}, {name:"field2", type:"text"}, {title:"Submit", type:"submit"} ], })] }), targetForm: "df", nextElement: "gate" }), // isc.XORGateway.create({ ID: "gate", inputFieldList: "field1", criteria: advancedCriteria, failureElement: "errorFlow", nextElement: "goodFlow" }), isc.DecisionGateway.create({ ID: "gate", inputFieldList: ["id", "field1","field2"], criteriaMap: {goodFlow: {field1: "value1"}, errorFlow: {field1: "value2"}}, defaultElement: "errorFlow" }), isc.ScriptTask.create({ ID:"goodFlow", inputFieldList: ["id", "field1", "field2"], execute: function(input, inputRecord) { isc.warn("goodFlow - save"); isc.Window.getById("wnd").hide(); }, nextElement: "save" }), isc.ServiceTask.create({ ID: "save", inputFieldList: ["id", "field1", "field2"], dataSource: ds, operationType: "update", }), isc.ScriptTask.create({ ID:"errorFlow", inputFieldList: ["id", "field1", "field2"], execute: function(input, inputRecord) { isc.warn("errorFlow - try again"); }, nextElement: "script" }) ] }); process.start(); </script> </body> </html>
and MainEntryPoint.java gwt example code:
Code:
package pl.com.tech4.client; import com.google.gwt.core.client.EntryPoint; import com.smartgwt.client.data.Criteria; import com.smartgwt.client.data.DataSource; import com.smartgwt.client.data.Record; import com.smartgwt.client.data.fields.DataSourceTextField; import com.smartgwt.client.types.DSDataFormat; import com.smartgwt.client.types.DSOperationType; import com.smartgwt.client.types.DSProtocol; import com.smartgwt.client.util.SC; import com.smartgwt.client.util.workflow.DecisionGateway; import com.smartgwt.client.util.workflow.ProcessElement; import com.smartgwt.client.util.workflow.ScriptTask; import com.smartgwt.client.util.workflow.ServiceTask; import com.smartgwt.client.util.workflow.UserTask; import com.smartgwt.client.util.workflow.XORGateway; import com.smartgwt.client.widgets.Window; import com.smartgwt.client.widgets.form.DynamicForm; import com.smartgwt.client.widgets.form.fields.SubmitItem; import com.smartgwt.client.widgets.form.fields.TextItem; import java.util.HashMap; public class MainEntryPoint implements EntryPoint { @Override public void onModuleLoad() { layout(); } private void layout() { DataSource ds = new DataSource(); ds.setID("Test"); ds.setDataURL("test.data.xml"); ds.setDataFormat(DSDataFormat.XML); ds.setDataProtocol(DSProtocol.POSTXML); DataSourceTextField id = new DataSourceTextField("id"); id.setPrimaryKey(true); DataSourceTextField field1 = new DataSourceTextField("field1"); DataSourceTextField field2 = new DataSourceTextField("field2"); ds.setFields(id, field1, field2); ds.setClientOnly(true); com.smartgwt.client.util.workflow.Process process = new com.smartgwt.client.util.workflow.Process() { @Override public void finished(Record state) { SC.logWarn("Process finished."); } }; process.setID("process"); ServiceTask dataTask = new ServiceTask(); dataTask.setID("data"); dataTask.setDataSource(ds); dataTask.setOutputFieldList("id", "field1", "field2"); dataTask.setOperationType(DSOperationType.FETCH); dataTask.setCriteria(new Criteria("field1", "valueA")); dataTask.setNextElement("script"); ScriptTask scriptTask = new ScriptTask() { @Override public Object execute(Object input, Record inputRecord) { SC.logEcho(inputRecord.getJsObj(),"scriptTask"); return input; } }; scriptTask.setID("script"); scriptTask.setNextElement("form"); scriptTask.setInputFieldList("id", "field1", "field2"); UserTask formTask = new UserTask(); formTask.setID("form"); formTask.setNextElement("gate"); formTask.setInputFieldList("id", "field1", "field2"); formTask.setOutputFieldList("id", "field1", "field2"); final Window wnd = new Window(); wnd.setWidth(300); wnd.setHeight(120); DynamicForm df = new DynamicForm(); df.setID("df"); TextItem idItem = new TextItem("id"); idItem.setHidden(true); TextItem field1Item = new TextItem("field1"); TextItem field2Item = new TextItem("field2"); SubmitItem submit = new SubmitItem("submit"); df.setFields(idItem, field1Item, field2Item, submit); wnd.addItem(df); formTask.setTargetView(wnd); formTask.setTargetForm(df); // XORGateway gateway = new XORGateway(); // gateway.setCriteria(criteria); // gateway.setNextElement("goodFlow"); // gateway.setFailureElement("errorFlow"); DecisionGateway gateway = new DecisionGateway(); gateway.setID("gate"); HashMap criteriaMap = new HashMap(); criteriaMap.put("goodFlow", new Criteria("field1", "value1")); criteriaMap.put("errorFlow", new Criteria("field1", "value2")); gateway.setCriteriaMap(criteriaMap); gateway.setDefaultElement("errorFlow"); ScriptTask goodFlowTask = new ScriptTask() { @Override public Object execute(Object input, Record inputRecord) { SC.warn("goodFlow - save"); wnd.hide(); return input; } }; goodFlowTask.setID("goodFlow"); goodFlowTask.setInputFieldList("id", "field1", "field2"); goodFlowTask.setNextElement("save"); ServiceTask saveTask = new ServiceTask(); saveTask.setID("save"); saveTask.setDataSource(ds); saveTask.setInputFieldList("id", "field1", "field2"); saveTask.setOperationType(DSOperationType.UPDATE); ScriptTask errorFlowTask = new ScriptTask() { @Override public Object execute(Object input, Record inputRecord) { SC.warn("errorFlow - try again"); return input; } }; errorFlowTask.setID("errorFlow"); errorFlowTask.setInputFieldList("id", "field1", "field2"); errorFlowTask.setNextElement("script"); ProcessElement[] elements = new ProcessElement[7]; elements[0] = dataTask; elements[1] = scriptTask; elements[2] = formTask; elements[3] = gateway; elements[4] = goodFlowTask; elements[5] = saveTask; elements[6] = errorFlowTask; // process.setElements(elements);//does not work process.getOrCreateJsObj(); process.setAttribute("elements", elements, true); //Record state = new Record(); //state.setAttribute("field1Item", "value2"); //process.setState(state); process.start(); } }
Code:
<response> <startRow>0</startRow> <endRow>1</endRow> <totalRows>2</totalRows> <data> <Test> <id>1</id> <field1>valueA</field1> <field2>valueB</field2> </Test> <Test> <id>2</id> <field1>valueC</field1> <field2>valueD</field2> </Test> </data> <status>STATUS_SUCCESS</status> </response>
Comments welcome.
MichalG
Comment