Skip to content

Commit

Permalink
Merge pull request #157 from binary-butterfly/apply-errors-after-runn…
Browse files Browse the repository at this point in the history
…ing-set-multiple-field-values-and-validate

Apply errors after running set multiple field values and validate
  • Loading branch information
DysphoricUnicorn committed Feb 15, 2024
2 parents a9e4c1f + 0ba6fdb commit 318d40a
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 10 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ They will return an object containing/ add the following props:
You can also optionally call this function with an object to override the previous field values as second parameter.
This function returns a promise that resolves with all values after the change.
Note that this does not trigger validation.
- `setMultipleFieldValuesAndValidate` Exactly the same as `setMultipleFieldValues` but it does trigger validation and returns a promise with the validation result
- `setMultipleFieldValuesAndValidate` Exactly the same as `setMultipleFieldValues` but it does trigger validation of all fields, sets the errors and returns a promise with the validation result
- `validateField` A function that allows you to trigger validation for a specific field by passing its name and optionally, to improve
performance, the field's value.
This function returns a promise that will be resolved with either `true` or `false` depending on if the value is valid.
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "formifly",
"version": "2.8.4",
"version": "2.8.5",
"description": "React form handling as light as a butterfly",
"main": "dist/formifly.umd.js",
"module": "dist/formifly.js",
Expand Down
17 changes: 13 additions & 4 deletions src/js/__tests__/components/meta/FormiflyContext.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ describe('FormiflyContext', () => {
foo: new StringValidator('bar'),
});

render(<FormiflyForm shape={shape} onSubmit={() => {}} defaultValues={{fruit: [{name: 'banana', tasty: true}]}}>
render(<FormiflyForm shape={shape} onSubmit={() => {
}} defaultValues={{fruit: [{name: 'banana', tasty: true}]}}>
<AutomagicFormiflyField label="Name" name="fruit.0.name"/>
<AutomagicFormiflyField label="Tasty" name="fruit.0.tasty"/>
<AutomagicFormiflyField label="Foo" name="foo"/>
Expand Down Expand Up @@ -487,34 +488,40 @@ describe('FormiflyContext', () => {

it('provides a setMultipleFieldValuesAndValidate function that can validate correct values', async () => {
const TestForm = () => {
const {setMultipleFieldValuesAndValidate, values} = useFormiflyContext();
const {setMultipleFieldValuesAndValidate, values, errors} = useFormiflyContext();
const [validationSuccess, setValidationSuccess] = React.useState(false);
const setAndValidate = () => {
setMultipleFieldValuesAndValidate([['foo', 'bar'], ['bla', 'blub']]).then(() => setValidationSuccess(true));
};

return <div>
<p>Foo: {values.foo}</p>
<p>Foo error: {errors.foo}</p>
<p>Bla: {values.bla}</p>
<AutomagicFormiflyField label="Foo input" name="foo"/>
<p>Validation success: {validationSuccess ? 'true' : 'false'}</p>
<button onClick={setAndValidate}>Set and validate</button>
</div>;
};
const shape = new ObjectValidator({foo: new StringValidator(), bla: new StringValidator()});
const shape = new ObjectValidator({foo: new StringValidator().required(), bla: new StringValidator()});
const renderResult = render(<FormiflyForm onSubmit={vi.fn()} shape={shape}>
<TestForm/>
</FormiflyForm>);

fireEvent.blur(renderResult.getByLabelText('Foo input'));
const errorMsg = await renderResult.findByText('Foo error: This field is required');
expect(errorMsg).toBeInTheDocument();
fireEvent.click(renderResult.getByText('Set and validate'));
const success = await renderResult.findByText('Validation success: true');
expect(success).toBeInTheDocument();
expect(renderResult.getByText('Foo: bar')).toBeInTheDocument();
expect(renderResult.getByText('Bla: blub')).toBeInTheDocument();
expect(renderResult.queryByText('Foo error: This field is required')).not.toBeInTheDocument();
});

it('provides a setMultipleFieldValuesAndValidate function that can validate incorrect values', async () => {
const TestForm = () => {
const {setMultipleFieldValuesAndValidate, values} = useFormiflyContext();
const {setMultipleFieldValuesAndValidate, values, errors} = useFormiflyContext();
const [validationSuccess, setValidationSuccess] = React.useState(true);
const setAndValidate = () => {
setMultipleFieldValuesAndValidate([['foo', 'bar'], ['bla', '']])
Expand All @@ -526,6 +533,7 @@ describe('FormiflyContext', () => {
<p>Validation success: {validationSuccess ? 'true' : 'false'}</p>
<p>Foo: {values.foo}</p>
<p>Bla: {values.bla === '' ? 'empty string' : values.bla}</p>
<p>Bla error: {errors.bla}</p>
<button onClick={setAndValidate}>Set and validate</button>
</div>;
};
Expand All @@ -539,5 +547,6 @@ describe('FormiflyContext', () => {
expect(success).toBeInTheDocument();
expect(renderResult.getByText('Foo: bar')).toBeInTheDocument();
expect(renderResult.getByText('Bla: empty string')).toBeInTheDocument();
expect(renderResult.getByText('Bla error: This field is required')).toBeInTheDocument();
});
});
11 changes: 9 additions & 2 deletions src/js/components/meta/FormiflyContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,15 @@ export const FormiflyProvider = <T extends ObjectValidator<any>>(props: Formifly
pairs: [string, V][], oldValues: ValueOfValidator<T> = values,
): Promise<DeepPartial<ValueOfValidator<T>> | undefined> => {
return setMultipleFieldValues(pairs, oldValues).then((newValues) => {
return validateAll(newValues);
return validateAll(newValues)
.then(() => {
setErrors({});
return Promise.resolve(newValues);
})
.catch((validationErrors: UnpackedErrors<T>) => {
setErrors(validationErrors);
return Promise.reject(validationErrors);
});
});
};

Expand Down Expand Up @@ -330,7 +338,6 @@ export const FormiflyProvider = <T extends ObjectValidator<any>>(props: Formifly
const result = shape.validate(valuesToValidate, valuesToValidate, valuesToValidate, t);
if (result[0]) {
resolve(result[1]);

} else {
reject(unpackErrors(result));
}
Expand Down

0 comments on commit 318d40a

Please sign in to comment.