Skip to content

Commit efdd32c

Browse files
committed
fix(renderer): add support for string pattern and flags
1 parent bf9c01a commit efdd32c

File tree

6 files changed

+78
-9
lines changed

6 files changed

+78
-9
lines changed

packages/react-form-renderer/src/form-renderer/condition.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import get from 'lodash/get';
77
const isEmptyValue = (value) => typeof value === 'number' || value === true ? false : lodashIsEmpty(value);
88

99
const Condition = ({ condition, children }) => {
10-
const fieldCondition = (value, { is, isNotEmpty, isEmpty, pattern, notMatch }) => {
10+
const fieldCondition = (value, { is, isNotEmpty, isEmpty, pattern, notMatch, flags }) => {
1111
if (isNotEmpty){
1212
return !isEmptyValue(value);
1313
}
@@ -17,7 +17,9 @@ const Condition = ({ condition, children }) => {
1717
}
1818

1919
if (pattern) {
20-
return notMatch ? !pattern.test(value) : pattern.test(value);
20+
const regExpPattern = RegExp(pattern, flags);
21+
22+
return notMatch ? !regExpPattern.test(value) : regExpPattern.test(value);
2123
}
2224

2325
const isMatched = Array.isArray(is) ? !!is.includes(value) : value === is;

packages/react-form-renderer/src/parsers/default-schema-validator.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ const checkCondition = (condition, fieldName) => {
5858
`);
5959
}
6060

61-
if (condition.hasOwnProperty('pattern') && !(condition.pattern instanceof RegExp)) {
61+
if (condition.hasOwnProperty('pattern') && (!(condition.pattern instanceof RegExp) && typeof condition.pattern !== 'string')) {
6262
throw new DefaultSchemaError(`
6363
Error occured in field definition with name: "${fieldName}".
64-
Field condition must have "pattern" of instance "RegExp"! Instance received: [${condition.pattern.constructor.name}].
64+
Field condition must have "pattern" of instance "RegExp" or "string"! Instance received: [${condition.pattern.constructor.name}].
6565
`);
6666
}
6767
};

packages/react-form-renderer/src/tests/form-renderer/render-form.test.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,52 @@ describe('renderForm function', () => {
311311
expect(wrapper.find(CustomComponent)).toHaveLength(1);
312312
});
313313

314+
it('should render condition field only if the pattern condition is met (string)', () => {
315+
const formFields = [{
316+
component: 'custom-component',
317+
name: 'foo',
318+
condition: {
319+
when: 'bar',
320+
pattern: 'fuzz',
321+
},
322+
}];
323+
const wrapper = mount(
324+
<ContextWrapper formFieldsMapper={{
325+
'custom-component': CustomComponent,
326+
}}>
327+
{ renderForm(formFields) }
328+
</ContextWrapper>
329+
);
330+
expect(wrapper.find(CustomComponent)).toHaveLength(0);
331+
332+
wrapper.find(Form).instance().form.change('bar', 'fuzz');
333+
wrapper.update();
334+
expect(wrapper.find(CustomComponent)).toHaveLength(1);
335+
});
336+
337+
it('should render condition field only if the pattern condition is met (string with flags)', () => {
338+
const formFields = [{
339+
component: 'custom-component',
340+
name: 'foo',
341+
condition: {
342+
when: 'bar',
343+
pattern: 'fuzz',
344+
flags: 'i',
345+
},
346+
}];
347+
const wrapper = mount(
348+
<ContextWrapper formFieldsMapper={{
349+
'custom-component': CustomComponent,
350+
}}>
351+
{ renderForm(formFields) }
352+
</ContextWrapper>
353+
);
354+
expect(wrapper.find(CustomComponent)).toHaveLength(0);
355+
356+
wrapper.find(Form).instance().form.change('bar', 'fUzz');
357+
wrapper.update();
358+
expect(wrapper.find(CustomComponent)).toHaveLength(1);
359+
});
314360
it('should render condition field only if the pattern condition is not met', () => {
315361
const formFields = [{
316362
component: 'custom-component',

packages/react-form-renderer/src/tests/parsers/__snapshots__/default-schema-validator.test.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ exports[`Default schema validator should fail if field condition is not correct
4141
exports[`Default schema validator should fail if field condition pattern property is not correct type. 1`] = `
4242
"
4343
Error occured in field definition with name: \\"foo\\".
44-
Field condition must have \\"pattern\\" of instance \\"RegExp\\"! Instance received: [Number].
44+
Field condition must have \\"pattern\\" of instance \\"RegExp\\" or \\"string\\"! Instance received: [Number].
4545
"
4646
`;
4747

packages/react-form-renderer/src/tests/parsers/default-schema-validator.test.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ describe('Default schema validator', () => {
9494
}]}, formFieldsMapper)).toThrowErrorMatchingSnapshot();
9595
});
9696

97+
it('should not fail if field condition pattern property is a string', () => {
98+
expect(() => defaultSchemaValidator({ fields: [{
99+
component: 'foo',
100+
name: 'foo',
101+
condition: { when: 'Foo', pattern: '^pattern' },
102+
}]}, formFieldsMapper)).not.toThrow();
103+
});
104+
97105
it('should fail if field condition have notMatch property and have not is/pattern.', () => {
98106
expect(() => defaultSchemaValidator({ fields: [{
99107
component: 'foo',

packages/react-renderer-demo/src/app/pages/renderer/condition.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,21 @@ condition: {
146146
pattern: /bar/,
147147
}
148148

149-
// Foo = 'This is a bar' => true
150-
// Foo = 'Foo foo baar!' => true
149+
// Foo = 'bar' => true
150+
// Foo = 'baar!' => false
151+
```
152+
153+
It also accepts string value, then you have to use additional property flags if you need to specify RegExp flags:
154+
155+
```jsx
156+
condition: {
157+
when: 'Foo',
158+
pattern: 'bar',
159+
flags: 'i'
160+
}
161+
162+
// Foo = 'bar' => true
163+
// Foo = 'bAr!' => true
151164
```
152165

153166
### Not match
@@ -161,8 +174,8 @@ condition: {
161174
notMatch: true,
162175
}
163176

164-
// Foo = 'This is a bar' => false
165-
// Foo = 'Foo foo baar!' => true
177+
// Foo = 'bar' => false
178+
// Foo = 'baar!' => true
166179
```
167180

168181
```jsx

0 commit comments

Comments
 (0)