react-form-lib

2.0.0 • Public • Published

react-form-lib - Facilitate React form integration and validation

React-form-lib is a Form framework which provides auto-validated components
With react-form-lib create forms faster in a simple and sementic way.
Avoid validation complexity by externalize and modularize all your business or technical form's validation rules in one place,
inject rules in the form and let the framework validate automatically

Features

  • Easy to maintain validation rules
  • Easy to implement click-stream with native show/hide capability
  • Semantic form integration and illimited DOM depth
  • Some basic form components (Select, RadioList, Label, ErrorMsg)
  • Label and ErrorMsg customization. you can pass custom component in place of default provided components
  • Support HTML5 form components (input...)

Install

npm install --save react-form-lib

API

<Form />

The Form wrapper component

  • The component accepts the following props:
Name Type Description
validationRules? Object A formatted Object which contains all business validation rules by field names
customLabel? Component React component to customize input labels. Inherit labelParams props from FormItems
customError? Component React component to customize input errors. Inherit error props from FormItems
  • How to format validationRules : (replace <> by "name" of field (see example))
const myRules = {
    <name_of_file_to_validate>: [
        {
          key: string | unique,
          message: string,
          isValid: function
        },
        ...
    ],
    <name_of_another_field_to_validate>: [
        {...},
        ...
    ],
    ...
}
  • Schema for each rule in validationRules
Name Type Description
key Object Unique key for this rule
message string Message returned if validation failed
isValid function function which got next field value and existing others form data, as param and return boolean
  • NOTE : for the message of fields marked as required (see FormItem props), You can add a simple rule with the name customGlobalRequiredMessage which contain only a message to override default required message
EXAMPLE 
rules = {
    customGlobalRequiredMessage: {message: 'myCustom required Message which will appear if my formItem is marked as required and is empty'}
}

<FormItem />

This component is a child of the Form component

  • The component accepts the following props:
