MobX Form State Management with automatic validation

Overview

MobX Light Form

MobX Form State Management with automatic validation

Seperate subjects which manage form data to prevent duplication of data and ensure consistency.
The basic principle of responsibility allocation is to allocate responsibility to objects with information that can perform responsibility, so that the form can take charge of the transformation of data to be sent from the client to the server.

Demo

예시 이미지

🔍️ Features

  • Form update and reset
  • Check form is valid or has some errors
  • To be added

Install

npm

npm install mobx-light-form

yarn

yarn add mobx-light-form

🚀 Quick Start

1-a. Define Form

{ const existingNicknames = [ 'AAA', 'BBB', 'CCC', 'DDD', 'EEE' ]; return new Promise(resolve => { setTimeout(() => { resolve(!existingNicknames.includes(value)); }, 200); }); } }; this.nickname = this.generateField ( { key: 'nickname', label: 'Nickname', value: '', validation: [ // If you want to use asynchronous validation async (v: string) => { const isAvailableNickname = await TestAPI.checkIsAvailable(v); return [isAvailableNickname, 'Your nickname already exists.']; } ] }, true // Prevent initial validation ); makeObservable(this, { name: observable, nickname: observable }); } public toDto() { // Convert data to be sent to the server here. return { personName: this.name.value, nickname: this.nickname.value }; } }">
import { makeObservable, observable } from 'mobx';

import Form, { FieldSource } from 'mobx-light-form';

export default class PersonForm extends Form {
  public name: FieldSource<string>;

  public nickname: FieldSource<string>;

  constructor() {
    super();

    this.name = this.generateField<string>({
      key: 'name', // Required: Should be same as member field
      label: 'Name',
      isRequired: true, // Should not be empty
      value: '', // Default value,
      validation: [
        /^Pewww.*$/, // Can be Regex or
        (v: string) => [ // function - () => [boolean, ErrorMessage | undefined]
          v === 'Pewwwww',
          "Should be 'Pewwwww'"
        ]
      ]
    });

    const TestAPI = {
      checkIsAvailable: (value: string) => {
        const existingNicknames = [
          'AAA',
          'BBB',
          'CCC',
          'DDD',
          'EEE'
        ];

        return new Promise(resolve => {
          setTimeout(() => {
            resolve(!existingNicknames.includes(value));
          }, 200);
        });
      }
    };

    this.nickname = this.generateField<string>(
      {
        key: 'nickname',
        label: 'Nickname',
        value: '',
        validation: [
          // If you want to use asynchronous validation
          async (v: string) => {
            const isAvailableNickname = await TestAPI.checkIsAvailable(v);

            return [isAvailableNickname, 'Your nickname already exists.'];
          }
        ]
      },
      true // Prevent initial validation
    );

    makeObservable(this, {
      name: observable,
      nickname: observable
    });
  }

  public toDto() { // Convert data to be sent to the server here.
    return {
      personName: this.name.value,
      nickname: this.nickname.value
    };
  }
}

1-b. Define Form with array value

Define another form to be an item of array.

import { makeObservable, observable } from 'mobx';

import Form, { FieldSource } from 'mobx-light-form';

export default class BookForm extends Form {
  public name: FieldSource<string>;

  public author: FieldSource<string>;

  constructor() {
    super();

    this.name = this.generateField<string>({
      key: 'name',
      label: 'Book Name',
      value: '',
      isRequired: true
    });

    this.author = this.generateField<string>({
      key: 'author',
      label: 'Author',
      value: ''
    });

    makeObservable(this, {
      name: observable,
      author: observable
    });
  }
}
import { makeObservable, observable, action } from 'mobx';

import Form, { FieldSource } from 'mobx-light-form';

import BookForm from 'src';

export default class PersonForm extends Form {
  // ...other fields
  public favoriteBooks: BookForm[];

  constructor() {
    super();

    this.favoriteBooks = [];

    makeObservable(this, {
      favoriteBooks: observable,
      addBook: action,
      clearBooks: action
    });
  }

  public addBook() { // If you need, override or create form methods.
    this.favoriteBooks.push(new BookForm());
  }

  public clearBooks() {
    this.favoriteBooks = [];
  }
}

2. Register form in store

import PersonForm from 'src';

export default class PersonStore {
  public personForm: PersonForm;

  constructor() {
    this.personForm = new PersonForm();
  }
}

3. Handle Input values

{!!form.errors.name && ( {form.errors.name} )} {!!form.errors.nickname && ( {form.errors.nickname} )} {form.favoriteBooks.map((f) => ( { f.update({ author: value }); }} /> { f.update({ name: value }); }} /> ))} Reset Add Book Clear Books Submit ); }); export default PersonBody;">
// Please see Demo

