react-shield-form
v0.1.0
Published
A form library that shields you from all the nasty stuff, when dealing with forms.
Downloads
6
Readme
React Shield Form
A form library that shields you from all the nasty stuff, when dealing with forms.
Hail Brethern, and....Sistren! Ahh Forms, something we all hate dealing with, instead of focusing on our Mission, we have to deal with all kinds of issues when it comes to forms, even for the most simplest tasks.
Spend more time drinking ale! and less time battling state management and validations!
react-shield-form keeps track of state, errors and handles validations (some basic validations are provided baked in, though you're free to use your own), you can let the library handle alot of this for you, though for more specific edge cases, various API's are exposed to allow you to use the library as you need.
Installation
Using your favourite package manager cough yarn cough.
NPM
npm install react-shield-form
YARN
yarn add react-shield-form
NOTE
- There are no dependencies required though, currently you do need to be able to use async / await this may change in the near future and I will remove this constraint.
- react-shield-form relies on the new context-api so you would need to use React v16+
Validations
react-shield-form comes with various validations baked in, to cover most of your general needs. The validations prop expects an array to be passed with strings from the selection below.
Default Validations
Currently these are the following validations which are included in react-shield-form
- "required": This field must have a value inside
- "min:number": The minimum required characters in the field E.g. "min:3"
- "max:number": The maximum characters allowed in a field E.g. "max:15"
- "numbers": Only numeric characters
- "email": (OWASP Regex) Email Validation
- "safe-text": (OWASP Regex) Lower and upper case letters and all digits
- "credit-card": (OWASP Regex) Valid Credit / Debit Card no.
- "valid-ip": (OWASP Regex) Valid IP No Validation
- "simple-password": (OWASP Regex) 4 to 8 character password requiring numbers and both lowercase and uppercase letters
- "complex-password": (OWASP Regex) 4 to 32 character password requiring at least 3 out 4 (uppercase and lowercase letters, numbers and special characters) and no more than 2 equal characters in a row
MORE TO COME
Custom Validations
You can pass in an object inside of the array to provide your own rules for validations also such as the example below. What errMsg is the error which will be displayed if the validation requirements are not met
Sync Custom Validation
const validations = [
{
errMsg: "You must have more than 2 characters!"
validate: input => input.length < 2
}
]
Async Custom Validation
Async validations are also handled, if you want to check on the server for specific cases. You must add the async flag, and the validate function must then return a promise.
const validations = [
"required",
{
async: true,
errMsg: "This field should not include the string javascript!"
validate: input => fakeApiCall(input)
}
]
const fakeApiCall = input => {
return new Promise((resolve) => {
setTimeout(() => {
if (input.includes("javascript")) {
resolve();
}
}, 500);
});
};
Simple Form Example
The examples below are not opinionated, the Feedback component, does not need to be placed within the same Group component. You are free to add in your own components, images etc inside of the form, to style it to your needs.
Note
- The ID is Required in your Input components
- The ID for the feedback must match the ID of the Input for validation feedback
- The Feedback component with ID of "server" will display global messages
import { Form, Label, Input, Feedback, Submit, Group } from "react-shield-form";
<Form onSubmit={onSubmit} async>
<Group>
<Label>Name:</Label>
<Input type="text" id="name" validations={["required"]} validateOnChange />
<Feedback id="name" />
</Group>
<Group>
<Button type="submit">Submit</Button>
</Group>
<Feedback id="server" />
</Form>
// MOCK API Call
function onSubmit(values) {
const testCase = true;
return new Promise((resolve, reject) => {
setTimeout(() => {
if (testCase) {
// Message to be displayed on success of form submit
resolve("Form has been submitted!");
} else {
// Message to be displayed if error returned from server
reject("Oh no there has been a server error!");
}
}, 500);
});
}
Advanced Form Example
The library is compatible with any CSS Framework, in the example below Bootstrap CSS classnames are being used
Note
- errorClass: This is the class that will be appended when a validation error is raised to style the feedback how you like
- validateOnChange: This will run the validations on each key change in real time.
const validations = [
"required",
{
async: true,
errMsg: "This field should not include the string javascript!"
validate: input => fakeApiCall(input)
}
]
const fakeApiCall = input => {
return new Promise((resolve) => {
setTimeout(() => {
if (input.includes("javascript")) {
resolve();
}
}, 500);
});
};
<Form
onError={this.onError}
onChange={this.onChange}
onSubmit={this.onSubmit}
async
>
<Group className="form-group">
<Label>Name</Label>
<Input
type="text"
id="name"
className="form-control"
errorClass="input-error"
validations={validations}
validateOnChange
/>
<Feedback id="name" errorClass="feedback-error" />
</Group>
<Group className="form-check">
<Input
id="agree"
type="checkbox"
className="form-check-input"
validateOnChange
validations={["required"]}
/>
<Label className="form-check-label">
Agree to terms and conditions
</Label>
<Feedback id="agree" errorClass="feedback-error" />
</Group>
<Group
className="d-flex justify-content-between">
<Button className="btn btn-primary" type="submit">
Submit
</Button>
</Group>
<Feedback
id="server"
errorClass="feedback-error"
successClass="feedback-success"
/>
</Form>
onChange = (state, target) => {
// The whole form state on each change
// The target is provided also, so you know which form element was changed
};
onError = (form, server) => {
// Array of all form validation errors
// The server error thrown
};
// MOCK API Call
onSubmit = async values => await AuthSignIn(values);
const AuthSignIn = () => {
const testCase = true;
return new Promise((resolve, reject) => {
setTimeout(() => {
if (testCase) {
resolve("Form Submitted!");
} else {
reject("There has been a server error!");
}
}, 500);
});
};
Form handle loadinging
The form can manage loading state for you when it is in submission, below is an example of how the group with the Submit button should be used.
- Pass in the
handleLoading
prop - You also need to pass in a component which will be rendered while loading
<Group
handleLoading
loader={<YourCustomLoader />}
className="d-flex justify-content-between">
<Button className="btn btn-primary" type="submit">
Submit
</Button>
</Group>
Password Validation Example
The form is handled as the examples above, below will show how you can manage password validation
- The
validate
function also exposes a 2nd argument, which is all the forms state values - You can use this to compare different fields to do things such as checking both password fields match
- If
Input
type ispassword
it will allow you to pass a component in theicon
prop
const checkPassword = [
{
errMsg: "Do not match!",
validate: (input, values) => {
if (input !== values["password"]) return false;
return true;
}
}
];
<Group className="form-group">
<Label>Password</Label>
<Input
type="password"
icon={
<img
className="icon-image"
height="25"
src="http://www.iconarchive.com/download/i99461/webalys/kameleon.pics/Key.ico"
/>
}
id="password"
className="form-control"
successClass="input-success"
errorClass="input-error"
validations={["simple-password"].concat(checkPassword)}
validateOnChange
/>
<Feedback
id="password"
successClass="feedback-success"
errorClass="feedback-error"
/>
</Group>
<Group className="form-group">
<Label>Confirm Password</Label>
<Input
type="password"
icon={
<img
height="25"
src="http://www.iconarchive.com/download/i99461/webalys/kameleon.pics/Key.ico"
/>
}
id="confirm-password"
className="form-control"
successClass="input-success"
errorClass="input-error"
validations={checkPassword}
validateOnChange
/>
<Feedback
id="confirm-password"
successClass="feedback-success"
errorClass="feedback-error"
/>
</Group>
Component API
Input
The input component can take the following props:
- id: This is for the library to identify the component REQUIRED - String
- type: "text" | "number" | "textarea" REQUIRED - String
- className: The customize the component how you like
- style: For inline styling as you would a normal react js component
- errorClass: The CSS to be appended to the input when a validation error occurs E.g. Red border around input
- successClass: The CSS to be appended to the input when a validation requirements are met E.g. Green border around input
- validations: The expects an Array of either strings or objects (See validations)
- validateOnChange: This is to trigger the fields validation check while typing
- validateOnBlur: This is to trigger the fields validation check on Blur
- icon: When
type="password"
you can pass in a component for your icon to trigger the input to show either password or text
Feedback
- id: This is for the library to identify the component - This must match a current Input you have named in the form REQUIRED - String
- className: The customize the component how you like
- errorClass: The CSS to be appended to the input when a validation error occurs E.g. Make the text green (This will be useful when successClass is implemented)
- successClass: The CSS to be appended to the input when a validation requirements are met E.g. Green text success message
- successMsg: The message to display when validation requirements are met
Group
- className: The customize the component how you like
- handleLoader: Set this prop if you want the form to handle form loading on form submission
- loader: Pass in a component to render while form is submitting form
Button
PROPS
- id: "reset" | None OPTIONAL
- "reset": Button will reset form state to originail initialization state
- type: "submit" | None OPTIONAL
- "submit": Button will act as a normal submit button
Todo
- Handle Select Inputs
- Handle Radio Buttons
- Handle success validation on fields
Future Roadmap
- Handle 3rd Party Form Elements