3.6.0 • Published 5 months ago

@traveloka/react-schema-form v3.6.0

Weekly downloads
500
License
MIT
Repository
-
Last release
5 months ago

React Schema

Installation

yarn

yarn add @traveloka/react-schema-form

npm

npm i @traveloka/react-schema-form --save

Motivation

Form is common in any application. The final result of form is data. This library would separate the UI and Form logic by giving basic API to Field Component. The flow how to get the data, would be the responsible of the Field Component.

Getting Started

Basic Usage

// InputField.js

import React from 'react';

export default function InputField({ onChange, value, ...rest }) {
  return (
    <input onChange={(e) => onChange(e.target.value)} value={value} {...rest} />
  );
}
// LoginForm.js

import React from 'react';
import { Form, Field } from '@traveloka/react-schema-form';  // ES6
import InputField from './InputField';

export default class LoginForm extends React.Component {

  form = null;

  render() {
    return (
      <React.Fragment>
        <Form fieldRef={(el) => form = el}>
          <Field name="email" component={InputField} />
          <Field name="password" component={InputField} type="password"/>
        </Form>
        <button onClick={this.handleSubmit}>Submit</button>
      </React.Fragment>
    );
  }

  handleSubmit = () => {
    this.props.onSubmit(this.form.getValues());
  }
}

Documentation

- Field

Importing

var Field = require('@traveloka/react-schema-form').Field;  // ES5

import { Field } from '@traveloka/react-schema-form';  // ES6

Props

PropertyTypeDefault ValueDescription
namestringnonerequired
fieldRefReact.createRefnoneto be able access field methods.
componentReact.ClassComponentnonerequired
revalidateOnErrorbooleantruewill auto validate when have an error
validateOnChangebooleanfalsewill auto validate when value is changes
normalizefunction(value) => valuewill serialize the value
defaultValueanydefault value.
rulesfuncarray of func

Methods

MethodsDescription
getValue() => anyreturn current field value
setValue(newValue: any) => anyset current field value
getError() => ValidationResultreturn current field error message
setError(error: ValidationResult) => ValidationResultset current field error
validate() => ValidationResulttrigger field to validate
reset() => voidreset field to defaultValue, and remove error
initialize(value: any) => anyset field defaultValue
getDefaultValue() => anyget field defaultValue
hasError() => booleanreturn true if field have an error
isDirty() => booleanreturn true if field value is not same with defaultValue

Given Props to Field Component

MethodsDescription
name: Stringthe Field name
label: StringUC Words of name
isDirty: Booleanstate of the changes value of field
error: String | nullfield error
onChange: (v) => anyfunction to change field value
value: anythe value of field

Usage

1. A Component

This can be any component class that you have written or have imported from a third party library.

/// MyCustomInput.js
import React, { Component } from 'react'

class MyCustomInput extends Component {
  static propTypes = {
    value: PropTypes.any,
    onChange: PropTypes.func,
    isDirty: PropTypes.bool,
    error: PropTypes.string,
  }

  render() {
    const { value, onChange } = this.props
    return (
      <div>
        <span>The current value is {value}.</span>
        <button type="button" onClick={() => onChange(value + 1)}>Inc</button>
        <button type="button" onClick={() => onChange(value - 1)}>Dec</button>
      </div>
    )
  }
}

Then, somewhere in your form...

import MyCustomInput from './MyCustomInput'
...
<Field name="myField" component={MyCustomInput}/>
2. Validation

