# React Form Builder

[Original Dev](https://github.com/kiho/react-form-builder) And there's an original original before him as well. 

A form builder for React that allows you to create forms with drag and drop functionality.


## Features

- Drag and drop form elements
- Custom form elements
- Form validation
- Form data export
- Form data import
- Form preview
- Form builder
- Form elements:
  - Text Input
  - Text Area
  - Dropdown
  - Checkboxes
  - Radio Buttons
  - Date Picker
  - Signature
  - Rating
  - Image
  - File Upload
  - Camera
  - Range
  - Tags
  - HyperLink
  - Download
  - Layout
  - Header
  - Paragraph
  - Label
  - Line Break

## Installation

```bash
npm install sprint-digital-react-form-builder
```

## Usage

```jsx
import { ReactFormBuilder } from 'sprint-digital-react-form-builder';
import 'sprint-digital-react-form-builder/dist/app.css';

function App() {
  return <ReactFormBuilder />;
}
```

## Props

| Prop | Type | Description |
|------|------|-------------|
| onPost | function | Callback function when form is submitted |
| onLoad | function | Callback function when form is loaded |
| url | string | URL to load form data from |
| saveUrl | string | URL to save form data to |
| saveAlways | boolean | Whether to save form data on every change |
| editMode | boolean | Whether to enable edit mode |
| editElement | object | Element being edited |
| className | string | CSS class name |
| renderEditForm | function | Function to render edit form |

## Examples

- [Basic](https://github.com/sprint-digital/react-form-builder/tree/master/examples/demo)
- [JSON Post](https://github.com/sprint-digital/react-form-builder/tree/master/examples/custom)
- [UMD](https://github.com/sprint-digital/react-form-builder/tree/master/examples/umd)
- [NEXT](https://github.com/sprint-digital/react-form-builder/tree/master/examples/next)
- [NEXT-Mongo](https://github.com/sprint-digital/react-form-builder/tree/master/examples/mongo)
- [create-react-app](https://github.com/sprint-digital/react-form-builder/tree/master/examples/cra)

## Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

![](screenshot.png)

### Editing Items
![](screenshot2.png)

# Basic Usage

```javascript
import React from 'react';
import ReactDOM from 'react-dom';
import { ReactFormBuilder } from 'react-form-builder2';
import 'react-form-builder2/dist/app.css';

ReactDOM.render(
  <ReactFormBuilder />,
  document.body
)
```

# Props

```javascript
var items = [{
  key: 'Header',
  name: 'Header Text',
  icon: 'fa fa-header',
  static: true,
  content: 'Placeholder Text...'
},
{
  key: 'Paragraph',
  name: 'Paragraph',
  static: true,
  icon: 'fa fa-paragraph',
  content: 'Placeholder Text...'
}];

<ReactFormBuilder
  url='path/to/GET/initial.json'
  toolbarItems={items}
  saveUrl='path/to/POST/built/form.json' />
```

# React Form Generator
Now that a form is built and saved, let's generate it from the saved json.

```javascript
import React from 'react';
import ReactDOM from 'react-dom';
import { ReactFormGenerator } from 'react-form-builder2';
import 'react-form-builder2/dist/app.css';

ReactDOM.render(
  <ReactFormGenerator
    form_action="/path/to/form/submit"
    form_method="POST"
    task_id={12} // Used to submit a hidden variable with the id to the form from the database.
    answer_data={JSON_ANSWERS} // Answer data, only used if loading a pre-existing form with values.
    authenticity_token={AUTH_TOKEN} // If using Rails and need an auth token to submit form.
    data={JSON_QUESTION_DATA} // Question data
  />,
  document.body
)
```

### Form Params

Name | Type | Required? | Description
--- | --- | --- | ---
form_action | string | Required | URL path to submit the form
form_method | string | Required | Verb used in the form submission.
action_name | string | Optional | Defines form submit button text.  Defaults to "Submit"
onSubmit | function | optional | Invoke when submit data, if exists will override form post.
onChange | function | optional | Invoke when Change data. only on generator
onBlur | function | optional | Invoke when Blur data. only on generator
data | array | Required | Question data retrieved from the database
back_action | string | Optional | URL path to go back if needed.
back_name | string | Optional | Button text for back action.  Defaults to "Cancel".
task_id | integer | Optional | User to submit a hidden variable with id to the form on the backend database.
answer_data | array | Optional | Answer data, only used if loading a pre-existing form with values.
authenticity_token | string | Optional | If using Rails and need an auth token to submit form.
hide_actions | boolean | Optional | If you would like to hide the submit / cancel buttons set to true.
skip_validations | boolean | Optional | Suppress form validations on submit, if set to true.
display_short | boolean | Optional | Display an optional "shorter page/form" which is common for legal documents or situations where the user will just have to sign or fill out a shorter form with only the critical elements.
read_only | boolean | Optional | Shows a read only version which has fields disabled and removes "required" labels.
variables | object | Optional | Key/value object that can be used for Signature variable replacement.
option_key_value | string | Optional | Use "key" or "value" of checked option item in json data, default is "key".

### Read only Signatures

Read only signatures allow you to use a saved/canned signature to be placed into the form. The signature will be passed in through the `variables` property to `ReactFormGenerator` and `ReactFormBuilder`.

To use a read only signature, choose the "Read only" option and enter the key value of the variable that will be used to pass in the signature.

![](screenshot3.png)

The signature data should be in base 64 format.

There is a `variables.js` file that contains a sample base 64 signature. This variable is passed into the demo builder and generator for testing. Use the variable key "JOHN" to test the variable replacement.

# Vendor Dependencies
In order to make the form builder look pretty, there are a few dependencies other than React. Style sheets from `Bootstrap` and `FontAwesome` must be added to index.html. See the example code in [index.html](https://github.com/Kiho/react-form-builder/blob/master/public/index.html#L5) for more details.

- Bootstrap
- FontAwesome

# SASS
All relevant styles located in css/application.css.scss.

# Develop
```bash
$ yarn install
$ yarn run build:dist
$ yarn run serve:api
$ yarn start
```
Then navigate to http://localhost:8080/ in your browser and you should be able to see the form builder in action.

# Customizations
- to customize the field edit form copy "src/form-elements-edit.jsx" to your project and pass it to the ReactFormBuilder as a prop. Here is an example
```jsx
<ReactFormBuilder
    edit
    data={form}
    //toolbarItems={items}
    customToolbarItems={items}
    onChange={handleUpdate}
    onSubmit={handleSubmit}

    renderEditForm={props => <FormElementsEdit {...props}/>}
/>
```

- to customize the ReactFormGenerator submit button use it like this

```jsx
<ReactFormGenerator
    data={form}
    toolbarItems={items}
    onSubmit={handleSubmit}
    actionName="Set this to change the default submit button text"
    submitButton={<button type="submit" className="btn btn-primary">Submit</button>}
    backButton={<a href="/" className="btn btn-default btn-cancel btn-big">Back</a>}
/>
```

# Custom Components
- Import component registry from react-form-builder2
```jsx
import { ReactFormBuilder, ElementStore, Registry } from 'react-form-builder2';
```

- Simple Custom Component 
```jsx
const TestComponent = () => <h2>Hello</h2>;
```

- Custom Component with input element
```jsx
const MyInput = React.forwardRef((props, ref) => {
  const { name, defaultValue, disabled } = props;
  return <input ref={ref} name={name} defaultValue={defaultValue} disabled={disabled} />;
});
```

- Register custom components to be used in form builder
```jsx
Registry.register('MyInput', MyInput);
Registry.register('TestComponent', TestComponent);
```

- Define Custom Components in Toolbar
```jsx
const items = [{
  key: 'TestComponent',
  element: 'CustomElement',
  component: TestComponent,
  type: 'custom',
  field_name: 'test_component',
  name: 'Something You Want',
  icon: 'fa fa-cog',
  static: true,
  props: { test: 'test_comp' },
  label: 'Label Test',
}, {
  key: 'MyInput',
  element: 'CustomElement',
  component: MyInput,
  type: 'custom',
  forwardRef: true,
  field_name: 'my_input_',
  name: 'My Input',
  icon: 'fa fa-cog',
  props: { test: 'test_input' },
  label: 'Label Input',
}, 
// Additional standard components, you don't need full definition if no modification is required. 
{  
  key: 'Header',
}, {
  key: 'TextInput',
}, {
  key: 'TextArea',
}, {
  key: 'RadioButtons',
}, {
  key: 'Checkboxes',
}, {
  key: 'Image',
}];
```

- Use defined Toolbar in ReactFormBuilder
```jsx
  <ReactFormBuilder
    ...
    toolbarItems={items}
  />
```
       
- Find working example [here](https://github.com/Kiho/react-form-builder/blob/master/examples/custom/app.js)


# Tests
```bash
$ npm test
```
Test is not working at this moment.
