All Projects β†’ bietkul β†’ React Reactive Form

bietkul / React Reactive Form

Licence: mit
Angular like reactive forms in React.

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to React Reactive Form

React Final Form
🏁 High performance subscription-based form state management for React
Stars: ✭ 6,781 (+2518.15%)
Mutual labels:  asynchronous, subscription, form-validation, forms
Final Form
🏁 Framework agnostic, high performance, subscription-based form state management
Stars: ✭ 2,787 (+976.06%)
Mutual labels:  subscription, observer, form-validation, forms
react-cool-form
😎 πŸ“‹ React hooks for forms state and validation, less code more performant.
Stars: ✭ 246 (-5.02%)
Mutual labels:  asynchronous, forms, form-validation, form-builder
Usetheform
React library for composing declarative forms, manage their state, handling their validation and much more.
Stars: ✭ 40 (-84.56%)
Mutual labels:  form-validation, forms, form-builder
grav-plugin-form
Grav Form Plugin
Stars: ✭ 48 (-81.47%)
Mutual labels:  forms, form-validation, form-builder
formio
Formio, form definition and binding library for Java platform
Stars: ✭ 24 (-90.73%)
Mutual labels:  forms, form-validation, form-builder
Rsformview
A Cocoapods library designed to easily create forms with multiple data entry fields
Stars: ✭ 84 (-67.57%)
Mutual labels:  form-validation, forms, form-builder
Form For
ReactJS forms made easy
Stars: ✭ 118 (-54.44%)
Mutual labels:  form-validation, forms, form-builder
React Hook Form
πŸ“‹ React Hooks for form state management and validation (Web + React Native)
Stars: ✭ 24,831 (+9487.26%)
Mutual labels:  form-validation, forms, form-builder
ng-observe
Angular reactivity streamlined...
Stars: ✭ 65 (-74.9%)
Mutual labels:  subscription, observer, observable
react-declarative
A React form builder which interacts with a JSON endpoint to generate nested 12-column grids with input fields and automatic state management in a declarative style. Endpoint is typed by TypeScript guards (IntelliSense available). This tool is based on material-ui components, so your application will look beautiful on any device...
Stars: ✭ 17 (-93.44%)
Mutual labels:  form-validation, form-builder
vue-use-form
βœ… A Vue.js composition API function to validate forms
Stars: ✭ 97 (-62.55%)
Mutual labels:  forms, form-validation
mutation-observer
A library for idiomatic use of MutationObserver with Angular
Stars: ✭ 32 (-87.64%)
Mutual labels:  observer, observable
django-siteforms
Django reusable app to simplify form construction
Stars: ✭ 15 (-94.21%)
Mutual labels:  forms, form-builder
ember-formly
JavaScript powered forms for Ember
Stars: ✭ 24 (-90.73%)
Mutual labels:  forms, form-builder
form-data-json
A zero dependency, cross browser library to easily get or set/manipulate form input values as/from a json object.
Stars: ✭ 37 (-85.71%)
Mutual labels:  forms, form-validation
view component-form
Rails FormBuilder for ViewComponent
Stars: ✭ 120 (-53.67%)
Mutual labels:  forms, form-builder
Formulary
Declarative iOS TableView Forms in Swift (pre-SwiftUI)
Stars: ✭ 83 (-67.95%)
Mutual labels:  form-validation, form-builder
smart-schema
A Laravel package to enable auto generation of forms
Stars: ✭ 18 (-93.05%)
Mutual labels:  form-validation, form-builder
core
πŸ”₯ Antares Core Implemenation. Most important project layer, this is the heart for your app. ACL, notifiter, console, geoip, areas, utils and many more...
Stars: ✭ 24 (-90.73%)
Mutual labels:  form-validation, form-builder

React Native Game Engine

React Reactive Forms

Build Status Backers on Open Collective Sponsors on Open Collective NPM Version code style: prettier gzip size PRs welcome

It's a library inspired by the Angular's Reactive Forms, which allows to create a tree of form control objects in the component class and bind them with native form control elements.

Features

  • UI independent.
  • Zero dependencies.
  • Nested forms.
  • Subscribers for value & status changes of controls.
  • Provides a set of validators & also supports custom sync & async validators.
  • FormGenerator api to create large forms with less code.
  • Better form management with FormGroup & FormArray apis.
  • Customizable update strategy for better performace with large forms.

Installation

npm install react-reactive-form --save

Basic Example

import React, { Component } from 'react';
import {
    FormBuilder,
    FieldGroup,
    FieldControl,
    Validators,
 } from "react-reactive-form";

