Skip to content

aexol-studio/react-nested-form

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

"100% bad....never use nested forms" - Harry Joy, stackoverflow.com May 11 '11 at 4:34

"A kitten dies every time you use nested forms" - Ibu, stackoverflow.com May 11 '11 at 5:12

Yes, that's how

<form action="killmeplease">
    <input name="now" type="text" />
</form>

html component work. This is why I think we need a new forms standard for react library.

<form action="you">
    <form action="can't">
        <form action="do">
            <form action="that">
            </form>
        </form>
    </form>
</form>

Welcome

nested-form

Installation

$ npm add nested-form

Library created to enable nested forms inside of your project. Every component is 100% Modular composed of replacable, extendable Components of form. You can replace or extend every component with your style or your new react component. You can write validate functions for every field, form and nested form. You can use validation on edit.

import * as React from 'react'
import { Form } from 'nested-form'

const YourComponent = () => (
    <div>
        <h1>I am a form</h1>
        <Form
            fields={[
                {
                    name: 'important',
                    fieldType: 'string',
                    validate: (e) => e === "password"
                    content: {
                        placeholder:'Important...',
                    },
                    required: true
                },
                {
                    name: 'data',
                    fieldType: 'select',
                    content:{
                        multi: true,
                        placeholder:'Data...',
                        options:[
                            {
                                label:'very data 1',
                                value:1
                            },
                            {
                                label:'very data 2',
                                value:2
                            }
                        ]
                    }
                },
                {
                    name:'iCanDoThat',
                    fieldType: 'nest',
                    content:{
                        fields:[
                            {
                                name:'IAmNested',
                                fieldType:'string',
                            }
                        ]
                    }
                },
                {
                    name:'nestArrayIsUseful',
                    fieldType: 'nestArray',
                    content:{
                        fields:[
                            {
                                name:'forAddableObjects',
                                fieldType:'string',
                            }
                        ]
                    }
                }
            ]}
            validate={e => {
                // This will only fire when 1 field is filled with 'password'
                fetch(`https://send-data-somewhere.com/?data=${JSON.stringify(e)}`)
            }}
        />
    </div>
)

Wrapper

It is also possible to replace form field Wrapper that wraps every field

import * as React from 'react'
import { Form } from 'nested-form'

const YourComponent = () => (
    <div>
        <h1>I am a form</h1>
        <Form
            fields={[
                {
                    name: 'important',
                    fieldType: 'string',
                    content: {
                        placeholder:'Important...',
                    },
                    required: true,
                    Component
                }
            ]}
            AlternativeWrapper={({children,field,error})=> (
                <div className="Wrap">
                    <div className="Label">{field.content.placeholder || field.name}</div>
                    <div className="Field">{children}</div>
                    {error && <div className="Errors">{error}</div>}
                </div>
            )}
            validate={e => {
                // This will only fire when 1 field is filled with 'password'
                fetch(`https://send-data-somewhere.com/?data=${JSON.stringify(e)}`)
            }}
        />
    </div>
)

Component Replace

import * as React from 'react';
import { Form, Input, FieldDefinition } from 'nested-form';

export const CustomInput: typeof Input = (props: FieldDefinition<'string'>) => (
  <input
    type="text"
    value={props.value}
    onChange={(e) => {
      props.onChange(e.target.value);
    }}
    style={{
      padding:20
    }}
  />
);

const YourComponent = () => (
    <div>
        <h1>I am a form</h1>
        <Form
            fields={[
                {
                    name: 'important',
                    fieldType: 'string',
                    content: {
                        placeholder:'Important...',
                    },
                    required: true,
                    Component: CustomInput
                }
            ]}
            validate={e => {
                // This will only fire when 1 field is filled with 'password'
                fetch(`https://send-data-somewhere.com/?data=${JSON.stringify(e)}`)
            }}
        />
    </div>
)

Submit button

import * as React from 'react';
import { Form, Input, FieldDefinition, SubmitComponent } from 'nested-form';


export const CustomSubmit: typeof SubmitComponent = ({ submitText, onClick }) => (
  <div onClick={onClick}>{submitText}</div>
);
const YourComponent = () => (
    <div>
        <h1>I am a form</h1>
        <Form
            fields={[
                {
                    name: 'important',
                    fieldType: 'string',
                    content: {
                        placeholder:'Important...',
                    },
                    required: true,
                }
            ]}
            Submit={CustomSubmit}
            validate={e => {
                // This will only fire when 1 field is filled with 'password'
                fetch(`https://send-data-somewhere.com/?data=${JSON.stringify(e)}`)
            }}
        />
    </div>
)

Component Styling

(Typestyle)[https://github.com/typestyle/typestyle] is a great styling library for React and typescript and was used to write this lib. You have to use it if you want to extend styles of components. If you want to keep, overwrite or replace them, you are fine with any css library.

Replacing a style

import * as React from 'react';
import { Form, Input, FieldDefinition, SubmitComponent,styles } from 'nested-form';
import { style } from "typestyle";

export const BigInput: typeof styles.Input = {
  Input: style({
    padding:30,
    fontSize:20
  })
}

const YourComponent = () => (
    <div>
        <h1>I am a form</h1>
        <Form
            fields={[
                {
                    name: 'important',
                    fieldType: 'string',
                    content: {
                        placeholder:'Important...',
                        styles:BigInput
                    },
                    required: true,
                }
            ]}
            Submit={CustomSubmit}
            validate={e => {
                // This will only fire when 1 field is filled with 'password'
                fetch(`https://send-data-somewhere.com/?data=${JSON.stringify(e)}`)
            }}
        />
    </div>
)

Extending style

import * as React from 'react';
import { Form, Input, FieldDefinition, SubmitComponent,styles } from 'nested-form';
import { style, classes } from "typestyle";

export const RedAutoSuggest: typeof styles.Autosuggest = {
  ...styles.Autosuggest,
  datalistSuggest: classes(
    styles.Autosuggest.datalistSuggest,
    style({
      background: 'red'
    })
  )
};

const myList = ['Cat', 'Caturday', 'KeyboardCat', 'Dog', 'Crocodile', 'Doge']

class YourComponent extends React.Component<{},{
    list: string[]
}> {
    state={
        list:[]
    }
    render(){
        return (
            <div>
                <h1>I am a form</h1>
                <Form
                    fields={[
                        {
                            fieldType: 'autosuggest',
                            name:'suggestions',
                            content:{
                                list:this.state.list,
                                load:(e) => {
                                    // It receives user input and match suggestions from list
                                    this.setState({
                                        list: myList.filter( element => element.match(e) )
                                    })
                                },
                                styles: RedAutoSuggest
                            }
                        }
                    ]}
                    Submit={CustomSubmit}
                    validate={e => {
                        // This will only fire when 1 field is filled with 'password'
                        fetch(`https://send-data-somewhere.com/?data=${JSON.stringify(e)}`)
                    }}
                />
            </div>
        )
    }
}

Autocomplete

This library is written in typescript so everybody will be 100% autocompleted.

About

Nested form in react with typescript

Resources

Stars

Watchers

Forks

Packages

No packages published