Introduction

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.

Steps Example

Step 1 

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

Step 2 

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

Step 3

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

Step 4

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.

  1. Some conversion "to" and "from" for the date is needed as the date is stored as String.
  2. To use the DateTime library, the string needs to be converted to a proper date format first.
  3. The DateTime is converted back to string when storing it back in the database.

Figure 5: Details to pay attention to

Step 5

Result:

Figure 6: Booking Form (Weekly)

Figure 7: Result (Weekly)

Figure 8: Booking Form (Monthly)

Figure 9: Result (Monthly)

Sample App

APP_kb_dx8_meeting_room_booking.jwa

  • No labels