Field accept rules as props. Rules can be a function / array of function. Each function accept one arguments, the value. The function just need to return null / string. The return value would be the error message for the field component (eg: if there's no error, return null).

// MyErrorableInput.js

import React from 'react';

export default function MyErrorableInput({ value, onChange, error, ...rest }) {
  return (
    <div>
      <input value={value} onChange={(e) => onChange(e.target.value)} {...rest} />
      {!!error && <div className="error">{error}</div>}
    </div>
  );
}

For rule functions

// isEmail.js
export default function isEmail(value) {
  return value.contains('@') ? null : `${value} is not an email format.`;
}

// maxLength.js
const maxLength = (length) => (value) => {
  return value && value.length <= length ? null : `Length must not exceed ${length} chars.`;
}

Then somewhere in your form...

import isEmail from './isEmail';
import maxLength from './maxLength';
import MyErrorableInput from './MyErrorableInput';

<Field name="email" component={MyCustomInput} rules={[isEmail, maxLength(10)]}>

- Form

Props

PropertyTypeDefault ValueDescription
arraybooleanfalsewould return the values as array
normalizefunction(val) => vala function that normalize the form values
fieldRefReact.createRefnoneto be able access field methods.

Methods

MethodsDescription
getValue() => ValueByFieldNamereturn form value by fieldName
setValue(newValue: ValueByFieldName) => ValueByFieldNameset form value by fieldName
getError() => ValidationResultByFieldNamereturn form error message by fieldName
setError(error: ValidationResultByFieldName) => ValidationResultByFieldNameset form error by fieldName
validate() => ValidationResultByFieldNametrigger form to validate
reset() => voidreset form to defaultValue, and remove error
initialize(value: ValueByFieldName) => anyset form defaultValue by fieldName
getDefaultValue() => ValueByFieldNameget defaultValue by fieldName
hasError() => booleanreturn true if some field have an error
hasErrorField(fieldName: string) => booleanreturn true if field have an error
isDirty() => booleanreturn true if some field value is not same with defaultValue
isDirtyField(fieldName: string) => booleanreturn true if field value is not same with field defaultValue
getValueField(fieldName: string) => anyreturn field value
setValueField(fieldName: string, value: any) => anyset field value
getErrorField(fieldName: string) => ValidationResultreturn field error message
setErrorField(fieldName: string, error: ValidationResult) => ValidationResultset field error message
validateField(fieldName: string) => ValidationResultvalidate specify field

Children Function Params

PropertyTypeDescription
valuesname: string: anyform value by fieldName
isDirtybooleantrue if some field value is not same with defaultValue
hasErrorbooleantrue if some field have an error
errorname: string: ValidationResultform error message by fieldName

Nested Forms

You could also build a nested form like this

<Form fieldRef={form => this.form = form}>
  <div>
    <Field name="email" component={InputField} />
    <Form name="profile">
      <Field name="first" component={InputField} />
      <Field name="last" component={InputField} />
    </Form>
  </div>
</Form>

// when you get value
this.form.getValue()
{
  email: ...,
  profile: {
    first: ...,
    last: ...
  }
}

Playground

  • Example 1 Edit [@traveloka/react-schema-form] #1
  • Example 2 Edit [@traveloka/react-schema-form] #2
3.6.0

5 months ago

3.5.1

5 months ago

3.5.0

5 months ago

3.4.6

2 years ago

3.4.5

2 years ago

3.4.5-alpha.0

3 years ago

3.4.4

4 years ago

3.4.3

5 years ago

3.4.2

5 years ago

3.4.1

5 years ago

3.4.0

5 years ago

3.3.8

5 years ago

3.3.7

5 years ago

3.3.6

5 years ago

3.3.5

5 years ago

3.3.4

5 years ago

3.3.3

5 years ago

3.3.2

5 years ago

3.3.1

5 years ago

3.3.0

5 years ago

3.2.3

5 years ago

3.2.2

5 years ago

3.2.1

5 years ago

3.2.0

5 years ago

3.1.11

5 years ago

3.1.10

5 years ago

3.1.9

5 years ago

3.1.8

5 years ago

3.1.7

5 years ago

3.1.6

5 years ago

3.1.5

5 years ago

3.1.4

5 years ago

3.1.3

6 years ago

3.1.2

6 years ago

3.1.1

6 years ago

3.1.0

6 years ago

3.0.0

6 years ago

2.0.1

6 years ago

2.0.0

6 years ago

1.0.7

6 years ago

1.0.6

6 years ago

1.0.5

6 years ago

1.0.4

6 years ago

1.0.3

6 years ago

1.0.2

6 years ago

1.0.1

6 years ago