const TextInput = ({ handler, touched, hasError, meta }) => (
  <div>
    <input placeholder={`Enter ${meta.label}`} {...handler()}/>
    <span>
        {touched
        && hasError("required")
        && `${meta.label} is required`}
    </span>
  </div>  
)
export default class Login extends Component {
    loginForm = FormBuilder.group({
        username: ["", Validators.required],
        password: ["", Validators.required],
        rememberMe: false
    });
    handleReset=() => {
        this.loginForm.reset();
    }
    handleSubmit=(e) => {
        e.preventDefault();
        console.log("Form values", this.loginForm.value);
    }
    render() {
        return (
              <FieldGroup
                control={this.loginForm}
                render={({ get, invalid }) => (
                  <form onSubmit={this.handleSubmit}>

                    <FieldControl
                      name="username"
                      render={TextInput}
                      meta={{ label: "Username" }}
                    />

                    <FieldControl
                      name="password"
                      render={TextInput}
                      meta={{ label: "Password" }}
                    />

                    <FieldControl
                      name="rememberMe"
                      render={({handler}) => (
                        <div>
                          <input {...handler("checkbox")}/>
                        </div>
                      )}
                    />
                    <button
                      type="button"
                      onClick={this.handleReset}
                    >
                      Reset
                    </button>
                    <button
                      type="submit"
                      disabled={invalid}
                    >
                      Submit
                    </button>
                  </form>
                )}
              />
        );
    }
}

Using FormGenerator

import React, { Component } from 'react';
import {
    Validators,
    FormGenerator
 } from "react-reactive-form";
// Input component
const TextInput = ({ handler, touched, hasError, meta }) => (
  <div>
    <input placeholder={`Enter ${meta.label}`} {...handler()}/>
    <span>
        {touched
        && hasError("required")
        && `${meta.label} is required`}
    </span>
  </div>  
)
// Checkbox component
const CheckBox = ({ handler }) => (
    <div>
      <input {...handler("checkbox")}/>
    </div>
  )
// Field config to configure form
const fieldConfig = {
    controls: {
        username: {
            options: {
                validators: Validators.required
            },
            render: TextInput,
            meta: { label: "Username" }
        },
        password: {
            options: {
                validators: Validators.required
            },
            render: TextInput,
            meta: { label: "Password" }
        },
        rememberMe: {
            render: CheckBox
        },
        $field_0: {
            isStatic: false,
            render: ({ invalid, meta: { handleReset } }) => (
                <div>
                    <button
                      type="button"
                      onClick={handleReset}
                    >
                      Reset
                    </button>
                    <button
                      type="submit"
                      disabled={invalid}
                    >
                      Submit
                    </button>
                </div>
            )
        }
    },
}
export default class Login extends Component {
    handleReset=() => {
        this.loginForm.reset();
    }
    handleSubmit=(e) => {
        e.preventDefault();
        console.log("Form values", this.loginForm.value);
    }
    setForm = (form) => {
        this.loginForm = form;
        this.loginForm.meta = {
            handleReset: this.handleReset
        }
    }
    render() {
        return (
            <form onSubmit={this.handleSubmit}>
                <FormGenerator
                    onMount={this.setForm}
                    fieldConfig={fieldConfig}
                />
            </form>
        );
    }
}

Add Controls Dynamically

You can also create controls without even initializing the group control object with the help of new react form components ( FieldGroup, FieldControl, FieldArray).

import React, { Component } from 'react'
import { FieldGroup, FieldControl, Validators } from 'react-reactive-form'

export default class Login extends Component {
  handleSubmit = (e, value) => {
    console.log('Form values', value)
    e.preventDefault()
  }
  render() {
    return (
      <FieldGroup
        render={({ get, invalid, reset, value }) => (
          <form onSubmit={e => this.handleSubmit(e, value)}>
            <FieldControl
              name="username"
              options={{ validators: Validators.required }}
              render={({ handler, touched, hasError }) => (
                <div>
                  <input {...handler()} />
                  <span>
                    {touched && hasError('required') && 'Username is required'}
                  </span>
                </div>
              )}
            />
            <FieldControl
              name="password"
              options={{ validators: Validators.required }}
              render={({ handler, touched, hasError }) => (
                <div>
                  <input {...handler()} />
                  <span>
                    {touched && hasError('required') && 'Password is required'}
                  </span>
                </div>
              )}
            />
            <FieldControl
              name="rememberMe"
              render={({ handler }) => (
                <div>
                  <input {...handler('checkbox')} />
                </div>
              )}
            />
            <button type="button" onClick={() => reset()}>
              Reset
            </button>
            <button type="submit" disabled={invalid}>
              Submit
            </button>
          </form>
        )}
      />
    )
  }
}

