0.2.7 • Published 2 years ago

@aderbalnunes/react-jsonform v0.2.7

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

jsonform

Create material design form from a JSON object

NPM JavaScript Style Guide

Dev Dependencies

Install

$ npm i --save @aderbalnunes/react-jsonform

Basic Usage

import React, { Component } from 'react'

import JsonForm from 'jsonform'

const formFields = {
  'name': {
    component: 'text',
    props: {
      label: 'Name',
      required: true
    }
  },
  'email': {
    component: 'text',
    props: {
      label: 'Email',
      required: true
    }    
  }
}

class MyClass extends Component {
  render() {
    return (
      <JsonForm 
        components={formFields}
        onSave={(data) => console.log(data)}
      />
    )
  }
}

Popule form with remote data

const formFields = {
  'user_name': {
    component: 'text',
    props: {
      label: 'Name',
      required: true
    }
  },
  'user_type': {
    component: 'select',
    props: {
      label: 'User Type',
      options: () => new Promise(resolve => {
        fetch('<rest api endpoint>')
          .then(res => res.json())
          .then(json => resolve(json.map(r => ({label: r.type, value: r.id}))
          .catch(resolve([]);
      })
    }
  }
}

// assume that the endpoint API returns something like: 
// { result: {user_id: 321, user_type: 123, user_name: 'Foo'} }
const fetchRemoteData = user => new Promise(resolve => {
  fetch(`<url endpoint>/${user}`)
    .then(res => res.json())
    .then(json => resolve({data: json.result}))
    .catch(() => resolve({}))
});

class MyClass extends Component {
  render() {
    return (
      <JsonForm 
        components={formFields}
        fetchData={fetchRemoteData}
        fetchParams={[321,]}
        onSave={(data) => console.log(data)}
        formChange={(data) => console.log(data)}
      />
    )
  }
}

Split form into columns

Splited columns

const formFields = [{
  'user_name': {
    component: 'text',
    props: {
      label: 'Name',
      required: true
    }
  },
  'user_email': {
    component: 'text',
    props: {
      label: 'E-mail',
      required: true
    }
  },
}, {
  'user_password': {
    component: 'text',
    props: {
      label: 'Password',
      required: true,
      type: 'password'
    }
  },
  'user_repassword': {
    component: 'text',
    props: {
      label: 'Password',
      required: true,
      type: 'password'
    }
  }   
}]

Custom components

const MyComponent = ({...props}) => {
  const {id,value,onChange} = props;

  const _increment = () => {
    if(typeof onChange === 'function'){
      onChange({target: {name: id, value: value + 1}})
    }
  }

  return (
    <Button onClick={_increment}>Increment {value}</Button>
  )
}

const formFields = {
  'my_component': {
    component: MyComponent,
    props: { value: 1 }
  },
}

Elements

  • Text input

    props required: label

'phone_number': {
  component: 'text',
  props: {
    label: 'Phone',
    required: true,
    value: "(123) 456 7899",
    validation: /\(?([0-9]{3})\)?([ .-]?)([0-9]{3})\2([0-9]{4})/,
    onKeyPress: (ev) => {  }
  }
}
  • Input Select

    props required: label and options

// fixed values
'user_level': {
  component: 'select',
  props: {
    label: 'User Level',
    required: true,
    options: [
      {value: 1, label: 'Admin'},
      {value: 2, label: 'Default'},
    ]
  }
}
// fetch remote data options
// assume that the endpoint API returns something like: [{id: 123, label: 'Foo'},...]
'user_status': {
  component: 'select',
  props: {
    label: 'User Status',
    options: () => new Promise(resolve => {
      fetch('<rest api endpoint>')
        .then(res => res.json())
        .then(json => resolve(json.map(r => ({label: r.label, value: r.id}))
        .catch(resolve([]);
    })
  }
}
// dependency
// fetch remote data based on value selected in other select
'user_profile': {
  component: 'select',
  props: {
    label: 'User Profile',
    depends: 'user_level',
    options: level => new Promise(resolve => {
      fetch(`<rest api endpoint>/${level}`)
        .then(res => res.json())
        .then(json => resolve(json.map(r => ({label: r.profile, value: r.id}))
        .catch(resolve([]);
    })
  }
}
  • Multiselect

    props required: label and options

// fixed values
'user_rights': {
  component: 'multiselect',
  props: {
    label: 'User Rights',
    required: true,
    options: [
      {value: 1, label: 'delete'},
      {value: 2, label: 'update'},
      {value: 3, label: 'insert'},
    ]
  }
}
// fetch remote data options
'user_rights': {
  component: 'multiselect',
  props: {
    label: 'User Rights',
    options: () => new Promise(resolve => {
      fetch('<rest api endpoint>')
        .then(res => res.json())
        .then(json => resolve(json.map(r => ({label: r.label, value: r.id}))
        .catch(resolve([]);
    })
  }
}
  • Radio Group
'user_gender': {
  component: 'radiogroup',
  props: {
    label: 'User Gender',
    value: 'male'
    options: [
      {value: 'male',   label: 'Male'},
      {value: 'female', label: 'Female'},
      {value: 'unknow', label: 'Unknow'}
    ]
  }
}
// fetch remote data options
'user_gender': {
  component: 'radiogroup',
  props: {
    label: 'User Gender',
    value: 'male'
    options: () => new Promise(resolve => {
      fetch('<rest api endpoint>')
        .then(res => res.json())
        .then(json => resolve(json.map(r => ({label: r.label, value: r.id}))
        .catch(resolve([]);
    })
  }
}
  • Switch

    props required: label

  'user_is_master': {
    component: 'switch',
    props: {
      label: 'Master user',
      value: true,
      value_type: 'bool'
    }
  }
  • File upload

    props required: label

  'file_upload': {
    component: 'upload',
    props: {
      label: 'File Upload',
      info: 'CSV or XML file'
    }
  }

Options

Controls

<JsonForm 
  components={formFields} 
  controlOptions={{
    saveText: 'Save Form',
    cancelText: 'Cancel'
  }}
  onSave={(data) => console.log(data)}
/>

Skip a property in the model

const formFields = {
  'name': {
    component: 'text',
    props: {
      label: 'Name',
      required: true
    }
  },
  'email': {
    component: 'text',
    props: {
      label: 'Email',
      required: true
    }    
  },
  'info': {
    component: 'info',
    props: {
      text: 'Tip: Use a non commercial email.'
    },
    options: {
      skipFromModel: true
    }    
  }  
}

Popule with a model

const MyModel = {
  user_name: 'Tom',
  user_email: 'tom@email.com',
  user_gener: 'male'
}

<JsonForm 
  components={formFields} 
  model={MyModel}
  onSave={(data) => console.log(data)}
/>

License

MIT © Aderbal Nunes

0.2.5-beta.1

2 years ago

0.2.8-beta.1

2 years ago

0.2.8-beta.2

2 years ago

0.2.5-beta.2

2 years ago

0.2.7

2 years ago

0.2.6

2 years ago

0.2.5

2 years ago

0.2.3

3 years ago

0.2.4

3 years ago

0.2.2

3 years ago

0.2.1

3 years ago

0.2.0

3 years ago

0.1.9

3 years ago

0.1.9-6-beta

3 years ago

0.1.9-beta

3 years ago

0.1.9-4-beta

3 years ago

0.1.9-5-beta

3 years ago

0.1.8

3 years ago

0.1.7

3 years ago

0.1.6

3 years ago

0.1.4

3 years ago

0.1.3

3 years ago

0.1.2

3 years ago