Small library to simplify the use of forms in React
With a simple higher-order component (HOC), you can get:
- The values of the inputs.
- The status of the form.
- Control of validations.
Examples.
- Simple Form
- Advanced Form
- Field Generator Form
-
Custom Fields Use of the getInput interface ({ name, value, onChange}). IMPORTANT: onChange parameter is an object with target and the value:
onChange({ target: { value } });
Getting Started
Installation
You can install with NPM: @jkr26/react-forms-builder-logic
npm i --save @jkr26/react-forms-builder-logic
Step 1: Create your component and do the HOC
import { formWrapper, Form } from "@jkr26/react-forms-builder-logic";
class ExampleFormComponent extends React.Component {
...
}
export const ExampleForm = formWrapper(ExampleFormComponent);
Step 2: Add the fields and initialize the form.
...
constructor(props) {
super(props);
this.setFields();
}
setFields() {
this.props.form.initForm({
name: {
defaultValue: "asdasd",
validators: [minStringValidator, maxStringValidator, isRequired]
},
age: {
defaultValue: "2017-06-01",
validators: [isRequired]
},
email: {
defaultValue: "jesus-aaaaaa@gml.c",
validators: [emailValidator, isRequired]
},
repeatEmail: {
validators: [equalValidatorEmail, isRequired]
},
policyPrivacy: {
defaultValue: true,
validators: [isRequired]
}
},
true
);
}
...
initForm
second param optional: true for validation fields in real time || [default] false only in submit state
Step 3: Do not forget, add to each of the fields of your html form your handler (props.form.getInput, props.form.getSelect, ...)
...
render() {
const { form } = this.props;
return (
<div>
<Form form={form}>
Name:
<input type="text" {...form.getInput("name")} />
Age:
<input type="date" {...form.getInput("age")} />
Email:
<input type="text" {...form.getInput("email")} />
Repeat email:
<input type="text" {...form.getInput("repeatEmail")} />
Condiciones de privacidad:
<input type="checkbox" {...form.getCheckbox("policyPrivacy")} />
<button>Submit</button>
</Form>
</div>
);
}
...
Step 4: Wrapper form html
...
<Form form={form}>
...
Step 5: Finally, you will receive the result of the form by props, "componentDidUpdate"
...
componentDidUpdate() {
if (this.props.form.isValidAfterSubmit) {
console.log("Send data:", this.props.form.values);
}
}
...
Optional: you can get the errors of each of the fields
...
render() {
...
<Form form={form}>
Name:
<input type="text" {...form.getInput("name")} />
{form.getErrors("name").map(e => (
<span key={e} style={{ color: "red" }}>
{e}
</span>
))}
Age:
<input type="date" {...form.getInput("age")} />
{form.getErrors("age").map(e => (
<span key={e} style={{ color: "red" }}>
{e}
</span>
))}
...
- You can also get all the errors, with props
props.form.errors
.
Optional: control submit
...
handleSubmit = e => {
e.preventDefault();
(...)
this.props.form.submit();
};
render() {
...
<Form form={form}>
Name:
<input type="text" {...form.getInput("name")} />
{form.getErrors("name").map(e => (
<span key={e} style={{ color: "red" }}>
{e}
</span>
))}
<button onClick={this.handleSubmit}>
Submit
</button>
...
Doc
Functions
function | params | description |
---|---|---|
initForm() |
{ exampleFieldName: { defaultValue: "foo", validators: [Validator1, Validator2, ValidatorN ] } } , boolean
|
Add the init form fields, along with their default value and validations. The second parameter indicates validations in real time, by default false. Method used in the contructor()
|
setFields() |
{ exampleFieldName: { defaultValue: "foo", validators: [Validator1, Validator2, ValidatorN ] } } |
Add the form fields, along with their default value and validations. |
setValues() |
{ nameField1: "foo", nameField2: "var", nameFieldN: "test" } |
Set values. The form must have the loading to false . |
clear() |
no params |
Set default values for errors , values and isValidAfterSubmit . |
getErrors() |
nameField |
Get the errors of a field. Returns an error array or an empty one. |
getInput() |
nameField |
Get input attributes. Only text, number and date. |
getSelect() |
nameField |
Get input attributes. Only for select. |
getCheckbox() |
nameField |
Get input attributes. Only for simple checkbox: true/false. |
getRadio() |
"nameField" , "value"
|
Get input attributes. Only for radio type. |
getCheckboxMulti() |
"nameField" , "value"
|
Get input attributes. Only for check with multiple options. |
Render props
prop | types | default value | description |
---|---|---|---|
errors |
{ elementKey: String[], ... } |
{} |
Errors by fields. |
values |
{ element: String, ... } |
{} |
Values by fields. |
isValidAfterSubmit |
boolean |
false |
All fields comply with their validations. After submit() . |
isValid |
boolean |
false |
All fields comply with their validations in real time. Example: <button style={{ backgroundColor: form.isValid ? "green" : "red" }}>Submit</button>
|
init |
boolean |
true |
false , when the form is ready. After initForm() . |
Component Form
Although the philosophy is not to create components, for the best control of the form we had to create a Form component to guarantee the load cycles and the alerts of uncontrolled components when they change to controlled:
...
<Form form={this.props.form}>
...
Validations
Example
The validation "isRequired" is included in the library.
Other examples of validation:
import { Validator } from "@jkr26/react-forms-builder-logic";
export const startWithJJ = new Validator(value => {
const error = "The element must start with jj.";
if (value && /^jj/.test(value)) {
return false;
}
return error;
});
export const maxStringValidator = new Validator(value => {
const error = "The item must have less than 10 characters.";
if (value && value.length < 10) {
return false;
}
return error;
});
export const emailValidator = new Validator(value => {
const error = "Invalid email";
const emailPattern = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (value && emailPattern.test(String(value).toLowerCase())) {
return false;
}
return error;
});
export const equalValidatorEmail = new Validator((value, formFields) => {
const error = "THE EMAIL DOES NOT MATCH.";
if (value && value === formFields.email.value) {
return false;
}
return error;
});
The validators work in a very simple way, as the first parameter they receive the value of the element and as a second parameter they receive all the values of the form, as an object: formFields = { name: "John", age: "33", email: "john@example.com", repeatEmail: "john" }
MIT License.