In long multi-section forms built with Joget DX, standard field validators display error messages next to each input. When a user submits a long form with multiple missing fields, they often have to scroll up and down repeatedly to find which required fields failed.
In this guide, we'll write a JavaScript snippet that intercepts Joget's submit button (#section-actions input), collects all unfulfilled field requirements, displays a clean SweetAlert popup summary, and smooth-scrolls directly to the first invalid field.
How It Works
-
Event Interception: The script unbinds Joget's default click handler on section action buttons (
$("#section-actions input").not("#cancel, #saveAsDraft").off("click")) and attaches a custom validator wrapper. -
Dynamic Inspection: It iterates through a validation matrix, automatically skipping fields that are currently disabled (
disabled) or read-only (readonly). -
Modal Alert & Smooth Scroll: If validation fails, all missing field notifications are concatenated into a modal alert. Upon closing the alert,
element.scrollIntoView({ behavior: "smooth", block: "center" })automatically focuses the user's screen on the first invalid input.
The Code
Add a Custom HTML element at the bottom of your Joget form and paste the code below:
<!-- Include SweetAlert2 for clean modal notifications (Optional) -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script>
$(document).ready(function () {
// Allow Joget internal scripts to finish initializing
setTimeout(function () {
const $submitButtons = $("#section-actions input").not("#cancel, #saveAsDraft");
// Remove default submit handler and attach custom validation suite
$submitButtons.off("click").on("click", function (event) {
event.preventDefault();
const $clickedButton = $(this);
// Define validation rules array
const validationRules = [
{
element: "input[name=request_date]",
value: $("input[name=request_date]").val()?.trim(),
isDisabled: $("input[name=request_date]").prop("disabled") || $("input[name=request_date]").prop("readonly"),
message: "• Please select the Request Date."
},
{
element: "select[name=department_category]",
value: $("select[name=department_category]").val()?.trim(),
isDisabled: $("select[name=department_category]").prop("disabled"),
message: "• Please select a Department Category."
},
{
element: "textarea[name=justification]",
value: $("textarea[name=justification]").val()?.trim(),
isDisabled: $("textarea[name=justification]").prop("disabled"),
message: "• Please provide a business Justification."
}
];
let firstInvalidSelector = null;
const errorList = [];
// Inspect enabled fields only
validationRules.forEach(rule => {
if (!rule.isDisabled) {
const isValid = !!rule.value;
if (!isValid) {
errorList.push(rule.message);
if (!firstInvalidSelector) {
firstInvalidSelector = rule.element;
}
}
}
});
// Display validation modal if errors are present
if (errorList.length > 0) {
if (typeof Swal !== "undefined") {
Swal.fire({
title: "Required Fields Missing",
html: "<div style='text-align:left; font-size:14px; line-height:1.6;'>" + errorList.join("<br>") + "</div>",
icon: "warning",
confirmButtonColor: "#0056b3",
confirmButtonText: "Review Form"
}).then(() => {
// Smooth-scroll screen to first invalid field
setTimeout(() => {
const targetElem = document.querySelector(firstInvalidSelector);
if (targetElem) {
targetElem.scrollIntoView({ behavior: "smooth", block: "center" });
targetElem.focus();
}
}, 200);
});
} else {
alert("Please complete the following required fields:\n\n" + errorList.join("\n"));
}
return false;
}
// All validations passed - submit form normally
$clickedButton.closest("form").submit();
});
}, 800);
});
</script>
Key Benefits
- Better User Experience: Displays a single consolidated popup summary rather than multiple scattered error labels.
- Auto Focus: Automatically scrolls the browser window to the first field needing attention.
- Conditional Aware: Smartly ignores fields hidden or disabled by Joget Form Visibility rules.
Top comments (0)