# Ms React Reactive Form

an implementation of the Reactive Form concept in React, supporting Javascript and Typescript with Full support for Functioal and Class Components

## Features

- Useing FormGroup, FormControl, Validators
- Initialize Form with a little amount of coding
- Having BaseValidator to return error type for each Input with its own Validity and Form Validity with Submission Status
- Having SetValidators and RemoveValidators to change Input Roles in runtime
- Compatiable with Javascript and Typescript
- Compatiable with Functional and Class Components
=

## Full Example
Full Example in https://github.com/EgAlexDeveloper/Ms-React-Reactive-Form
please check the Js and Ts branches

## Teck
- [React JS] - built for React Java script applications
- [React TS] - built for React Type script applications
- [Typescript] - the plugin build in Typrscript and transpilied to Javascript

## Installation
Install the dependencies and devDependencies and start the server.

```sh
yarn add ms-react-reactive-form
npm i ms-react-reactive-form
```

## Typescript Examples
# Funtional Component
``` TSX
    // init FormGroup
    const form: FormGroup = new FormGroup({
        password: new FormControl("", [Validators.required(), Validators.pattern(/[0-9]/)])
    });
    
    // Store Form in State
    const [passwordForm, updatePasswordForm] = useState<FormGroup>(form);
    
    // Form Submit
    const save = (event: FormEvent<HTMLFormElement>) => {
        event.preventDefault();
        
        // Call Reactive Form Base Validator
        let validate = new BaseValidator(passwordForm);
        // Process validation
        validate.analysis()
            .then(controls => {
                // Fetch Final Validation Results
                let res = validate.result(controls);
                
                // update form state must be called here
    
                // handel success submittion
                if (res.form.validity) {
                    console.log(res.payload);
                } else {
                    // handel failed submittion
                    console.log(res.form)
                }
            });
    };
    
    // Update Form Values
    const changeHandler = (event: FormEvent<HTMLInputElement>) => {
        const { name, value } = event.currentTarget;
        passwordForm.controls[name].setValue(value);
        // update form state must be called here
    };

    // Reset Password Value
    resetPassword = () => {
        passwordForm.controls[Control Name].setValue("");
        // Update Form State Here
    };
    
    // remove Validators
    const removePasswordValidators = () => {
        passwordForm.controls[Control Name].removeValidators([List of Validators]);
        // update form state must be called here
    };
    
    // Set Validators
    const setPasswordValidators = () => {
        passwordForm.controls[Control Name].setValidators([List of Validators]);
        // update form state must be called here
    };
    
    return (
        <form onSubmit={save}>
            <div>
                <input
                    name="password"
                    id="password"
                    placeholder="password"
                    value={loginForm.controls.password.value}
                    onChange={(event: FormEvent<HTMLInputElement>) => changeHandler(event)}
                />

                {
                    passwordForm.controls.password.validity === false &&
                    <span>
                        {
                            passwordForm.controls.password.errors.required &&
                            <span>Password is Required</span>
                        }

                        {
                            passwordForm.controls.password.errors.pattern &&
                            <span>Password pattern error</span>
                        }
                    </span>
                }
            </div>
        </form>
    )
```
# Class Component
``` TSX
    state = {
        passwordForm: new FormGroup({
            password: new FormControl("", [Validators.required(), Validators.pattern(/[0-9]/)])
        })
    };
    
    save = (event: FormEvent<HTMLFormElement>) => {
        event.preventDefault();
        const { passwordForm } = this.state;

        let validate = new BaseValidator(passwordForm);
        validate.analysis()
            .then(controls => {
                let res = validate.result(controls);
                // Update Form State Here

                if (res.form.validity) {
                    console.log(res.payload);
                } else {
                    console.log(res.form)
                }
            });
    };
    
    changeHandler = (event: FormEvent<HTMLInputElement>) => {
        const { passwordForm } = this.state;
        const { name, value } = event.currentTarget;
        loginForm.controls[name].setValue(value);

        // Update Form State Here
    };
    
    resetPassword = () => {
        const { passwordForm } = this.state;
        passwordForm.controls[Control Name].setValue("");
        // Update Form State Here
    };
    
    removePasswordValidators = () => {
        const { loginForm } = this.state;
        passwordForm.controls[Control Name].removeValidators([Validators.min, Validators.max, Validators.required()]);
        // Update Form State Here
    };

    setPasswordValidators = () => {
        const { loginForm } = this.state;
        passwordForm.controls[Control Name].setValidators([Validators.required()]);
        // Update Form State Here
    };
    
    render() {
        const { passwordForm: { controls } } = this.state;
        
        return (
            <form onSubmit={this.save}>
                <h1>Class Form</h1>
                <div>
                    <input
                        name="password"
                        id="password"
                        placeholder="password"
                        value={controls.password.value}
                        onChange={this.changeHandler}
                    />

                    {
                        controls.password.validity === false &&
                        <span>
                            {
                                controls.password.errors.required &&
                                <span>Password is Required</span>
                            }

                            {
                                controls.password.errors.pattern &&
                                <span>Password pattern error</span>
                            }
                        </span>
                    }
                </div>
            )
        }
```

| Name | Description          |
| ------------- | ----------- |
| FormGroup      | to create Form Group containing all Controls |
| FormControl      | to create Form Control containing all Input Methods and roles |
| Validators     | require, min, max, minLength, maxLength, pattern |
| BaseValidators      | analysis, result to return validations  |
| removeValidators      | take list of not needed validators  |
| setValidators      | take list of needed validators  |

## License
MIT
