Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ufukbakan/formua

React Formua - Stateless validations
https://github.com/ufukbakan/formua

Last synced: about 2 months ago
JSON representation

React Formua - Stateless validations

Awesome Lists containing this project

README

        

Formua



React Stateless Validations

[![NPM Version](https://img.shields.io/npm/v/formua)](https://www.npmjs.com/package/formua)

## Getting Started
### Installation
```
npm i formua
```

### What's New In 1.2.1
- validateForm method added to formua result object
- validatedErrors added to formua result object

### API
```ts
function Formua(params: FormuaParams /*OPTIONAL*/ ): FormuaResult;

type FormuaParams = {
form: HTMLFormElement, // OPTIONAL: Specifies form element explicitly
validations: ValidationMap, // OPTIONAL: Validations per input name
transforms: TransformationMap, // OPTIONAL: Transformations per input name
legacyListeners: boolean // OPTIONAL: Try enabling this if you face compatibility issues
}

type FormuaResult = {
formData: FormData, // Returns transformations applied form data
pureData: FormData, // Returns pure form data
formErrors: Record, // Returns error messages for each invalid input field
isFormValid: boolean // Returns true if all fields are valid otherwise false,
validateForm: () => ValidationResult
validatedErrors: Record // If validateForm method is called once then returns error messages for each invalid input field otherwise returns errors messages for only fields those triggered blur event
}

// FormData is completely immutable
type FormData = {
data: Record; // same as getAll()
get(key): any;
getAll(): Record;
has(key): boolean;
set(key, value): FormData; // returns a new form data with updated key:value, also can be used as append method
select(...keys: string[]): Record; // returns a new form data with only selected fields
drop(...keys: string[]): Record; // returns a new form data without specified fields
keys(): string[];
values(): any[];
entries(): Record;
toString(): string;
toJSON(): Record;
}

type ValidationMap = {
[fieldName: string]: Validation
}

type Validation = {
errorMessage: string,
validator: (o: any) => boolean
}

type ValidationResult = {
isValid: boolean,
errors: Record
}

type TransformationMap = {
[fieldName: string]: TransformerFunction
}

interface TransformerFunction{
(o: any) => any
}

```

### Simple Usage
If you have only single form in the page, formua will automatically detect it and retrieve data from it. A Typescript example is provided below.

```tsx
import { Formua } from "formua";
import { chainAnd, hasNoSpecialCharacters, isEmail, minLength, required } from "formua/helpers";

export default function SignupForm() {

const { formData, pureData, formErrors, isFormValid } = Formua({
validations: {
username: {
errorMessage: "Username is required and must contain no special characters",
validator: chainAnd(required, hasNoSpecialCharacters)
},
email: {
errorMessage: "Please enter your email address",
validator: isEmail
},
password: {
validator: minLength(8),
errorMessage: "Password must be at least 8 characters long"
}
}
});

return (


{formErrors.username && (

{formErrors.username}
)}

{formErrors.email && (
{formErrors.email}
)}

{formErrors["password"] && (
{formErrors["password"]}
)}
Sign Up

);
}

```

### Advanced Usage
The example below shows how to use Formua to validate, transform and post a form data without any statefull input element. Typescript definitions are optional.

```tsx
import axios from "axios";
import { Formua, FormData } from "formua";
import { chainAnd, hasNoSpecialCharacters, isEmail, minLength, minTrimmedLength, sameAs, trim, sameAsField } from "formua/helpers";
import { useEffect, useRef } from "react";

export default function SignupForm() {

const formRef = useRef(null);
const { formData, pureData, formErrors, isFormValid } = Formua({
form: formRef.current,
validations: {
username: {
errorMessage: "Username must be at least 4 characters long and must contain no special characters",
validator: chainAnd(minTrimmedLength(4), hasNoSpecialCharacters)
},
email: {
errorMessage: "Please enter your email address",
validator: isEmail
},
"email-again": {
errorMessage: "Emails do not match",
validator: sameAsField("email")
},
password: {
validator: minLength(8),
errorMessage: "Password must be at least 8 characters long"
},
"password-again": {
errorMessage: "Passwords do not match",
validator: sameAsField("password")
}
},
transforms: {
username: trim
}
});

function submitHandler() {
axios.post("/signup", formData.getAll())
.then(res => console.log("success!"))
.catch(err => console.log("error!"));
}

return (


{formErrors.username && (

{formErrors.username}
)}

{formErrors.email && (
{formErrors.email}
)}

{formErrors["email-again"] && (
{formErrors["email-again"]}
)}

{formErrors["password"] && (
{formErrors["password"]}
)}

{formErrors["password-again"] && (
{formErrors["password-again"]}
)}
Sign Up

);
}
```