diff --git a/package-lock.json b/package-lock.json
index e81c9aac..788b1c74 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "react-form-builder2",
- "version": "0.5.14",
+ "version": "0.6.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 5205066c..2996023f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-form-builder2",
- "version": "0.5.14",
+ "version": "0.6.0",
"description": "A complete form builder for react.",
"main": "lib/index.js",
"license": "MIT",
diff --git a/src/form-elements/component-header.jsx b/src/form-elements/component-header.jsx
new file mode 100644
index 00000000..54d2412f
--- /dev/null
+++ b/src/form-elements/component-header.jsx
@@ -0,0 +1,18 @@
+import React from 'react';
+import HeaderBar from './header-bar';
+
+const ComponentHeader = (props) => {
+ if (props.mutable) {
+ return null;
+ }
+ return (
+
+ { props.data.pageBreakBefore &&
+
Page Break
+ }
+
+
+ );
+};
+
+export default ComponentHeader;
diff --git a/src/form-elements/component-label.jsx b/src/form-elements/component-label.jsx
new file mode 100644
index 00000000..25065ef7
--- /dev/null
+++ b/src/form-elements/component-label.jsx
@@ -0,0 +1,15 @@
+import React from 'react';
+import myxss from './myxss';
+
+const ComponentLabel = (props) => {
+ const hasRequiredLabel = (props.data.hasOwnProperty('required') && props.data.required === true && !props.read_only);
+
+ return (
+
+ );
+};
+
+export default ComponentLabel;
diff --git a/src/form-elements/date-picker.jsx b/src/form-elements/date-picker.jsx
new file mode 100644
index 00000000..9f7e440a
--- /dev/null
+++ b/src/form-elements/date-picker.jsx
@@ -0,0 +1,156 @@
+import React from 'react';
+import { format, parse } from 'date-fns';
+import ReactDatePicker from 'react-datepicker';
+import ComponentHeader from './component-header';
+import ComponentLabel from './component-label';
+
+class DatePicker extends React.Component {
+ constructor(props) {
+ super(props);
+ this.inputField = React.createRef();
+
+ const { formatMask } = DatePicker.updateFormat(props, null);
+ this.state = DatePicker.updateDateTime(props, { formatMask }, formatMask);
+ }
+
+ // formatMask = '';
+
+ handleChange = (dt) => {
+ let placeholder;
+ const { formatMask } = this.state;
+ if (dt && dt.target) {
+ placeholder = (dt && dt.target && dt.target.value === '') ? formatMask.toLowerCase() : '';
+ const formattedDate = (dt.target.value) ? format(dt.target.value, formatMask) : '';
+ this.setState({
+ value: formattedDate,
+ internalValue: formattedDate,
+ placeholder,
+ });
+ } else {
+ this.setState({
+ value: (dt) ? format(dt, formatMask) : '',
+ internalValue: dt,
+ placeholder,
+ });
+ }
+ };
+
+ static updateFormat(props, oldFormatMask) {
+ const { showTimeSelect, showTimeSelectOnly } = props.data;
+ const dateFormat = showTimeSelect && showTimeSelectOnly ? '' : props.data.dateFormat;
+ const timeFormat = showTimeSelect ? props.data.timeFormat : '';
+ const formatMask = (`${dateFormat} ${timeFormat}`).trim();
+ const updated = formatMask !== oldFormatMask;
+
+ return { updated, formatMask };
+ }
+
+ static updateDateTime(props, state, formatMask) {
+ let value;
+ let internalValue;
+ const { defaultToday } = props.data;
+ if (defaultToday && (props.defaultValue === '' || props.defaultValue === undefined)) {
+ value = format(new Date(), formatMask);
+ internalValue = new Date();
+ } else {
+ value = props.defaultValue;
+
+ if (value === '' || value === undefined) {
+ internalValue = undefined;
+ } else {
+ internalValue = parse(value, state.formatMask, new Date());
+ }
+ }
+ return {
+ value,
+ internalValue,
+ placeholder: formatMask.toLowerCase(),
+ defaultToday,
+ formatMask: state.formatMask,
+ };
+ }
+
+ // componentWillReceiveProps(props) {
+ // const formatUpdated = this.updateFormat(props);
+ // if ((props.data.defaultToday !== !this.state.defaultToday) || formatUpdated) {
+ // const state = this.updateDateTime(props, this.formatMask);
+ // this.setState(state);
+ // }
+ // }
+
+ static getDerivedStateFromProps(props, state) {
+ const { updated, formatMask } = DatePicker.updateFormat(props, state.formatMask);
+ if ((props.data.defaultToday !== state.defaultToday) || updated) {
+ const newState = DatePicker.updateDateTime(props, state, formatMask);
+ return newState;
+ }
+ return null;
+ }
+
+ render() {
+ const { showTimeSelect, showTimeSelectOnly } = this.props.data;
+ const props = {};
+ props.type = 'date';
+ props.className = 'form-control';
+ props.name = this.props.data.field_name;
+ const readOnly = this.props.data.readOnly || this.props.read_only;
+ const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
+ const placeholderText = this.state.formatMask.toLowerCase();
+
+ if (this.props.mutable) {
+ props.defaultValue = this.props.defaultValue;
+ props.ref = this.inputField;
+ }
+
+ let baseClasses = 'SortableItem rfb-item';
+ if (this.props.data.pageBreakBefore) { baseClasses += ' alwaysbreak'; }
+
+ return (
+
+ );
+ }
+}
+
+export default DatePicker;
diff --git a/src/header-bar.jsx b/src/form-elements/header-bar.jsx
similarity index 100%
rename from src/header-bar.jsx
rename to src/form-elements/header-bar.jsx
diff --git a/src/form-elements.jsx b/src/form-elements/index.jsx
similarity index 78%
rename from src/form-elements.jsx
rename to src/form-elements/index.jsx
index 7c31dcb0..10e45d0e 100644
--- a/src/form-elements.jsx
+++ b/src/form-elements/index.jsx
@@ -1,59 +1,17 @@
// eslint-disable-next-line max-classes-per-file
import React from 'react';
import Select from 'react-select';
-import xss from 'xss';
-import { format, parse } from 'date-fns';
-// import moment from 'moment';
import SignaturePad from 'react-signature-canvas';
import ReactBootstrapSlider from 'react-bootstrap-slider';
-import ReactDatePicker from 'react-datepicker';
+
import StarRating from './star-rating';
import HeaderBar from './header-bar';
+import DatePicker from './date-picker';
+import ComponentHeader from './component-header';
+import ComponentLabel from './component-label';
+import myxss from './myxss';
const FormElements = {};
-const myxss = new xss.FilterXSS({
- whiteList: {
- u: [],
- br: [],
- b: [],
- i: [],
- ol: ['style'],
- ul: ['style'],
- li: [],
- p: ['style'],
- sub: [],
- sup: [],
- div: ['style'],
- em: [],
- strong: [],
- span: ['style'],
- },
-});
-
-const ComponentLabel = (props) => {
- const hasRequiredLabel = (props.data.hasOwnProperty('required') && props.data.required === true && !props.read_only);
-
- return (
-
- );
-};
-
-const ComponentHeader = (props) => {
- if (props.mutable) {
- return null;
- }
- return (
-
- { props.data.pageBreakBefore &&
-
Page Break
- }
-
-
- );
-};
class Header extends React.Component {
render() {
@@ -230,142 +188,6 @@ class TextArea extends React.Component {
}
}
-class DatePicker extends React.Component {
- constructor(props) {
- super(props);
- this.inputField = React.createRef();
-
- this.updateFormat(props);
- this.state = this.updateDateTime(props, this.formatMask);
- }
-
- formatMask = '';
-
- handleChange = (dt) => {
- let placeholder;
- if (dt && dt.target) {
- placeholder = (dt && dt.target && dt.target.value === '') ? this.formatMask.toLowerCase() : '';
- const formattedDate = (dt.target.value) ? format(dt.target.value, this.formatMask) : '';
- this.setState({
- value: formattedDate,
- internalValue: formattedDate,
- placeholder,
- });
- } else {
- this.setState({
- value: (dt) ? format(dt, this.formatMask) : '',
- internalValue: dt,
- placeholder,
- });
- }
- };
-
- updateFormat(props) {
- const { showTimeSelect, showTimeSelectOnly } = props.data;
- const dateFormat = showTimeSelect && showTimeSelectOnly ? '' : props.data.dateFormat;
- const timeFormat = showTimeSelect ? props.data.timeFormat : '';
- const formatMask = (`${dateFormat} ${timeFormat}`).trim();
- const updated = formatMask !== this.formatMask;
- this.formatMask = formatMask;
- return updated;
- }
-
- updateDateTime(props, formatMask) {
- let value;
- let internalValue;
- const { defaultToday } = props.data;
- if (defaultToday && (props.defaultValue === '' || props.defaultValue === undefined)) {
- value = format(new Date(), formatMask);
- internalValue = new Date();
- } else {
- value = props.defaultValue;
-
- if (value === '' || value === undefined) {
- internalValue = undefined;
- } else {
- internalValue = parse(value, this.formatMask, new Date());
- }
- }
- return {
- value,
- internalValue,
- placeholder: formatMask.toLowerCase(),
- defaultToday,
- };
- }
-
- componentWillReceiveProps(props) {
- const formatUpdated = this.updateFormat(props);
- if ((props.data.defaultToday !== !this.state.defaultToday) || formatUpdated) {
- const state = this.updateDateTime(props, this.formatMask);
- this.setState(state);
- }
- }
-
- render() {
- const { showTimeSelect, showTimeSelectOnly } = this.props.data;
- const props = {};
- props.type = 'date';
- props.className = 'form-control';
- props.name = this.props.data.field_name;
- const readOnly = this.props.data.readOnly || this.props.read_only;
- const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
- const placeholderText = this.formatMask.toLowerCase();
-
- if (this.props.mutable) {
- props.defaultValue = this.props.defaultValue;
- props.ref = this.inputField;
- }
-
- let baseClasses = 'SortableItem rfb-item';
- if (this.props.data.pageBreakBefore) { baseClasses += ' alwaysbreak'; }
-
- return (
-
- );
- }
-}
class Dropdown extends React.Component {
constructor(props) {
diff --git a/src/form-elements/myxss.js b/src/form-elements/myxss.js
new file mode 100644
index 00000000..ba6fabf3
--- /dev/null
+++ b/src/form-elements/myxss.js
@@ -0,0 +1,22 @@
+import xss from 'xss';
+
+const myxss = new xss.FilterXSS({
+ whiteList: {
+ u: [],
+ br: [],
+ b: [],
+ i: [],
+ ol: ['style'],
+ ul: ['style'],
+ li: [],
+ p: ['style'],
+ sub: [],
+ sup: [],
+ div: ['style'],
+ em: [],
+ strong: [],
+ span: ['style'],
+ },
+});
+
+export default myxss;
diff --git a/src/star-rating.jsx b/src/form-elements/star-rating.jsx
similarity index 88%
rename from src/star-rating.jsx
rename to src/form-elements/star-rating.jsx
index f515ff59..904d2d70 100644
--- a/src/star-rating.jsx
+++ b/src/form-elements/star-rating.jsx
@@ -22,15 +22,21 @@ export default class StarRating extends React.Component {
constructor(props) {
super(props);
+ this.min = 0;
+ this.max = props.ratingAmount || 5;
+
+ const ratingVal = props.rating;
+ const ratingCache = {
+ pos: ratingVal ? this.getStarRatingPosition(ratingVal) : 0,
+ rating: props.rating,
+ };
+
this.state = {
- ratingCache: {
- pos: 0,
- rating: 0,
- },
- editing: props.editing || true,
+ ratingCache,
+ editing: props.editing || !props.rating,
stars: 5,
- rating: 0,
- pos: 0,
+ rating: ratingCache.rating,
+ pos: ratingCache.pos,
glyph: this.getStars(),
};
}
@@ -48,22 +54,22 @@ export default class StarRating extends React.Component {
return stars;
}
- componentWillMount() {
- this.min = 0;
- this.max = this.props.ratingAmount || 5;
- if (this.props.rating) {
- this.state.editing = this.props.editing || false;
- const ratingVal = this.props.rating;
- this.state.ratingCache.pos = this.getStarRatingPosition(ratingVal);
- this.state.ratingCache.rating = ratingVal;
-
- this.setState({
- ratingCache: this.state.ratingCache,
- rating: ratingVal,
- pos: this.getStarRatingPosition(ratingVal),
- });
- }
- }
+ // componentWillMount() {
+ // this.min = 0;
+ // this.max = this.props.ratingAmount || 5;
+ // if (this.props.rating) {
+ // this.state.editing = this.props.editing || false;
+ // const ratingVal = this.props.rating;
+ // this.state.ratingCache.pos = this.getStarRatingPosition(ratingVal);
+ // this.state.ratingCache.rating = ratingVal;
+
+ // this.setState({
+ // ratingCache: this.state.ratingCache,
+ // rating: ratingVal,
+ // pos: this.getStarRatingPosition(ratingVal),
+ // });
+ // }
+ // }
componentDidMount() {
this.root = ReactDOM.findDOMNode(this.rootNode);
diff --git a/src/form-validator.jsx b/src/form-validator.jsx
index d4213236..61b9e7cf 100644
--- a/src/form-validator.jsx
+++ b/src/form-validator.jsx
@@ -32,7 +32,7 @@ export default class FormValidator extends React.Component {
};
}
- componentWillMount() {
+ componentDidMount() {
this.subscription = this.props.emitter.addListener('formValidation', (errors) => {
this.setState({ errors });
});
diff --git a/src/preview.jsx b/src/preview.jsx
index f006e21d..5110a351 100644
--- a/src/preview.jsx
+++ b/src/preview.jsx
@@ -31,10 +31,11 @@ export default class Preview extends React.Component {
this.insertCard = this.insertCard.bind(this);
}
- componentWillReceiveProps(nextProps) {
- if (this.props.data !== nextProps.data) {
- store.dispatch('updateOrder', nextProps.data);
+ static getDerivedStateFromProps(props, state) {
+ if (props.data && props.data !== state.data) {
+ store.dispatch('updateOrder', props.data);
}
+ return null;
}
componentDidMount() {