So, it's not mandatory that you need to define your control separately but if you want a better control over your form state then you should do that, if your controls are dynamic then you can also initalize the empty group control and add the controls later. See the example:

import React, { Component } from 'react'
import {
  FormBuilder,
  FieldGroup,
  FieldControl,
  Validators
} from 'react-reactive-form'

export default class Login extends Component {
  // Initialize the empty group control
  loginForm = FormBuilder.group({})

  handleReset = e => {
    this.loginForm.reset()
  }
  handleSubmit = e => {
    console.log('Form values', this.loginForm.value)
    e.preventDefault()
  }
  render() {
    return (
      <FieldGroup
        control={this.loginForm}
        render={({ get, invalid, reset, value }) => (
          <form onSubmit={this.handleSubmit}>
            <FieldControl
              name="username"
              options={{ validators: Validators.required }}
              render={({ handler, touched, hasError }) => (
                <div>
                  <input {...handler()} />
                  <span>
                    {touched && hasError('required') && 'Username is required'}
                  </span>
                </div>
              )}
            />
            <FieldControl
              name="password"
              options={{ validators: Validators.required }}
              render={({ handler, touched, hasError }) => (
                <div>
                  <input {...handler()} />
                  <span>
                    {touched && hasError('required') && 'Password is required'}
                  </span>
                </div>
              )}
            />
            <FieldControl
              name="rememberMe"
              render={({ handler }) => (
                <div>
                  <input {...handler('checkbox')} />
                </div>
              )}
            />
            <button type="button" onClick={this.handleReset}>
              Reset
            </button>
            <button type="submit" disabled={invalid}>
              Submit
            </button>
          </form>
        )}
      />
    )
  }
}

Documentation

Code Sandboxes

Try out react-reactive-forms in these sandbox versions of the Examples.

FAQ

How is it different from other form libraries?

React has many libraries which works on the form logic, but here are some concerns with these:

Code Complexity

If you’re using the redux-form then you should know the pain, for just a two field login form you’d to write the store logic.In RRF you can see that how simple is to deal with simple and complex forms.

And one of the awesome thing is that you can just write your form controls logic anywhere in your application.

Dependencies

Many libraries come with dependencies for e.g redux is required for redux-form, So what If I’m using another state management or not event using any. According to Dan Abramov, form state is inherently ephemeral and local, so tracking it in Redux (or any kind of Flux library) is unnecessary. RRF comes with zero dependency, So it’s totally up to you that how you want to save your form state if needed.

Performance

Now that’s a big problem with almost all libraries when you're dealing with large forms.

How RRF does solve performance issues ?

  • It uses subscription to update the components so rather updating all the fields on every input changes, it only update the particular field for which the state change takes place.
  • RRF has a nice option to define that when(blur, submit or change) to update your form's state by using the updateOn property.

Dynamic Changes

With the help of subscribers it's pretty easy to listen for a particular state changes and modify the controls accordingly.

What are value and status changes subscribers?

RRF uses inbuilt Subject, A Subject is an object with the method next(v).To feed a new value to the Subject,RRF just calls the next(theValue), and it will be multicasted to the Observers registered to listen to the Subject. So basically it provides three subjects for each AbstractControl valueChanges, statusChanges and stateChanges and additional two subjects for FormControl ( onValueChanges, onBlurChanges) You can register an observer to a particular Subject to do some actions whenever some particular changes happen.

Example:

componentDidMount() {
  this.myForm.get(β€œgender”).valueChanges.subscribe((value) => {
    // do something
  })
}

Checkout the Basic usage guide for more details.

How the Field components work?

Field components are subscribed to the state changes of a particular control which means that it’ll re-render the component only when it’s state changes disregarding of other field changes.You can also implement your custom wrappers by using the stateChanges Subject.

How updateOn feature works?

Its an another performance booster in RRF, it just holds the computation needed to be made after every keystroke or value changes until you want to execute.It has three options change(default), blur and submit, you can define all of them at both field and record level.

Is this library compatible with React Native?

Yes, this library works with react-native also, currently it supports react-native TextInput and Switch component.

Note:

If you're using react-native then please add the following line of code in index.js of your project to avoid error in android devices.

import "core-js/es6/symbol";
import "core-js/fn/symbol/iterator";

Let's make React Reactive Forms better! If you're interested in helping, all contributions are welcome and appreciated.

And don't forget to star the repo, I will ensure more frequent updates! Thanks!

Contributors

This project exists thanks to all the people who contribute.

Backers

Thank you to all our backers! πŸ™ [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].