Joget DX 8 Stable Released
The stable release for Joget DX 8 is now available, with a focus on UX and Governance.
element - Element that this binder is tie to. (org.joget.apps.form.model.Element)
primaryKey - The primary key provided by the element to load data. (java.lang.String)
formData - The data holder of the whole form. (org.joget.apps.form.model.FormData)
Load user data using jdbc.
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import org.joget.apps.app.service.AppUtil; import org.joget.apps.form.model.Element; import org.joget.apps.form.model.FormData; import org.joget.apps.form.model.FormRow; import org.joget.apps.form.model.FormRowSet; import org.joget.commons.util.LogUtil; public FormRowSet load(Element element, String username, FormData formData) { FormRowSet rows = new FormRowSet(); if (username != null && !username.isEmpty()) { Connection con = null; try { // retrieve connection from the default datasource DataSource ds = (DataSource)AppUtil.getApplicationContext().getBean("setupDataSource"); con = ds.getConnection(); // execute SQL query if(!con.isClosed()) { PreparedStatement stmt = con.prepareStatement("SELECT username, firstName, lastName, email from dir_user where username=?"); stmt.setObject(1, username); ResultSet rs = stmt.executeQuery(); while (rs.next()) { FormRow row = new FormRow(); System.out.println(rs.getObject("username") ); row.setProperty("username", (rs.getObject("username") != null)?rs.getObject("username").toString():""); row.setProperty("firstName", (rs.getObject("firstName") != null)?rs.getObject("firstName").toString():""); row.setProperty("lastName", (rs.getObject("lastName") != null)?rs.getObject("lastName").toString():""); row.setProperty("email", (rs.getObject("email") != null)?rs.getObject("email").toString():""); rows.add(row); break; } } } catch(Exception e) { LogUtil.error("Sample app - Form 1", e, "Error loading user data in load binder"); } finally { //always close the connection after used try { if(con != null) { con.close(); } } catch(SQLException e) {/* ignored */} } } return rows; } //call load method with injected variable return load(element, primaryKey, formData);
Load time zone as the select box options.
import java.util.Map; import org.joget.apps.app.service.AppUtil; import org.joget.apps.form.model.Element; import org.joget.apps.form.model.FormData; import org.joget.apps.form.model.FormRow; import org.joget.apps.form.model.FormRowSet; import org.joget.apps.form.service.FormUtil; import org.joget.commons.util.TimeZoneUtil; public FormRowSet load(Element element, String username, FormData formData) { FormRowSet rows = new FormRowSet(); //Get timezones using timezone util for(Map.Entry entry : TimeZoneUtil.getList().entrySet()){ FormRow option = new FormRow(); option.setProperty(FormUtil.PROPERTY_VALUE, (String) entry.getKey()); option.setProperty(FormUtil.PROPERTY_LABEL, (String) entry.getValue()); rows.add(option); } return rows; } //call load method with injected variable return load(element, primaryKey, formData);
Load user as options based on the group id passed by the controlling field.
import java.util.Collection; import org.joget.apps.app.service.AppUtil; import org.joget.apps.form.model.Element; import org.joget.apps.form.model.FormData; import org.joget.apps.form.model.FormRow; import org.joget.apps.form.model.FormRowSet; import org.joget.apps.form.service.FormUtil; import org.joget.directory.model.User; import org.joget.directory.model.service.ExtDirectoryManager; public FormRowSet load(String[] values) { FormRowSet rows = new FormRowSet(); ExtDirectoryManager directoryManager = (ExtDirectoryManager) AppUtil.getApplicationContext().getBean("directoryManager"); //set groupId based on dependency value String groupId = null; if (values != null && values.length > 0) { groupId = values[0]; } //Get users using directory manager Collection userList = directoryManager.getUsers(null, null, null, null, groupId, null, null, "firstName", false, null, null); for(Object u : userList){ User user = (User) u; FormRow option = new FormRow(); option.setProperty(FormUtil.PROPERTY_VALUE, user.getUsername()); option.setProperty(FormUtil.PROPERTY_LABEL, user.getFirstName() + " " + user.getLastName()); rows.add(option); } return rows; } //call load method with injected variable return load(values);
Compare the submitted value with the value of another field.
import java.util.Arrays; import org.joget.apps.app.service.AppUtil; import org.joget.apps.form.model.Element; import org.joget.apps.form.model.Form; import org.joget.apps.form.model.FormData; import org.joget.apps.form.service.FormUtil; public boolean validate(Element element, FormData formData, String[] values) { boolean result = true; //get field 1 value from form data object String field1Id = "field1"; Form form = FormUtil.findRootForm(element); Element field1 = FormUtil.findElement(field1Id, form, formData); if (field1 != null) { //get value of field 1 String[] compareValues = FormUtil.getElementPropertyValues(field1, formData); //compare the value of field 2 and field 1 are equals if (!Arrays.equals(values, compareValues)) { String id = FormUtil.getElementParameterName(element); formData.addFormError(id, "Value not equal!!!!"); result = false; } } else { //ignore if the field 1 not exist } return result; } //call validate method with injected variable return validate(element, formData, values);
Check the current user's username are same with the form field "creator" value. The following sample using Form Hash Variable to retrieve form field value.
import java.util.Map; import org.joget.directory.model.User; public boolean isAuthorized(User user, Map params) { //using hash variable to get "creator" field value and escapes it with java syntax, then compare with current username return "#form.crm_account.creator?java#".equals(user.getUsername()); } //call isAuthorized method with injected variable return isAuthorized(user, requestParams);
Randomly assign an user in a department to a workflow activity
import java.util.ArrayList; import java.util.Collection; import org.joget.apps.app.service.AppUtil; import org.joget.directory.model.User; import org.joget.directory.model.service.ExtDirectoryManager; import org.joget.workflow.model.WorkflowActivity; public Collection getAssignees(WorkflowActivity activity) { Collection assignees = new ArrayList(); ExtDirectoryManager directoryManager = (ExtDirectoryManager) pluginManager.getBean("directoryManager"); String deptId = "D-005"; //Get total user in department Long total = directoryManager.getTotalUsers(null, null, deptId, null, null, null, null); //Get random number from 0 to the total number of users in department int random = (int) (Math.random() * total); //Get users using directory manager Collection userList = directoryManager.getUsers(null, null, deptId, null, null, null, null, "firstName", false, random, 1); for(Object u : userList){ User user = (User) u; assignees.add(user.getUsername()); } return assignees; } //call getAssignees method with injected variable return getAssignees(workflowActivity);
Do not use wildcard in import statement. It giving a very bad performance in Bean Shell interpreter to search the whole package and loads it in memory.
Don't:
import java.util.*;
Do:
import java.util.Collection;
Bean Shell interpreter cannot recognise the element type syntax of collections class like Collection, Map, List, Set and etc.
Don't:
Map<String, String> map = new HashMap<String, String>();
Do:
Map map = new HashMap();
It will make yours and others life easier to maintain and review the script whenever necessary as Joget Workflow provided flexibility to adapt change quickly.
If your script is pretty long and some parts of the script are reusable, please make use of function to write your script. It provided better reading and performance.
It will helps you and others to understand what is the purpose for the script quickly.
If you are using a lot of Bean Shell Scripting in your app, a meaningful log message can help you to locate your issue quickly.
Don't
try { //do something } catch (Exception e) { LogUtil.error("BeanShell", e, "Error executing script"); }
Do:
try { //do something } catch (Exception e) { LogUtil.error("CRM app - Backend userview", e, "Error retrieving user department in Report category permission"); }
If your script need to reuse for multiple times in an app or can be used by others app in future development, please consider to make your Bean Shell script as a plugin instead of copy and paste it multiple times across your app. Bean Shell script is harder to maintain in this case. Imagine that you want to make a change, you will have to update all the places that are using the same script as well. Beside that, a normal plugin implementation will have better performance than a script running by a Bean Shell interpreter.