Joget DX 8 Stable Released
The stable release for Joget DX 8 is now available, with a focus on UX and Governance.
This article discusses how to implement a recurrence function in a Joget app. The recurrence function can be achieved by using Beanshell Form Binder as the store binder. The idea behind this implementation is to use a custom script to handle the storing part.
The recurring function is built on top of the Meeting Room Booking App for DX from Joget marketplace. You may download the app before starting this tutorial to ensure a smooth implementation.
Assuming you have a booking app, add a "recurring" checkbox and "period of recurrence" select box element to your booking form as shown in Figure 1.
Figure 1: Add checkbox and select box form element
Figure 2: Form Layout
In the booking form, go to Settings>Configure Form>Advanced. And set the "Save data to" field to Beanshell as shown in Figure 3.
Figure 3: Advanced Setting
Paste the following code to the script field as shown in Figure 3.
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.model.FormStoreBinder; import org.joget.plugin.base.PluginManager; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import org.joget.commons.util.UuidGenerator; public FormRowSet store(Element element, FormRowSet rows, FormData formData) { //check the rows is not empty before store it if (rows != null && !rows.isEmpty()) { //Get the submitted data FormRow row = rows.get(0); recurring = row.getProperty("recurring"); if(recurring.equals("true")){ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); // create the formatter that cater to our form field period = row.getProperty("period"); start_date = row.getProperty("start_date"); end_date = row.getProperty("end_date"); PluginManager pluginManager = (PluginManager) AppUtil.getApplicationContext().getBean("pluginManager"); FormStoreBinder binder = (FormStoreBinder) pluginManager.getPlugin("org.joget.apps.form.lib.WorkflowFormBinder"); for(i = 0; i < 10; i++){ // we assume the iteration to be 10 times. can be controlled with more logics row.setId(UuidGenerator.getInstance().getUuid()); // we give this row a new uuid on each loop so it saves as a new row in the database if(period.equals("weekly")){ //use plusWeeks row.setProperty("start_date", formatter.format(LocalDateTime.parse(start_date, formatter).plusWeeks(i))); row.setProperty("end_date", formatter.format(LocalDateTime.parse(end_date, formatter).plusWeeks(i))); } else if(period.equals("monthly")){ // use plusMonths row.setProperty("start_date", formatter.format(LocalDateTime.parse(start_date, formatter).plusMonths(i))); row.setProperty("end_date", formatter.format(LocalDateTime.parse(end_date, formatter).plusMonths(i))); } binder.store(element, rows, formData); // store the modified row at the end of the loop } } else{ // we just do a normal store binding PluginManager pluginManager = (PluginManager) AppUtil.getApplicationContext().getBean("pluginManager"); FormStoreBinder binder = (FormStoreBinder) pluginManager.getPlugin("org.joget.apps.form.lib.WorkflowFormBinder"); binder.store(element, rows, formData); } } return rows; } //call store method with injected variable return store(element, rows, formData);
Figure 4: Paste code into script field
In the Beanshell code, it checks for the 'recurring' flag and its time period. The code will store the form data multiple times based on the specified parameters. In the example provided in this article, it iterates 10 times, meaning that it will store the booking information into the database 10 times. Feel free to make any necessary changes accordingly.
Figure 5: Details to pay attention to
Result:
Figure 6: Booking Form (Weekly)
Figure 7: Result (Weekly)
Figure 8: Booking Form (Monthly)
Figure 9: Result (Monthly)