react-native-dynamic-form
![Licence](https://img.shields.io/npm/l/react-native-dynamic-form.svg)
Dynamic form builder for React Native
Sneak Peak
![](https://user-images.githubusercontent.com/16062709/40332552-47eb7776-5d4c-11e8-924d-34044580c671.gif)
Installation
$ npm install react-native-dynamic-form --save
or use yarn
$ yarn add react-native-dynamic-form
Usage
Note: Ensure to add and configure react-native-vector-icons in your project before using this package.
You can clone and try out the sample app.
Sample usage:
import React, { Component } from 'react';
import {
StyleSheet,
View
} from 'react-native';
import DynamicForm from 'react-native-dynamic-form';
const form = [
{
key: 'hdghhdbdfgh',
type: 'header',
subtype: 'h1',
label: 'Dynamic Form',
},
];
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<DynamicForm
form={form}
style={styles.formContainer}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
formContainer: {
marginTop: 10,
},
});
Props
The component takes one compulsory prop - form
. Other props are optional. The table below explains more.
Prop | Required | Type | Purpose |
---|
form | Yes | Array | array of objects representing form components to render (see Form Components for more info) |
theme | No | Object | Theme to apply to entire dynamic form elements. See below for more info |
style | No | Object, Number | Style to apply to form container. View Style |
onFormDataChange | No | Function | Returns form responses as funtion argument whenever any change occur in form |
submitButton | No | Object | Object for displaying button at the end of form. More info below |
submitButton (prop)
Object for displaying button at the end of form. Holds configuration on button appeareance and beahaviour. See below for sample:
import React, { Component } from 'react';
import { View } from 'react-native';
import DynamicForm, { buildTheme } from 'react-native-dynamic-form';
const theme = buildTheme();
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<DynamicForm
form={form}
theme={theme} // theme prop is optional and default theme is applied if theme is not provided
submitButton={{
action: (responses) => {
console.log('Submit Button Responses: ', responses);
}, // button action, takes form responses as argument, optional
label: 'Submit', // button label, required
buttonStyle: {
backgroundColor: '#CCCCCC',
borderRadius: 3,
height: 40,
}, // View PropTypes, optional
buttonTextStyle: {
fontSiz3: 18,
}, // Text PropTypes, optional
disabled: false, // boolean to disable button, optional
}}
/>
</View>
);
}
}
_getFormResponses
Use component reference to get form responses at any point in time
import React, { Component } from 'react';
import { View, Button } from 'react-native';
import DynamicForm, { buildTheme } from 'react-native-dynamic-form';
export default class App extends Component {
getFormResponses = () => {
const responses = this.formRef._getFormResponses();
}
render() {
return (
<View style={styles.container}>
<DynamicForm
ref={ref => this.formRef = ref}
form={form}
/>
<Button
onPress={this.getFormResponses}
title="Get Form Responses"
/>
</View>
);
}
}
Theming
A global theme object can be passed to the Dynamic Form
component which gets applied to most of the form elements. Theming is still a work in progress and far from perfect, but it provides a basic way of customizing form elements. Theming instructions are provided below:
import React, { Component } from 'react';
import { View } from 'react-native';
import { buildTheme } from 'react-native-dynamic-form';
const theme = buildTheme();
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<DynamicForm
form={form}
theme={theme} // theme prop is optional and default theme is applied if theme is not provided
/>
</View>
);
}
}
The code sample above builds a theme template and apply defaults configuration. This file conatins the default values. The defaultTheme
export in the styles config can be used as a template to build really customized theme object.
Full customization
To fully customize form elements, the buildTheme
export accepts three parameters in the order they appear below:
-
userColors - Object of colors to apply to form element. See file for exact format.
-
userFonts - Object of fonts to apply to form element. See file for exact format.
-
userTheme - Complete user theme object which is a clone of defaultTheme
export in styles config file. This can be copied over and modified.
Below is an example of a fully customized theme builder
import { buildTheme } from 'react-native-dynamic-form';
const myColors = {
primary: '#00a5ff',
textPrimary: '#2A3C53',
primaryDark: '#0077cb',
error: '#FF6565',
iconDark: 'rgba(0,0,0,0.4)',
textInputBorderColor: '#cac8c8',
placeholderTextColor: '#A9A9A9',
starFillColor: '#f5a623',
black: '#000000',
white: '#FFFFFF',
success: '#50e3c2',
};
const myFonts = {
defaultFontFamily: 'Roboto',
};
const myTheme = {
label: {
marginTop: 10,
fontSize: 14,
color: myColors.textPrimary,
},
error: {
fontSize: 12,
color: myColors.error,
},
headers: {
h1: {
fontSize: 24,
color: myColors.textPrimary,
fontFamily: myFonts.defaultFontFamily,
},
h2: {
fontSize: 20,
color: myColors.textPrimary,
fontFamily: myFonts.defaultFontFamily,
},
h3: {
fontSize: 16,
color: myColors.textPrimary,
fontFamily: myFonts.defaultFontFamily,
},
},
p: {
fontSize: 16,
color: myColors.textPrimary,
fontFamily: myFonts.defaultFontFamily,
},
input: {
placeholderTextColor,
iconColor: iconDark,
style: {},
},
rating: {
starFillColor,
remarkStyle: {
color: myColors.starFillColor,
fontSize: 14,
},
},
toggle: {
knobColor: myColors.primaryDark,
tintColor: myColors.primary,
},
select: {
tagRemoveIconColor: myColors.error,
tagBorderColor: myColors.textInputBorderColor,
tagTextColor: myColors.primary,
selectedItemTextColor: myColors.primary,
selectedItemIconColor: myColors.primary,
itemTextColor: myColors.textPrimary,
submitButtonColor: myColors.success,
},
};
const theme = buildTheme(myColors, myFonts, myTheme);
const theme = buildTheme(myColors);
Form Components
All component fields are required, except stated otherwise.
Represents a header component.
![](https://user-images.githubusercontent.com/16062709/40320434-a6c79a32-5d23-11e8-8c94-a279d3556509.png)
{
key: 'hdghhdbdfgh',
type: 'header',
subtype: 'h2',
label: 'Dynamic Form',
style: {
fontSize: 14,
},
}
Paragraph
Represents a paragraph component.
![](https://user-images.githubusercontent.com/16062709/40320297-18a7c876-5d23-11e8-8d18-08620bc7d626.png)
{
key: 'addsdfdvdvdd',
type: 'paragraph',
label: 'Instructions on how to fill dynamic form',
style: {
fontSize: 15,
},
}
TextInput
Represents an input component.
![](https://user-images.githubusercontent.com/16062709/40321118-f04db27a-5d25-11e8-9872-3f46e6ecd825.png)
{
key: 'manshgdsuudfg',
type: "text",
required: true,
label: 'What is your last name?',
placeholder: 'Last Name',
subtype: 'text',
maxlength: 30,
value: 'Salako',
disabled: false,
icon: 'lock',
validationFunc: (value) => {
},
}
TextArea
Represents a multi-line input component.
![](https://user-images.githubusercontent.com/16062709/40323721-2edbcf06-5d2e-11e8-9bd6-c1922ef7c525.png)
{
key: 'jahaughabdvad',
type: 'textarea',
label: 'Please describe yourself in not more than 400 characters',
placeholder: "My name is John Doe and I am...",
maxlength: 400,
required: true,
value: '',
validationFunc: (value) => {
},
}
Rating
Represents a rating component.
![](https://user-images.githubusercontent.com/16062709/40324095-627362b0-5d2f-11e8-9377-d15bd4e0143e.png)
{
key: 'liaksunshdfjnbah',
type: 'starRating',
label: 'Rate your programming skill',
maxStars: 5,
value: 3,
required: false,
config: {
iconSet: 'MaterialIcons',
emptyStar: 'star-border',
fullStar: 'star',
halfStar: 'star-half',
enableHalfStar: false,
ratingRemark: {
1: 'Beginer',
2: 'Enthusiast',
3: 'Junior',
4: 'Intermediate',
5: 'Senior',
},
},
}
Radio Button
Represents a radio button component.
![](https://user-images.githubusercontent.com/16062709/40326814-88605ea2-5d38-11e8-88db-8e62abb1b3df.png)
{
key: 'sbasgdsbdgffgf',
type: 'radio-group',
label: 'Favorite Programming Language',
other: true,
values: [
{
label: 'JavaScript',
value: 'javascript',
selected: true,
},
{
label: 'Ruby',
value: 'ruby',
}
]
}
CheckBox
Represents a checkbox component.
![](https://user-images.githubusercontent.com/16062709/40329231-ca94f2ee-5d40-11e8-91a6-12a3840029ab.png)
{
key: 'avfsragsghgdbhfg',
type: 'checkbox-group',
label: 'Top 3 tech companies in the world',
other: true,
values: [
{
label: 'Google',
value: 'google',
},
{
label: 'Apple',
value: 'apple',
},
{
label: 'Facebook',
value: 'facebook',
selected: true,
},
{
label: 'Microsoft',
value: 'microsoft',
},
{
label: 'Amazon',
value: 'amazon',
},
]
}
Toggle
Represents a toggle component.
![](https://user-images.githubusercontent.com/16062709/40329121-75c2bf44-5d40-11e8-9ead-c78d00bda337.png)
{
key: 'anhsgabgbfnhhdnbf',
type: 'checkbox-group',
label: 'Sorting Algorithms familiar with',
toggle: true,
other: true,
values: [
{
label: 'Bubble Sort',
value: 'bubble sort',
selected: true,
},
{
label: 'Heapsort',
value: 'heapsort',
},
{
label: 'Insertion Sort',
value: 'insertion sort',
},
{
label: 'Merge Sort',
value: 'merge sort',
},
{
label: 'Quicksort',
value: 'quicksort',
},
]
},
Date
Represents a date component.
![](https://user-images.githubusercontent.com/16062709/40329400-5cd312c6-5d41-11e8-8f29-c7126fabef68.png)
![](https://user-images.githubusercontent.com/16062709/40329466-8d71c4ea-5d41-11e8-8d83-ceefe398ff61.png)
{
key: 'aabnstfavahbdaas',
type: 'date',
label: 'Date of Birth',
value: '26-11-2018',
placeholder: '25-05-2018',
dateFormat: 'DD-MM-YYYY',
disabled: false,
}
Number Input
Represents a number input component.
![](https://user-images.githubusercontent.com/16062709/40329651-253e01ee-5d42-11e8-91cd-72d2fa3e6a64.png)
{
key: 'manbsgvagsdbdhh',
type: 'number',
label: 'Number of Data Structure and Algorithm books read',
placeholder: 0,
value: 0,
min: 0,
max: 100,
step: 2,
disabled: false,
directTextEdit: false,
}
Select
Represents a select component.
![](https://user-images.githubusercontent.com/16062709/40329932-33fbb7a2-5d43-11e8-9cdd-9e82ab7ecb10.png)
![](https://user-images.githubusercontent.com/16062709/40329983-68a0a4f4-5d43-11e8-9c1c-2c61e7a9887d.png)
![](https://user-images.githubusercontent.com/16062709/40330819-14f6224a-5d46-11e8-9fed-bfb1db28ea17.png)
![](https://user-images.githubusercontent.com/16062709/40330964-a81610c6-5d46-11e8-8d3b-540d3f78b5f7.png)
{
key: 'nabsgsgdhyshdhf',
type: 'select',
label: 'Languages Spoken',
multiple: false,
searchInputPlaceholder: 'Search Languages...',
values: [
{
label: 'Yoruba',
value: 'yoruba',
selected: true,
},
{
label: 'Igbo',
value: 'igbo',
},
{
label: 'Hausa',
value: 'hausa',
},
{
label: 'English',
value: 'english',
},
{
label: 'Spanish',
value: 'spanish',
},
{
label: 'French',
value: 'french',
},
]
}
Contributing
Contributions are welcome and will be fully credited.
Contributions are accepted via Pull Requests on Github.
Pull Requests
-
Document any change in behaviour - Make sure the README.md
and any other relevant documentation are kept up-to-date.
-
Consider our release cycle - We try to follow SemVer v2.0.0. Randomly breaking public APIs is not an option.
-
Create feature branches - Don't ask us to pull from your master branch.
-
One pull request per feature - If you want to do more than one thing, send multiple pull requests.
-
Send coherent history - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please squash them before submitting.
Issues
Check issues for current issues.
Contributors
License
The MIT License (MIT). Please see LICENSE for more information.