react-form-package
Version:
A declarative form component with inbuilt validation and state management
418 lines (369 loc) • 16.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Form = void 0;
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _Context = require("../Context");
var _helpers = require("../../helpers");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var Form =
/*#__PURE__*/
function (_React$Component) {
_inherits(Form, _React$Component);
function Form(props) {
var _this;
_classCallCheck(this, Form);
_this = _possibleConstructorReturn(this, _getPrototypeOf(Form).call(this, props));
var _this$props = _this.props,
validate = _this$props.validate,
validateOnClick = _this$props.validateOnClick,
form = _this$props.form,
input = _this$props.input,
checkbox = _this$props.checkbox,
textarea = _this$props.textarea,
radio = _this$props.radio,
radioContainer = _this$props.radioContainer,
button = _this$props.button,
select = _this$props.select,
error = _this$props.error;
_this.state = {
FormComponent: form,
InputComponent: input,
ButtonComponent: button,
SelectComponent: select,
CheckboxComponent: checkbox,
RadioGroupComponent: radio,
RadioGroupContainerComponent: radioContainer,
TextareaComponent: textarea,
ErrorLabelComponent: error,
data: {},
validate: validate,
validateOnClick: validateOnClick,
formValid: false,
buttonClicked: false
};
_this.handleOnFocus = _this.handleOnFocus.bind(_assertThisInitialized(_this));
_this.handleOnChange = _this.handleOnChange.bind(_assertThisInitialized(_this));
_this.handleOnBlur = _this.handleOnBlur.bind(_assertThisInitialized(_this));
_this.setInitialState = _this.setInitialState.bind(_assertThisInitialized(_this));
_this.updateState = _this.updateState.bind(_assertThisInitialized(_this));
_this.validateForm = _this.validateForm.bind(_assertThisInitialized(_this));
_this.addField = _this.addField.bind(_assertThisInitialized(_this));
_this.removeField = _this.removeField.bind(_assertThisInitialized(_this));
_this.setButtonClicked = _this.setButtonClicked.bind(_assertThisInitialized(_this));
return _this;
}
_createClass(Form, [{
key: "componentDidMount",
value: function componentDidMount() {
this.updateState();
}
}, {
key: "setButtonClicked",
value: function setButtonClicked() {
this.setState({
buttonClicked: true
});
}
}, {
key: "handleOnFocus",
value: function handleOnFocus(e, cb) {
var _this2 = this;
var _e$target = e.target,
id = _e$target.id,
type = _e$target.type,
name = _e$target.name;
var data = this.state.data;
var myId = type === 'radio' ? name : id;
this.setState({
data: _objectSpread({}, data, _defineProperty({}, myId, _objectSpread({}, data[myId], {
visited: true
})))
}, function () {
return _this2.validateForm(cb);
});
}
}, {
key: "handleOnChange",
value: function handleOnChange(e, rules, options, cb) {
var _this3 = this;
var _e$target2 = e.target,
id = _e$target2.id,
value = _e$target2.value,
checked = _e$target2.checked,
type = _e$target2.type,
name = _e$target2.name,
files = _e$target2.files;
var data = this.state.data;
var checkbox = type === 'checkbox';
var file = type === 'file';
var radio = type === 'radio';
var myId = radio ? name : id;
var myValue = radio ? id : value;
myValue = checkbox ? checked : myValue;
var myFiles = files;
if (!files) {
myValue = options.preOnChange ? options.preOnChange(myValue) : myValue;
} else {
myFiles = options.preOnChange ? options.preOnChange(files) : files;
}
var valid = (0, _helpers.checkFormInput)(rules, myValue, data);
var newData = _objectSpread({}, data, _defineProperty({}, myId, _objectSpread({}, data[myId], {
value: myValue,
files: file ? myFiles : undefined,
checked: checked,
valid: valid,
invalid: !valid,
pristine: value === data[myId].initialValue,
dirty: value !== data[myId].initialValue
})));
if (options.dynamic && myValue) {
newData = _objectSpread({}, newData, _defineProperty({}, options.field.id, _objectSpread({}, (0, _helpers.initialState)(options.field, data))));
}
if (options.bindTo && (myValue || myValue === false)) {
newData = (0, _helpers.handleBindToValues)(newData, data, myValue, options);
}
if (rules.sameAs) {
newData = _objectSpread({}, newData, _defineProperty({}, rules.sameAs, _objectSpread({}, newData[rules.sameAs], {
valid: valid,
invalid: !valid
})));
}
this.setState({
data: _objectSpread({}, newData)
}, function () {
return _this3.validateForm(cb);
});
}
}, {
key: "handleOnBlur",
value: function handleOnBlur(e, cb) {
var _this4 = this;
var _e$target3 = e.target,
id = _e$target3.id,
type = _e$target3.type,
name = _e$target3.name;
var data = this.state.data;
var myId = type === 'radio' ? name : id;
this.setState({
data: _objectSpread({}, data, _defineProperty({}, myId, _objectSpread({}, data[myId], {
touched: true
})))
}, function () {
return _this4.validateForm(cb);
});
}
}, {
key: "setInitialState",
value: function setInitialState(children) {
var _this5 = this;
var data = {};
children.forEach(function (child) {
data = _objectSpread({}, data, _defineProperty({}, child.props.id, _objectSpread({}, (0, _helpers.initialState)(child.props, data))));
});
this.setState({
data: data
}, function () {
return _this5.validateForm();
});
}
}, {
key: "addField",
value: function addField(fields) {
var _this6 = this;
var data = this.state.data;
var fieldsArr;
var newFields = {};
if (!Array.isArray(fields)) {
fieldsArr = [fields];
} else {
fieldsArr = fields;
}
fieldsArr.forEach(function (field) {
newFields = _objectSpread({}, newFields, _defineProperty({}, field.id, _objectSpread({}, (0, _helpers.initialState)(field, data))));
});
this.setState({
data: _objectSpread({}, data, {}, newFields)
}, function () {
return _this6.validateForm();
});
}
}, {
key: "removeField",
value: function removeField(fieldIds) {
var _this7 = this;
var data = this.state.data;
var fieldIdsArr;
var newFields = {};
if (!Array.isArray(fieldIds)) {
fieldIdsArr = [fieldIds];
} else {
fieldIdsArr = fieldIds;
}
Object.keys(data).forEach(function (d) {
if (!fieldIdsArr.includes(d)) {
newFields = _objectSpread({}, newFields, _defineProperty({}, d, data[d]));
}
});
this.setState({
data: newFields
}, function () {
return _this7.validateForm();
});
}
}, {
key: "updateState",
value: function updateState() {
var children = this.props.children;
var flatChilds = (0, _helpers.getNestedChilds)(children, []);
this.setInitialState(flatChilds);
}
}, {
key: "validateForm",
value: function validateForm(cb) {
var _this8 = this;
var data = this.state.data;
var allFieldValidations = [];
var newData = _objectSpread({}, data);
Object.keys(data).forEach(function (key) {
var oneValid = false;
if (data[key].rules.sameAs) {
oneValid = (0, _helpers.checkFormInput)(data[key].rules, data[key].value, data);
newData = _objectSpread({}, newData, _defineProperty({}, key, _objectSpread({}, data[key], {
valid: oneValid,
invalid: !oneValid
})));
} else {
oneValid = data[key].valid;
}
allFieldValidations.push(oneValid);
});
var allFieldsValid = allFieldValidations.every(function (val) {
return val;
});
this.setState({
data: newData,
formValid: allFieldsValid
}, function () {
var state = _this8.state;
if (cb) {
cb((0, _helpers.createReturnState)(state));
}
});
}
}, {
key: "render",
value: function render() {
var _this$state = this.state,
FormComponent = _this$state.FormComponent,
InputComponent = _this$state.InputComponent,
ButtonComponent = _this$state.ButtonComponent,
SelectComponent = _this$state.SelectComponent,
CheckboxComponent = _this$state.CheckboxComponent,
RadioGroupComponent = _this$state.RadioGroupComponent,
RadioGroupContainerComponent = _this$state.RadioGroupContainerComponent,
TextareaComponent = _this$state.TextareaComponent,
ErrorLabelComponent = _this$state.ErrorLabelComponent,
data = _this$state.data,
validate = _this$state.validate,
validateOnClick = _this$state.validateOnClick,
formValid = _this$state.formValid,
buttonClicked = _this$state.buttonClicked;
var _this$props2 = this.props,
children = _this$props2.children,
encType = _this$props2.encType;
return _react["default"].createElement(_Context.Context.Provider, {
value: {
FormComponent: FormComponent,
InputComponent: InputComponent,
ButtonComponent: ButtonComponent,
SelectComponent: SelectComponent,
CheckboxComponent: CheckboxComponent,
RadioGroupComponent: RadioGroupComponent,
RadioGroupContainerComponent: RadioGroupContainerComponent,
TextareaComponent: TextareaComponent,
ErrorLabelComponent: ErrorLabelComponent,
data: data,
validate: validate,
validateOnClick: validateOnClick,
formValid: formValid,
buttonClicked: buttonClicked,
handleOnFocus: this.handleOnFocus,
handleOnChange: this.handleOnChange,
handleOnBlur: this.handleOnBlur,
addField: this.addField,
removeField: this.removeField,
setButtonClicked: this.setButtonClicked
}
}, _react["default"].createElement(FormComponent.type, _extends({}, FormComponent.props, {
encType: encType
}), children));
}
}]);
return Form;
}(_react["default"].Component);
exports.Form = Form;
Form.defaultProps = {
validate: false,
validateOnClick: false,
form: _react["default"].createElement("form", {
className: "rfp-form"
}),
input: _react["default"].createElement("input", {
className: "rfp-input"
}),
checkbox: _react["default"].createElement("input", {
className: "rfp-checkbox"
}),
radio: _react["default"].createElement("input", {
className: "rfp-radio-group"
}),
radioContainer: _react["default"].createElement("div", {
className: "rfp-radio-group-container"
}),
button: _react["default"].createElement("button", {
className: "rfp-button"
}),
// eslint-disable-line
select: _react["default"].createElement("select", {
className: "rfp-select"
}),
// eslint-disable-line
textarea: _react["default"].createElement("textarea", {
className: "rfp-textarea"
}),
error: _react["default"].createElement("div", {
className: "rfp-error-label"
}),
encType: undefined
};
Form.propTypes = {
validate: _propTypes["default"].bool,
validateOnClick: _propTypes["default"].bool,
form: _propTypes["default"].element,
input: _propTypes["default"].element,
checkbox: _propTypes["default"].element,
radio: _propTypes["default"].element,
radioContainer: _propTypes["default"].element,
button: _propTypes["default"].element,
select: _propTypes["default"].element,
textarea: _propTypes["default"].element,
error: _propTypes["default"].element,
children: _propTypes["default"].oneOfType([_propTypes["default"].arrayOf(_propTypes["default"].element), _propTypes["default"].element]).isRequired,
encType: _propTypes["default"].string
};