1. Why This Matters
If the same user is selected for multiple approval roles, approvals lose segregation and audits become weak.
This validator blocks duplicate user selections at form submission time.
2. Where to Use in Joget
- Form Builder: add this as a Custom Validator on each approver-related field.
- Suitable fields: dropdown, select box, or user picker fields storing usernames.
- Not for Workflow Builder or API Builder: this is pre-submission form validation.
3. Configuration You Must Set
Update these field IDs to match your form:
reviewerauthorizerapprover
Attach the same validator script to each of these fields so each selected value is checked against the other roles.
4. Validator Code
5. Quick Validation Checklist
- Select the same user in two roles: form must fail with duplicate error.
- Select different users across roles: form must submit.
- Leave a required role empty: form must show empty-field error.
6. Security and Publishing Note
- Keep sample field IDs generic when sharing publicly.
- Do not publish real usernames, emails, internal group names, or environment-specific IDs.
7. Final Note
This validator is small but high impact: it enforces role separation before workflow execution and prevents approval design mistakes early.
Source Code
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;
import org.joget.commons.util.LogUtil;
import java.util.Arrays;
public boolean validate(Element element, FormData formData, String[] fileUploadValues) {
try {
// Get dropdown select box value
//String ProcessOwner = "ProcessOwner";
String reviewerFieldName = "reviewer";
String authorizerFieldName = "Authorizer";
String approverFieldName = "Approver";
Form form = FormUtil.findRootForm(element);
//Element ProcessOwnerElement = FormUtil.findElement(ProcessOwner, form, formData);
Element reviewerElement = FormUtil.findElement(reviewerFieldName, form, formData);
Element authorizerElement = FormUtil.findElement(authorizerFieldName, form, formData);
Element approverElement = FormUtil.findElement(approverFieldName, form, formData);
if (fileUploadValues != null && reviewerElement != null && authorizerElement != null && approverElement != null) {
// Get values of the four dropdowns
//String[] ProcessOwnerValues = FormUtil.getElementPropertyValues(ProcessOwnerElement, formData);
String[] reviewerValues = FormUtil.getElementPropertyValues(reviewerElement, formData);
String[] authorizerValues = FormUtil.getElementPropertyValues(authorizerElement, formData);
String[] approverValues = FormUtil.getElementPropertyValues(approverElement, formData);
String id = FormUtil.getElementParameterName(element);
if (fileUploadValues[0].isEmpty()) {
formData.addFormError(id, "ProcessOwner cannot be Blank");
return false;
}
if (fileUploadValues[0].equals(reviewerValues[0]) || Arrays.asList(authorizerValues).contains(fileUploadValues[0]) || fileUploadValues[0].equals(approverValues[0])) {
formData.addFormError(id, "Process Owner must be Unique");
return false;
}
} else {
// Ignore if any of the dropdowns do not exist
return false;
}
// Return true if validation passes
return true;
} catch (Exception e) {
// Handle the exception (e.g., log it)
//LogUtil.error(getClass().getName(), e.getMessage(), e);
return false; // Or handle the exception in a way that makes sense for your application
}
}
// Call validate method with injected variable
return validate(element, formData, values);
// Maintenance note: this snippet is the reference version for the
// "All Approvers Should Be Unique" article and should be updated carefully
// if the validation fields or form names change.
Top comments (0)