In Joget DX forms, standard cascading drop-down lists work well when selecting a single parent item. However, when a user selects multiple items in a multi-select box or checkbox group, cascading target options requires a custom BeanShell Form Options Binder.
In this guide, we'll write a Java/BeanShell script that receives an array of selected parent keys, queries related child items from the database using SQL PreparedStatements, and returns a populated FormRowSet formatted for Joget Select Box and Multi-Select elements.
How It Works
-
Array Inspection: When a parent multi-select field changes, the options binder receives an array of selected keys (
values). - Prepared Statement Loop: The script iterates through the selected parent IDs, executing a parameterized query to fetch corresponding child options.
-
FormRowSet Construction: For each database match, a
FormRowobject is created with two essential properties:-
FormUtil.PROPERTY_VALUE: The stored value / primary key. -
FormUtil.PROPERTY_LABEL: The display label shown in the UI.
-
The BeanShell Form Options Binder Script
Open your Joget Form in Form Builder, select the target Multi-Select or Select Box element, set Options Binder to BeanShell Form Options Binder, and paste the script below:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.sql.DataSource;
import org.joget.apps.app.service.AppUtil;
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.LogUtil;
FormRowSet optionRows = new FormRowSet();
// Ensure parent selection contains values
if (values != null && values.length > 0) {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
DataSource ds = (DataSource) AppUtil.getApplicationContext().getBean("setupDataSource");
con = ds.getConnection();
if (con != null && !con.isClosed()) {
// Build SQL query for matching child records based on selected parent categories
String sql = "SELECT id, c_supplier_name, c_registration_code " +
"FROM app_fd_registered_suppliers " +
"WHERE c_category_id = ? " +
"ORDER BY c_supplier_name ASC";
ps = con.prepareStatement(sql);
for (Object valObj : values) {
if (valObj == null) continue;
String selectedCategoryId = valObj.toString().trim();
if (selectedCategoryId.isEmpty()) continue;
ps.setString(1, selectedCategoryId);
rs = ps.executeQuery();
while (rs.next()) {
String supplierId = rs.getString("id");
String supplierName = rs.getString("c_supplier_name");
String code = rs.getString("c_registration_code");
FormRow row = new FormRow();
row.setProperty(FormUtil.PROPERTY_VALUE, supplierId);
row.setProperty(FormUtil.PROPERTY_LABEL, supplierName + " (" + code + ")");
optionRows.add(row);
}
rs.close();
}
}
} catch (Exception e) {
LogUtil.error("MultiSelect Options Binder", e, "Error fetching dynamic options");
} finally {
if (rs != null) try { rs.close(); } catch (Exception e) {}
if (ps != null) try { ps.close(); } catch (Exception e) {}
if (con != null) try { con.close(); } catch (Exception e) {}
}
}
return optionRows;
AJAX Trigger Setup in Form Builder
To update the target multi-select dropdown immediately when the parent field selection changes without reloading the page:
- Edit the Target Multi-Select / Select Box in Form Builder.
- Under Advanced Options, check AJAX Change Option.
- Set Listen to Field to your parent Multi-Select element ID (e.g.
category_ids).
Key Advantages
- Multi-Parent Filtering: Unlike standard single-select cascading dropdowns, this script handles multi-selection filtering effortlessly.
-
SQL Injection Safe: Uses
PreparedStatement.setString()to execute queries safely.
Top comments (0)