Skip to content

Commit

Permalink
Fix validateOn events.
Browse files Browse the repository at this point in the history
  • Loading branch information
webblocksapp committed Mar 25, 2024
1 parent c5e7d3c commit 145099f
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 5 deletions.
Expand Up @@ -40,8 +40,13 @@ export const ValidateOnImpl: Component = () => {
</div>
</div>
<div class="mb-3 w-100">
<button class="btn btn-primary me-2 mt-2">Submit</button>
<button disabled={formHandler.isFormInvalid()} class="btn btn-primary me-2 mt-2">
Submit
</button>
</div>
<pre>
<code>{JSON.stringify(formHandler._.getFormState(), null, 2)}</code>
</pre>
</form>
</>
);
Expand Down
@@ -0,0 +1,12 @@
import type { Meta } from 'storybook-solidjs';

import { ValidateOnZodImpl } from '.';

const meta = {
title: 'BS5 Implementations',
component: ValidateOnZodImpl,
} satisfies Meta<typeof ValidateOnZodImpl>;

export default meta;

export const ValidateOnZod = {};
53 changes: 53 additions & 0 deletions packages/lib/examples/implementations/ValidateOnZodImpl/index.tsx
@@ -0,0 +1,53 @@
import { Component } from 'solid-js';
import { useFormHandler } from '@hooks';
import { zodSchema } from '@adapters';
import { TextInput } from '@example-components';
import { z } from 'zod';

export type Schema = { name: string; email: string };

export const schema = z.object({
name: z.string().min(1, 'Required field'),
email: z.string().email().min(1, 'Required field'),
});

export const ValidateOnZodImpl: Component = () => {
const formHandler = useFormHandler(zodSchema(schema), {
validateOn: ['input'],
});
const { formData } = formHandler;

const submit = async (event: Event) => {
event.preventDefault();
try {
await formHandler.validateForm();
alert(JSON.stringify(formData()));
formHandler.resetForm();
} catch (error) {
console.error(error);
}
};

return (
<>
<form onSubmit={submit}>
<div class="row gy-3">
<div class="col-sm-12 col-md-6">
<TextInput label="Name" name="name" formHandler={formHandler} />
</div>
<div class="col-sm-12 col-md-6">
<TextInput label="Email" name="email" formHandler={formHandler} />
</div>
</div>
<div class="mb-3 w-100">
<button disabled={formHandler.isFormInvalid()} class="btn btn-primary me-2 mt-2">
Submit
</button>
</div>
<pre>
<code>{JSON.stringify(formHandler._.getFormState(), null, 2)}</code>
</pre>
</form>
</>
);
};
6 changes: 3 additions & 3 deletions packages/lib/src/components/Field/index.tsx
@@ -1,5 +1,5 @@
import { CommonEvent, FieldProps, SetFieldValueOptions, ValidateFieldOptions } from '@interfaces';
import { createEffect, createUniqueId, splitProps } from 'solid-js';
import { createEffect, createUniqueId, mergeProps, splitProps } from 'solid-js';
import { useFieldContext, withFieldProvider } from '@hocs';
import {
CheckboxField,
Expand Down Expand Up @@ -48,16 +48,16 @@ export const Field = withFieldProvider((props: FieldComponentProps) => {
* if no form field event attribute matches the expected interface.
*/
const onFieldBlur = (options?: ValidateFieldOptions) => {
props.formHandler?.validateField?.(props.name, options);
props.formHandler?.touchField?.(props.name);
props.formHandler?.setFieldValue(props.name, props.formHandler?.getFieldValue(props.name), options);
};

/**
* Extended onBlur event.
*/
const onBlur: FieldComponentProps['onBlur'] = (event) => {
//Form handler prop validate and touch the field.
onFieldBlur(props.onBlurOptions);
onFieldBlur({ ...props.onBlurOptions, validateOn: ['blur'] });

//onBlur prop is preserved
if (typeof props.onBlur === 'function') {
Expand Down
10 changes: 9 additions & 1 deletion packages/lib/src/hooks/useFormHandler/index.ts
Expand Up @@ -199,8 +199,16 @@ export const useFormHandler = <T = any>(validationSchema: ValidationSchema<T>, o
_?: FormStateUpdateBehavior
): Promise<any> => {
if (!path) return;
const validateOn = options?.validateOn || formHandlerOptions.validateOn;

options = {
touch: true,
dirty: true,
validate: hasEventTypes(validateOn),
mapValue: (value) => value,
...options,
};

options = { touch: true, dirty: true, validate: true, mapValue: (value) => value, ...options };
setFieldData(path, value, { mapValue: options.mapValue });

const promises = Promise.all([
Expand Down

0 comments on commit 145099f

Please sign in to comment.