I just got this code working, and it's pretty useful, so I wanted to share here for anyone else that may benefit from it.
This code allows a user to reject a form created in the Layout Designer without needing to fill in all required fields.
I was previously doing this by having code populate the submission action into a hidden field and then having Field Rules remove the required validation based on that field value (Link to Example). But this is a code-only solution (no hidden field and no Field Rules) so it's much easier to add on to new forms.
This was tested in Forms Version 12.0.2509.20409
/*Bypass required fields on form reject by user.
The reqFields array is declared outside the function so that it carries across multiple submission attempts.
If the Reject button is used, the required validation of the fields is removed, even if the submission fails
for another reason.
However, another submission attempt (non-Reject) will reinstate the required validation of those fields
based on what is carried over in the reqFields array from the prior Reject submission attempt.*/
var reqFields = [];
LFForm.onFormSubmission(async function (event) {
const userAction = event.data.action.value;
if (userAction == 'Reject') {
reqFields = LFForm.findFields(f => f.settings.required);
for (const e of reqFields) {
await LFForm.validateFields(e, {"required": false});
}
}
else {
for (const e of reqFields) {
await LFForm.validateFields(e, {"required": true});
}
}
});
EDIT: Based on feedback from Zac St. Louis, I removed the await keyword from line 11 because the LFForm.findFields function runs synchronously.
EDIT AGAIN: Modified code with more feedback from Zac St. Louis. Rather than looping through the array, it verifies the array isn't empty and passes the whole array to the LFForm.validateFields function, so that improves functionality. Also addresses some edge cases around the initial Reject submission failing (for a different reason than required fields) and ensuring the required fields are reapplied before any other submissions.
/*Bypass required fields on form reject by user.
The reqFields array is declared outside the function so that it carries across multiple submission attempts.
If the Reject button is used, the required validation of the fields is removed, even if the submission fails
for another reason.
However, another submission attempt (non-Reject) will reinstate the required validation of those fields
based on what is carried over in the reqFields array from the prior Reject submission attempt.*/
let reqFields = [];
LFForm.onFormSubmission(async function (event) {
const userAction = event.data.action.value;
if (userAction == 'Reject') {
reqFields = LFForm.findFields(f => f.settings.required);
if (reqFields.length > 0) {
await LFForm.validateFields(reqFields, { "required": false });
}
}
else {
const stillReq = LFForm.findFields(f => f.settings.required).filter((f) => reqFields.findIndex(rf => rf.fieldId === f.fieldId) === -1);
const allReq = reqFields.concat(stillReq);
if (allReq.length > 0) {
await LFForm.validateFields(allReq, { "required": true });
}
}
});