@simosol/forms
v2.0.0
Published
These forms work only with react stateless components. React hooks should be available.
Downloads
39
Keywords
Readme
Forms
Requirements
These forms work only with react stateless components. React hooks should be available.
Installation
npm install @simosol/forms --save
Basic usage
The example, which includes every use case and possible api call.
import * as React from 'react';
import { Form, useForm, useError, useValidated, ValidationRuleSimple } from '@simosol/forms';
import * as rules from '@simosol/forms/lib/rules';
import FormInput, { KeysOfType } from '@simosol/forms/lib/FormInput';
// prepare common rules
const required = rules.required('Field is required'); // accepts message, returns rule function
const email = rules.email('Invalid e-mail'); // accepts message, returns rule function
const ruleNumber = rules.number('Should be a number'); // accepts message, returns rule function
// custom simple validation rule, check min string length
const customRuleMinLength =
(min: number, message: string): ValidationRuleSimple =>
(value: any) => {
if (typeof value !== 'string' || value.length < min) return message;
};
// custom complex rule with dependence of other fields
// one field should be less than other field, if values are numeric
const customRuleLess =
<T, >(otherField: keyof T, message: string) =>
(value: T[keyof T], form: Form<T>) => {
const fieldIsNotEmpty = rules.required()(value) === undefined;
const fieldIsNumber = rules.number()(value) === undefined;
const otherFieldValue = form.getValue(otherField);
const otherFieldValidated = form.isValidated(otherField);
const otherFieldIsNumber = rules.number()(otherFieldValue) === undefined;
if (
fieldIsNotEmpty &&
otherFieldValidated &&
otherFieldIsNumber &&
fieldIsNumber &&
Number(value) >= Number(otherFieldValue)
) {
return message;
}
};
const CompanyRegister = () => {
// prepare data
const data = React.useState(() => ({
companyName: 'Your company name', // pre-filled value
email: '',
revenue: '',
profit: '',
password: '',
passwordConfirm: '',
}))[0];
// create form, using data and validation rules
const form = useForm(
data,
{
companyName: rules.required('Company name is required'), // custom required message
email: [email],
revenue: [required, ruleNumber],
profit: [ruleNumber, customRuleLess('revenue', 'Should be less than revenue')],
password: [rules.required('Password is required'), customRuleMinLength(6, 'Minimum password length is 6')],
passwordConfirm: [
required,
rules.same('password', 'Should be same as password'),
],
},
);
const onSubmitClick = () => {
// if all fields are valid, then do something (send request etc.)
if (form.validateAll()) {
console.log('do something');
}
};
const onErrorClick = () => {
// this is needed, when something went wrong
// show custom email error
form.setError('email', 'E-mail already exists');
};
return (
<div>
<Field field={'companyName'} form={form} label={'Company name'}/>
<Field field={'email'} form={form} label={'E-mail'}/>
<Field field={'revenue'} form={form} label={'Revenue'}/>
<Field field={'profit'} form={form} label={'Profit'}/>
<Field field={'password'} form={form} label={'Password'}/>
<Field field={'passwordConfirm'} form={form} label={'Confirm password'}/>
<div>
<button onClick={onSubmitClick}>Submit</button>
</div>
<div>
<button onClick={onErrorClick}>Error</button>
</div>
</div>
);
};
// simple field component with label and error
const Field = <T, >(
props: { label: string, field: KeysOfType<T, string>, form: Form<T>},
) => {
const { field, label, form } = props;
const error = useError(form, field);
const validated = useValidated(form, field); // if field was validated at least once
const borderColor = validated ? (error ? 'red' : 'green') : 'none';
return (
<div style={{ paddingBottom: 16 }}>
<div>{label}</div>
<div>
<FormInput style={{ borderColor }} field={field} form={form}/>
</div>
<div>{error}</div>
</div>
);
};
export default CompanyRegister;