diff --git a/src/process/validation/rules/validateCustom.ts b/src/process/validation/rules/validateCustom.ts index f184d469..2968de2d 100644 --- a/src/process/validation/rules/validateCustom.ts +++ b/src/process/validation/rules/validateCustom.ts @@ -36,7 +36,7 @@ export const validateCustomSync: RuleFnSync = (context: ValidationContext) => { context.input = value; }); - if (isValid === null || isValid === true) { + if (isValid === null || isValid === true || isValid === undefined) { return null; } diff --git a/src/utils/__tests__/Evaluator.test.ts b/src/utils/__tests__/Evaluator.test.ts index 9a3aa3cc..7f43b86a 100644 --- a/src/utils/__tests__/Evaluator.test.ts +++ b/src/utils/__tests__/Evaluator.test.ts @@ -267,4 +267,34 @@ describe('Evaluator', function () { 'Travis', ); }); + + it('Should treat undefined variable as true in custom conditional evaluation', function () { + // Simulate the checkCustomConditional logic + const context = { data: {}, form: {}, paths: {}, local: {} }; + // Script does not set 'show', so result should be true + assert.equal( + Evaluator.evaluate('if (false) { show = false; }', context, 'show'), + undefined + ); + // The checkCustomConditional logic would treat undefined as true + // So, simulate that logic here + const value = Evaluator.evaluate('if (false) { show = false; }', context, 'show'); + assert.equal(value === undefined ? true : value, true); + + // Script sets show = false + assert.equal( + Evaluator.evaluate('show = false;', context, 'show'), + false + ); + const value2 = Evaluator.evaluate('show = false;', context, 'show'); + assert.equal(value2 === undefined ? true : value2, false); + + // Script sets show = true + assert.equal( + Evaluator.evaluate('show = true;', context, 'show'), + true + ); + const value3 = Evaluator.evaluate('show = true;', context, 'show'); + assert.equal(value3 === undefined ? true : value3, true); + }); }); diff --git a/src/utils/conditions.ts b/src/utils/conditions.ts index 9b45d787..67adbc08 100644 --- a/src/utils/conditions.ts +++ b/src/utils/conditions.ts @@ -45,6 +45,12 @@ export function checkCustomConditional( return null; } const value = evaluate(condition, context, variable); + // For reverse compatability... if "show" is never set, then it should be shown. This + // comes from the following legacy behavior + // https://github.com/formio/formio.js/blob/973b214ec6bf23d8679d0f5007b3522528abd36d/src/utils/utils.js#L311C33-L311C37 + if (value === undefined) { + return true; + } if (value === null) { return null; }