1.1.7 • Published 4 years ago

mytabworks-react-form-validator v1.1.7

Weekly downloads
5
License
MIT
Repository
github
Last release
4 years ago

mytabworks-react-form-validator

This repository is a light-weight, eazy, fast, powerlful and ultimately... beautiful!, yes! you read it exactly as it is. It is light-weight because it was build from the ground up, no extra dependency added. it dont need reducer to call over time and don't need to pass on a event handler to children to children. The rules is extendable and yet reusable. It can be extend with your own rules added in the framework, so there is no need to redundantly create a rules. It is easy to implement, because in just a few characters you are validating. it can be implemented with other component without a sweat, cheers! It is fast because it is made to be fast, it was build to make the state rest from every entry, and it don't need to call the whole reducer like redux does. It is powerful bacause you can rules your form field components without affecting your properties. that is why it can be easily use in both small and scalable projects. It is beautiful because it don`t need a ugly and redandunt hard to maintain conditional rules code, and rendering of event handlers to children to children, because rules can be implemented beautifully in components to components without the old fashion terror implementation. The rules style is inspired by Laravel Validator!.

installation

npm i mytabworks-react-form-validator

How to use

import to your project

import {Form, Input, TextArea, Select} from "mytabworks-react-form-validator"

Stylesheet

mytabworks-form-validator Form component doesn't require stylesheet. however for component Input, TextArea, and Select need a stylesheet. it is seperated to reduce payload when not using field components

import "mytabworks-react-form-validator/field.css"

Basic Usage

<Form>
    <Input type="text" id="name" name="name" placeholder="enter your name..." label="Name"/>
    <Select id="vote" name="vote" label="Level">
        {[
            {label: "I like It", value: "1"}, 
            {label: "I Hate It", value: "4"}
        ]}
    </Select>
    <TextArea id="comment" name="comment" placeholder="what is on your mind..."/>
</Form>

Advance Usage with rules

<Form>
    <Input rules="required|alpha" type="text" id="name" name="name" placeholder="enter your name..." label="Name"/>
    <Input rules="required|email" type="text" id="email" name="email" placeholder="enter your email..." label="E-mail"/> 
    <Input rules="required" type="radio" id="gender" name="gender" className="inline-box" label="Gender" >
        {[
            {label: "Male", value: "1"},
            {label: "Female", value: "2"},
        ]}
    </Input>
    <Input rules="min:2|max:3" type="checkbox" id="interest" name="interested[]" className="inline-box" label="Interested">
        {[
            {label: "javascript", value: "1", defaultChecked: true},
            {label: "c#", value: "2", disabled: true},
            {label: "python", value: "3"},
            {label: "java", value: "4"}
        ]}
    </Input>
    <Select rules="required" id="level" name="level" label="Level">
        {[  
            {label: "choose one..", value: ""},
            {label: "beginer", value: "1"},
            {label: "mid-level", value: [
                {label: "intermidiate", value: "2"},
                {label: "exprerience", value: "3"}
            ]},  
            {label: "expert", value: "4"}
        ]}
    </Select>
    <TextArea rules="required" id="about" name="about" placeholder="describe your self..." defaultValue="I'am" label="About yourself"/>
    <Input rules="mimes:pdf,csv|max:2" type="file" id="resume" name="resume" multiple label="Your Resume`"/>

    <button type="submit" style={{padding:"10px 15px", backgroundColor:"ivory"}}>Submit me</button>
</Form>

Customizable

It can implement rules in new and old component without changing its property structure

Before Customize

import React from 'react'

export const Design = ({disabled = false}) => {

    return (
      <div>
          <div>
              <label>labelUI</label>
              <input name="ui" disabled={disabled}/>
          </div>
          <div>
              <label>labelUX</label>
              <input name="ux" disabled={disabled}/> 
          </div>
      </div>
    )
}

After Customize

import React from 'react'
import { useFormState } from "mytabworks-react-form-validator"

export const Design = ({disabled = false}) => {
    /*using form state*/
    const {formRegister, formUpdate, formState} = useFormState(React.useContext)
    
    /*getting the state of the fields*/
    const {ui, ux} = formState() 
    
    const registration = [
      {name:'ui', label:'labelUI', rules: 'required|max:10'},
      {name:'ux', label:'labelUX', rules: 'required|min:10'}
    ]
    
    /*registration of the fields to the state*/
    registration.forEach(registry => {
      formRegister(registry, React.useEffect)
    })
    
    /*formUpdate can use indirectly. when you need to get the value or other things*/
    /*it can also use directly in the eventListeners*/
    const indirectFormUpdateUse = e => {
        formUpdate(e)
        /*do other things here*/
    }

    return (
      <div>
          <div>
              <label>labelUI</label>
              <input name="ui" disabled={disabled} onChange={formUpdate}/> /*formUpdate direct use*/
              /*field state is use to render a message if invalid*/
              {ui && ui.isInvalid && <span className="your-style">{ui.message}</span>} 
          </div>
          <div>
              <label>labelUX {ux && ux.isInvalid && ux.message}</label>
              <input name="ux" disabled={disabled} onChange={indirectFormUpdateUse} /> /*formUpdate indirect use*/
          </div>
      </div>
    )
  }

