diff --git a/src/functionsfactory.ts b/src/functionsfactory.ts index 3dbace39ee..fb46bc3057 100644 --- a/src/functionsfactory.ts +++ b/src/functionsfactory.ts @@ -371,4 +371,15 @@ function propertyValue(params: any[]): any { const q = getQuestionValueByContext(this, params[0]); return q ? q[params[1]] : undefined; } -FunctionFactory.Instance.register("propertyValue", propertyValue); \ No newline at end of file +FunctionFactory.Instance.register("propertyValue", propertyValue); +function substring_(params: any[]): any { + if(params.length < 2) return ""; + const s = params[0]; + if(!s || typeof s !== "string") return ""; + const start = params[1]; + if(!Helpers.isNumber(start)) return ""; + const end = params.length > 2 ? params[2] : undefined; + if(!Helpers.isNumber(end)) return s.substring(start); + return s.substring(start, end); +} +FunctionFactory.Instance.register("substring", substring_); \ No newline at end of file diff --git a/tests/expressions/expressionParserTest.ts b/tests/expressions/expressionParserTest.ts index ed826bd82a..227d78599e 100644 --- a/tests/expressions/expressionParserTest.ts +++ b/tests/expressions/expressionParserTest.ts @@ -1509,3 +1509,12 @@ QUnit.test("Custom function returns object&array, #7050", function(assert) { FunctionFactory.Instance.unregister("func1"); FunctionFactory.Instance.unregister("func2"); }); +QUnit.test("ExpressionRunner: substring", function(assert) { + var runner = new ExpressionRunner("substring({s}, 1, 3)"); + const values: any = { s: "abcdef" }; + assert.equal(runner.run(values), "bc", "abcdef"); + values.s = undefined; + assert.equal(runner.run(values), "", "undefined"); + values.s = 10; + assert.equal(runner.run(values), "", "10"); +});