import React, { useCallback } from 'react';
import { observer } from 'mobx-react';
import debounce from 'lodash.debounce';

import { usePersonStores } from '../stores/PersonProvider';

import { Input, Button } from '../components';

const PersonBody = observer(() => {
  const { personStore } = usePersonStores(); // The way you get mobx store
  const { personForm: form } = personStore;

  const handleChange = useCallback(
    (fieldName: string) => (value: string) => {
      form.update({
        [fieldName]: value
      });
    },
    [form]
  );

  const debouncedValidate = useCallback(debounce(() => {
    form.validate(); // Trigger validation when you need
  }, 500), [form]);

  const handleNicknameChange = useCallback((value: string) => {
    form.update(
      {
        nickname: value
      },
      true // Prevent validation
    );

    debouncedValidate();
  }, [form, debouncedValidate]);

  const handleReset = useCallback(() => {
    form.reset();
  }, [form]);

  const handleBookAdd = useCallback(() => {
    form.addBook();
  }, [form]);

  const handleBooksClear = useCallback(() => {
    form.clearBooks();
  }, [form]);

  const handleSubmit = useCallback(() => {
    console.log('Submit Result: ', form.toDto());
  }, [form]);

  return (
    <Wrapper>
      <Input
        label={form.name.label}
        value={form.name.value}
        placeholder="Write name"
        onChange={handleChange("name")}
      />
      {!!form.errors.name && (
        <ErrorMessage>{form.errors.name}</ErrorMessage>
      )}
      <Input
        label={form.nickname.label}
        value={form.nickname.value}
        placeholder="Write nickname"
        onChange={handleNicknameChange}
      />
      {!!form.errors.nickname && (
        <ErrorMessage>{form.errors.nickname}</ErrorMessage>
      )}
      {form.favoriteBooks.map((f) => (
        <FavoriteBookWrapper key={f.__id}>
          <Input
            placeholder="Write author"
            label={f.author.label}
            value={f.author.value}
            onChange={(value) => {
              f.update({
                author: value
              });
            }}
          />
          <Input
            placeholder="Write book name"
            label={f.name.label}
            value={f.name.value}
            className="book-name"
            onChange={(value) => {
              f.update({
                name: value
              });
            }}
          />
        </FavoriteBookWrapper>
      ))}
      <StyledButton onClick={handleReset}>Reset</StyledButton>
      <StyledButton onClick={handleBookAdd}>Add Book</StyledButton>
      <StyledButton onClick={handleBooksClear}>Clear Books</StyledButton>
      <StyledButton onClick={handleSubmit} disabled={!form.isValid}>
        Submit
      </StyledButton>
    </Wrapper>
  );
});

export default PersonBody;
You might also like...
A complete form validation hook for React

A complete form validation hook for React

Simple form validation library for React and React Native

React Cee Form Inspired by react hook form and their props name and rewritten in a simple way. It can be used for both React Native and ReactJs. Don't

Form Builder powered by native-base & react-hook-form
Form Builder powered by native-base & react-hook-form

native-base-form-builder Form Builder written in typescript with inbuilt Validation, dropdown, autocomplete powered by react-hook-form & native-base.

This Login Form made using React hooks , React Js , Css, Json. This form have 3 inputs, it also validate those inputs & it also having length limitations.

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

React Form Example with usage of React Hook Form, Typescript, zod and i18next

React Form Example with usage of React Hook Form, Typescript, zod and i18next This project was bootstrapped with Create React App. Disclaimer Main goa

Light weight schema Form builder for react-hook-form

React hook form builder Light weight schema Form builder for react-hook-form. This package takes your schema and builds the form based on that using y

Modern Front End Form Management Library for React
Modern Front End Form Management Library for React