Implementation of Customize

import React from 'react'
import { Form } from "mytabworks-react-form-validator"
import { Design } from "../Design"

export const Fields = () {
    return (
        <Form>
            <Design/>
            <button type="submit">Submit</button>
        </Form>
    )
}

Form Submition

const handleSubmit = (formevent) => {
    if(formevent.isReady()) { 
        /*all fields rules is passed*/
        
        fetch("/request", {
            method: "POST", 
            headers: {
                // "Content-Type": "application/json"
                "Content-Type": "application/x-www-form-urlencoded",
            },
            body: formevent.param() /*for json use formevent.json(), for FormData use formevent.formData()*/
        })
        .then(/*next move*/)

    } else {
        /*some fields rules is failed*/
    }
}
<Form id="form-fields" onSubmit={handleSubmit}>
    /*form fields*/ 
    <button type="submit">Submit</button>
</Form>

rules

What are the current or supported rules

What are the extension rules

How to extend a rules)

Validator does not require to repeatedly extend rules each component, you only have to extend rules each once, I suggest to import it to the ancestors component that handle all Forms

import { Validator } from "mytabworks-utils";
import { 
    max_size, 
    min_size,
    required_if,
    alpha_space
} from "mytabworks-utils/extend/rules";
// required_if:name_of_target_field=target_expected_value 
// required_if can use @ as Alias to cover the real name_of_target_field and target_expected_value because they are mostly developer readable 
// required_if's target_expected_value can be regular expression or a normal string
// all those who have second parameter can use @ as Alias
// max_size:kilobytes
// min_size:kilobytes
// alpha_space
Validator.rulesExtend({ max_size, min_size, required_if, alpha_space })
    import {Input} from "mytabworks-react-form-validator"

    export const ReasonFields = () =>{
        retrun (
            <div>
                <Input type="text" rules="alpha_space" name="rss" id="rss" label="Reasons"/>
                <Input type="file" rules="required_if:rss@Reasons=(.+)@has content|mimes:jpeg,jpg,xls|min_size:1000|max_size:5000" name="flexa" id="flexa" label="File XA"/>
                <Input type="text" rules="required_if:flexa=(.*\.(jpeg|jpg))@spreadshit" name="commit" id="commit" label="Commit"/>
            </div>
        )
    }

How to create a customize rules

import { Validator } from "mytabworks-utils";
import { 
    same
} from "mytabworks-utils/extend/rules";
// same:name_of_target_field 
// all those who have second parameter can use @ as Alias
const strong_password = {
    regexp: /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).+$/g,
    exe(
        received, /*it is the value of the input you put*/
        first_param, /*rules:first_param*/ 
        second_param    /*rules:first_param=second_param*/
    ) {
        /*we don't need first_param and second_param for this rules*/
        /*must return true when it is INVALID*/
        return !this.regexp.test(received)
    },
    message: "The :attribute must have 1 small letter, 1 capital letter, 1 number, and 1 special character"
    /*note! the :attribute is replace with the label of the form field you rules*/
    /*note! if you have first_param in your rules you must put the same name as your rules like :strong_password in the message*/
    /*note! if you have second_param you must put :third_party in the message*/
}

Validator.rulesExtend({ same, strong_password })
    import {Form, Input} from "mytabworks-react-form-validator"

    export const Register = () =>{
        retrun (
            <Form>
                <Input type="text" rules="required|alpha" name="hname" id="hname" label="Name"/> 
                <Input type="password" rules="required|strong_password" name="p_word" id="p_word" label="Password"/> 
                <Input type="password" rules="required|same:p_word@Password" name="confirm" id="confirm" label="Confirm"/>
                <button type="submit">Submit</button>
            </Form>
        )
    }

Form Properties

All properties that is supported by Form Component. The datatypes with "*" means it is required.

PROPERTYDATATYPESDEFAULTDESCRIPTION
form defaults attributemozila form documentationand w3schools form documentationAll the default attributes of the form element tag can be use. visit the link for more info.
onSubmitfunctioninstance FormEvent will be passed unto the function argument with the capablities of getting the form data of the form.

FormEvent methods for Form onSubmit

All properties that is supported by instance FormEvent.