Name Type Description
name string The schema name of the data of the field (The one which has to be used for validationRules and schema persistence)
type string Reference the type of the field passed as child. Takes only text or radio or select or submit or reset
required? boolean Define if field is required (add red star to label and validate if filled or not with message (or customRequiredMessage => see validationRules notes)
initialValue? ? Initial or Default field value
validationTrigger? string Define when field validation is triggered. takes only onChange for now
inputSubInfo? ? String or Component to add subinfo under input field
labelParams? Object The label params of the field (see schema below)
show? function Function which got all values stored in Form and return boolean to add some logic for show/hide field.
className? string className for field wrapper
callBackAction? function Function which got all values stored in Form called after validationTrigger is triggered.
resetAfterSubmit? boolean Only on FormItem of type 'submit'. if callBackAction Promise is resolved, reset the form
  • Schema of labelParams? object
Name Type Description
text string The label of the field
subLabel? ? String or Component to add subinfo under label text
inlinePosition? boolean Determine if label is on inline position with field or block position
fixedWidth? number fix the width of the label

<Select /> AND <RadioList />

These components are both child of FormItem

  • They accepts only one props:
Name Type Description
className string className for component
dataSet array An array of {label, value} objects
name string inherited from FormItem
onChange function inherited from FormItem
placeHolder? string only for Select : add first disabled option in select
value string inherited from Form : default value
  • Schema of dataSet
[
  {
      label: string,
      value: string
  },
  {...}
]

<Label />

This components is the built in component to display input labels

  • It accepts these props:
Name Type Description
label string content of label
required? boolean default false : display red star if true
subLabel? string Add a small text under label

<ErrorMsg />

This components is the built in component to display input errors

  • It accepts this props:
Name Type Description
error string content of error

Example

  • Here the full example with various use cases.
import React, {useState} from 'react'
import {Form, FormItem, Select, RadioList, ErrorMsg} from "../src";
import "./App.scss";

const enumMrMrs = [
    {label: "Mr", value: "Mr"}, {label: "Mrs", value: "Mrs"}
];
const personTypes = [
    {label: "Parent1", value: "1"},
    {label: "Parent2", value: "2"}
];

function isNotEmpty(v) {
    return v !== undefined && v !== "" && v !== null && v.length !== 0 && v !== [];
}


// You can put these rules in external file and import it
/*All rules have to respect this format to be parsed by validation method in Form.
for each field you want to be validated you have to reference his exact "name" props in this array
then for each entry you have to put a "key" property (what you want : unique), a "message" property as an Error message to display after validation
and a "isValid" property that is a function which takes the value of the field and do whatever you want to return a boolean
You can put more than one rule per field reference.*/
const rules = {
    customGlobalRequiredMessage: "is empty. Please fill it.",
    maidenName: [
        {
            key: "maidenname_invalid",
            message: "This name is not allowed",
            isValid: (nextVal) => (nextVal !== "test")
        },
        {
            key: "maidenname_empty",
            message: "Maiden name is required if you are a girl. Please fill it.",
            isValid: (nextVal, values) => (values.title === '' || values.title === 'Mr' || (values.title === 'Mrs' && isNotEmpty(nextVal)))
        }
    ],
    lastName: [
        {
            key: "lastname_empty",
            message: "Last name can't contains numbers.",
                isValid: (nextVal) => (nextVal.match(/^[a-zA-Z]+$/))
        },

    ],
    firstName: [
        {
            key: "lastname_nonempty_but_firstname_empty",
            message: "FirstName has to contain more than 1 charachter.",
            isValid: (nextVal) => (nextVal.match(/^([A-Za-z]{2,})$/))
        }
    ],
};

const App = () => {

    const [persistOk, setPersistOk] = useState(false);
    const [apiErr, setApiErr] = useState(null);
    const [dataStore, setDataStore] = useState({});

    const persist = (data) => {

        //simulate api call
        let prom = new Promise((resolve, reject) => {
            // comment the resolve method call and uncomment the reject method call to simulate Service error and test ErrorMsg component
            resolve(setDataStore({data: data}))
            //reject("PERSISTENCE_MOCK_ERR_CODE")

        });

        return prom.then(() => {
            setPersistOk(true)
        })
        .catch((err) => {
            setApiErr(err)
            return Promise.reject(err)
        })
    };


    let customLabel = null;
    let customError = null;

    // uncomment these lines to test custom component for input label and input errors
    /*customLabel = (props) => <div style={{color: 'violet'}}>My Custom Label : {props && props.labelParams.text}</div>
    customError = (props) => <div style={{color: 'orange'}}>My Custom Error : {props && props.error}</div>*/


    const inputInfoExample = <label style={{display: 'block'}}>inputSubInfo</label>

    const myLabelWithGlobalParams = ({...myCustomParams}) => {
        return {...myCustomParams, inlinePosition:true, fixedWidth: 200}
    }

    return (
        <>
            <div className={`${persistOk ? 'filter-active' : ""} prf_container inline-block`}>
                {apiErr && <ErrorMsg error={`An error occured ! ${apiErr}`}/>}
                <Form validationRules={rules} customLabel={customLabel} customError={customError} >
                    <FormItem
                        name="person"
                        type={"select"}
                        labelParams={myLabelWithGlobalParams({text:"Person"})}
                        className={"prf_form-item"}
                    >
                        <Select dataSet={personTypes} placeHolder={"Select a type"} className={"prf_select prf_input"}/>
                    </FormItem>
                    <FormItem
                        name="title"
                        type={"radio"}
                        labelParams={myLabelWithGlobalParams({text:"Title civility"})}
                        className={"prf_form-item"}
                    >
                        <RadioList dataSet={enumMrMrs} />
                    </FormItem>
                    <div className={"prf-divider"}/>
                    <FormItem
                        name="maidenName"
                        type={"text"}
                        initialValue={"initial name"}
                        validationTrigger={'onChange'}
                        inputSubInfo={inputInfoExample}
                        labelParams={myLabelWithGlobalParams({text: "Maiden name", subLabel: "Name 'test' is not allowed"})}
                        className={"prf_form-item"}
                    >
                        <input className="prf_input" />
                    </FormItem>
                    <FormItem
                        name="lastName"
                        type={"text"}
                        required={true}
                        labelParams={myLabelWithGlobalParams({text: "Last name"})}
                        className={"prf_form-item"}
                    >
                        <input className="prf_input" />
                    </FormItem>
                    <FormItem
                        name="firstName"
                        type={"text"}
                        required={true}
                        labelParams={myLabelWithGlobalParams({text: "First name"})}
                        show={(values) => (values && values.lastName !== "")}
                        className={"prf_form-item"}
                    >
                        <input className="prf_input" />
                    </FormItem>
                    <div className={"prf-btn-toolbar"}>{/*Here example of wrapper for FormItem inside Form*/}
                        <FormItem
                            type={"submit"}
                            callBackAction={persist}
                            resetAfterSubmit={true} //if callBackAction Promise is resolved form will be reseted
                            className={"inline-block"}
                        >
                            <button className="prf-btn prf-btn--primary" type={"button"}>Submit</button>
                        </FormItem>
                        <FormItem
                            callBackAction={() => setApiErr(null)}
                            type={"reset"}
                            className={"inline-block"}
                        >
                            <button className="prf-btn prf-btn--primary" type={"button"}>Reset</button>
                        </FormItem>
                    </div>
                </Form>
                {persistOk && <div className={`modal`}><div className={"modal-message"}>Data saved correctly <pre>dataStore = {JSON.stringify(dataStore.data, null, 4)}</pre></div><button onClick={() => (setPersistOk(false))} className="prf-btn prf-btn--primary" type={"button"}>OK</button></div>}
            </div>
        </>
    )


}

export default App;

Running locally

go in project folder and run following commands

npm install

npm start

Readme

Keywords

none

Package Sidebar

Install

npm i react-form-lib

Weekly Downloads

0

Version

2.0.0

License

ISC

Unpacked Size

31.5 kB

Total Files

3

Last publish

Collaborators

  • zb2oby