Rong Form Rong Form is a modern form management library for React Quick Start Install: yarn add rong-form -S npm i rong-form -S Import : import { Form

Reactive forms for react and react native, using hooks and Mobx@6
Reactive forms for react and react native, using hooks and Mobx@6

Reactive forms for react and react native, using hooks and Mobx@6 Installation: npm install -s react-fluid-form mobx mobx-react yup lodash // or: yarn

Simply create a forms, without having to write state management logic on your own.
Simply create a forms, without having to write state management logic on your own.

Create React forms just with a pure JSX and let the react-standalone-form manage its state for you. A themeable form library based on Context API with a selection of user friendly inputs and wide customization abilities to match your design and functionality.

Comments
  • [Fix]  __identifier, _initialValues fix

    [Fix] __identifier, _initialValues fix

    안녕하세요. 두가지 정도 수정하면 어떨까 싶어서 남겨봅니다.

    1. _initialValues -> initialValues 수정
    • reset() 에서 가져오는 초기값을 _initialValues가 아닌 get initialValues 로 수정하면 어떨까 싶습니다. 기존 코드처럼으로도 참조할 수 있지만, private 한 값인데 get initialValues로 가지고 와야 의미가 맞지 않나 싶어서요.
    1. __identifier에 readonly 식별자 추가
    • __identifierconstructor에서 선언 이후로 수정이 되지 않는데, readonly를 안붙일 이유가 없다고 봅니다. 혹시나 다른 의도가 있으신건지 궁금합니다. ㅎㅎ
    opened by bluelion2 2
  • Fix issues

    Fix issues

    Pull Request

    Related issue (Problems)

    https://github.com/Pewww/mobx-light-form/issues/4 https://github.com/Pewww/mobx-light-form/issues/6 https://github.com/Pewww/mobx-light-form/issues/7

    Description

    1. Modify props to receive a custom message when 'isRequired' option is true.
    2. Add clear method to check validation after initializing the form.
    3. Setting jest and add test codes.
    opened by Pewww 0
  • Support Asynchronous validation

    Support Asynchronous validation

    Pull Request

    Related issue (Problems)

    https://github.com/Pewww/mobx-light-form/issues/2

    Description

    1. Support asynchronous validation.
    2. Add 'validate' public method to trigger validation at a specific point in time.
    opened by Pewww 0
Releases(v1.0.5)
  • v1.0.5(Sep 21, 2022)

    Description

    'untouch': Reset 'touched' property of a particular field to false. 'untouchAll': Reset 'touched' property of all fields to false.

    Source code(tar.gz)
    Source code(zip)
An easy-to-use form validation library for React, as of now it only supports email and required field validation, will be adding other quite soon.

react-use-form-validate Super customizable validation library for forms in react Install npm install --save react-use-form-validate Usage import { use

Himanshu Bhardwaz 2 Jun 30, 2022
React Hook Form Validation example with react-hook-form 7 and Bootstrap 4

React Hook Form Validation example with react-hook-form 7 and Bootstrap 4 Project setup In the project directory, you can run: npm install # or yarn i

JS-IT 4 Mar 17, 2022
React Hook Form: A Form whit some fiels and standard validation on it

React Hook Form: A Form whit some fiels and standard validation on it

null 1 Feb 10, 2022
Simple and performant form library built with MobX

MobX Easy Form Simple and performant form library built with MobX. Works with React, React Native and any other framework that supports MobX. Motivati

Mateo Hrastnik 8 Oct 13, 2022
🏁 High performance subscription-based form state management for React

You build great forms, but do you know HOW users use your forms? Find out with Form Nerd! Professional analytics from the creator of React Final Form.

Final Form 7.2k Jan 8, 2023
A simple react and react native form validator inspired by Laravel validation.

Simple React Validator is exactly as it sounds. We wanted to build a validator for react that had minimal configuration and felt natural to use. It's configuration and usage is similar to the Laravel PHP framework and make validation as easy as one line.

Dockwa 266 Jan 3, 2023
The most compact reactive form controller (including Validation) that you'll ever see.

Svelte Use Form A svelte form library that is easy to use and has no boilerplate. It helps you control and validate forms and their fields and check o

Noah Versace Salvi 176 Jan 2, 2023
Formik-and-Yup-Reactjs - A React Validation form with formik and yup

Signup form with formik Create simple signup form with formik and use yup for th

Jonata Serpa 5 Sep 19, 2022
React hook for handling Laravel form requests and validation (for React & React Native)

React-use-form: React hook for handling form states, requests, and validation, compatible with React and React Native. ✅ Simple and intuitive API ✅ 10

Alfonso Bribiesca 5 Dec 3, 2022
Implementation Angular 13 Form Validation with Submit using Reactive Forms Module and Bootstrap 4.

Implementation Angular 13 Form Validation with Submit using Reactive Forms Module and Bootstrap 4. The form has: Full Name: required Username: require

Meher 1 May 5, 2022