METHODSRETURNSDESCRIPTION
.targetform elementIt will get the form element.
.locateFailed()integerIt will locate the form field that fails the requirements. you can adjust the position by passing a int parameter .locateFailed(70/default is 40/) depends on your navbar height if it is floating
.isReady()booleanIt will check if the form is ready and passed all the requirement rules.
.json()objectIt will return the form data in json.
.paramArray()arrayIt will return the form data in array.
.param()stringIt will return the form data in url encode string.
.formData()FormDatait will return instance of FormData.
.forEach(/callback/)voidit will loop each of the form data.

Select Properties

All properties that is supported by Select Component. The datatypes with "*" means it is required.

PROPERTYDATATYPESDEFAULTDESCRIPTION
idstring *id of the HTML select
namestring *name of the HTML select
labelstringthe label of your form field
valuearray|stringthe set the controllable value
defaultValuearray|stringthe set the default value
classNamestringadditional className for the Component container
disabledboleanfalsedisabling the Select
multiplebooleanfalseit allow users to select multiple option
onChangefunctionit enables to subscribe change event
rulesstringit enables to rules the form field
aliasstringit enables to distinctively rules a form field with the same name, especially when user have priviledges to add new field
....etcyou can passed on anything in select tag supported or data-something

Select option properties

All the properties of each option

PROPERTYDATATYPESDEFAULTDESCRIPTION
labelstring *label of the option
valuestringarray *the value of the option, if array of object of label and value will be group in optgroup
....etcyou can passed on anything individually supported or data-something

Select option with group usage

<Form>
    <Select id="emotions" name="emotions" defaultValue={["1","2"]} multiple={true}>
        {[  
            {label: "Possitive", value: [
                {label: "Happy", value: "1"},
                {label: "Excited", value: "2"}
            ]}, 
            {label: "Negative", value: [
                {label: "Sad", value: "3"},
                {label: "Angry", value: "4"}, 
                {label: "Scared", value: "5"}
            ]},
            {label: "Hype", value: "6"},
            {label: "Pretty", value: "7"}
        ]}
    </Select>
</Form>

TextArea Properties

All properties that is supported by TextArea Component. The datatypes with "*" means it is required.

PROPERTYDATATYPESDEFAULTDESCRIPTION
idstring *id of the HTML textarea
namestring *name of the HTML textarea
labelstringthe label of your form field
valuearray|stringthe set the controllable value
defaultValuearray|stringthe set the default value
placeholderstringplaceholder of your textarea
classNamestringadditional className for the Component container
disabledbooleanfalsedisabling the textarea
onChangefunctionit enables to subscribe change event
rulesstringit enables to rules the form field
aliasstringit enables to distinctively rules a form field with the same name, especially when user have priviledges to add new field
....etcyou can passed on anything in textarea tag supported or data-something

Input Properties

All properties that is supported by Input Component. The datatypes with "*" means it is required.

PROPERTYDATATYPESDEFAULTDESCRIPTION
idstring *id of the HTML input
namestring *name of the HTML input
typestringtexttype of the HTML input. all the type in input field is supported, but radio and checkbox have small different mechanics because it is a selection
labelstringthe label of your form field
valuearray|stringthe set the controllable value only for type of fields that supported it
defaultValuearray|stringthe set the default value only for type of fields that supported it
placeholderstringplaceholder of your input exluded radio, checkbox, color, range
classNamestringadditional className for the Component container
disabledbooleanfalsedisabling the input
onChangefunctionit enables to subscribe change event
rulesstringit enables to rules the form field
aliasstringit enables to distinctively rules a form field with the same name, especially when user have priviledges to add new field
....etcyou can passed on anything in input tag supported or data-something

Input type [checkbox, radio] children individual properties

All the properties of the Individual children of type checkbox, radio

PROPERTYDATATYPESDEFAULTDESCRIPTION
labelstring *label in the Input Component is the label of the form field container and this is the label of your input type checkbox, radio
valuestring *the value of the input type checkbox, radio
disabledbooleanfalsedisabling the checkbox, radio individually
defaultCheckedbooleanfalseit will checked individually the type checkbox, radio
....etcyou can passed on anything individually supported or data-something

Example for type [checkbox, radio]

/*All properties set in Input will be a property of all the individual except [className, label, rules] because this will all goes in form field container*/
<Form>
    <Input type="checkbox" id="interest" name="interested[]" className="inline-box" label="Interested">
        {[
            {label: "javascript", value: "1", defaultChecked: true},
            {label: "c#", value: "2", disabled: true},
            {label: "python", value: "3"},
            {label: "java", value: "4"}
        ]}
    </Input>
</Form>

License

MIT Licensed. Copyright (c) Mytabworks 2020.