availity-reactstrap-validation
Version:
Form validation helpers for reactstrap
465 lines (359 loc) • 15.4 kB
JavaScript
'use strict';
exports.__esModule = true;
var _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; };
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _AvInputContainer = require('./AvInputContainer');
var _AvInputContainer2 = _interopRequireDefault(_AvInputContainer);
var _AvValidator = require('./AvValidator');
var _AvValidator2 = _interopRequireDefault(_AvValidator);
var _reactstrap = require('reactstrap');
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
var _lodash = require('lodash.get');
var _lodash2 = _interopRequireDefault(_lodash);
var _lodash3 = require('lodash.set');
var _lodash4 = _interopRequireDefault(_lodash3);
var _lodash5 = require('lodash.isstring');
var _lodash6 = _interopRequireDefault(_lodash5);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var getInputErrorMessage = function getInputErrorMessage(input, ruleName) {
var errorMessage = input.props.errorMessage;
if ((typeof errorMessage === 'undefined' ? 'undefined' : _typeof(errorMessage)) === 'object') {
return errorMessage[ruleName];
} else {
return errorMessage;
}
};
var AvForm = function (_InputContainer) {
_inherits(AvForm, _InputContainer);
function AvForm(props) {
_classCallCheck(this, AvForm);
var _this = _possibleConstructorReturn(this, _InputContainer.call(this, props));
_this.state = {
invalidInputs: {},
dirtyInputs: {},
touchedInputs: {},
badInputs: {},
submitted: false
};
_this.handleSubmit = _this.handleSubmit.bind(_this);
_this.handleNonFormSubmission = _this.handleNonFormSubmission.bind(_this);
return _this;
}
AvForm.prototype.getChildContext = function getChildContext() {
return {
FormCtrl: {
inputs: this._inputs,
getDefaultValue: this.getDefaultValue.bind(this),
getInputState: this.getInputState.bind(this),
hasError: this.state.invalidInputs,
isDirty: this.state.dirtyInputs,
isTouched: this.state.touchedInputs,
isBad: this.state.badInputs,
setDirty: this.setDirty.bind(this),
setTouched: this.setTouched.bind(this),
setBad: this.setBad.bind(this),
register: this.registerInput.bind(this),
unregister: this.unregisterInput.bind(this),
validate: this.validateInput.bind(this),
validationEvent: this.props.validationEvent,
parent: this.context.FormCtrl || null
}
};
};
AvForm.prototype.componentWillMount = function componentWillMount() {
_InputContainer.prototype.componentWillMount.call(this);
this._validators = {};
};
AvForm.prototype.registerInput = function registerInput(input) {
_InputContainer.prototype.registerInput.call(this, input);
if (_typeof(input.validations) === 'object') {
this._validators[input.props.name] = this.compileValidationRules(input, input.validations);
}
};
AvForm.prototype.unregisterInput = function unregisterInput(input) {
_InputContainer.prototype.unregisterInput.call(this, input);
delete this._validators[input.props.name];
};
AvForm.prototype.handleNonFormSubmission = function handleNonFormSubmission(event) {
if (this.props.onKeyDown(event) !== false) {
if (event.type === 'keydown' && (event.which === 13 || event.keyCode === 13 || event.key === 'Enter')) {
event.stopPropagation();
event.preventDefault();
this.handleSubmit.apply(this, arguments);
}
}
};
AvForm.prototype.render = function render() {
var _props = this.props;
var Tag = _props.tag;
var errorMessage = _props.errorMessage;
var model = _props.model;
var onValidSubmit = _props.onValidSubmit;
var onInvalidSubmit = _props.onInvalidSubmit;
var validate = _props.validate;
var validateOne = _props.validateOne;
var validateAll = _props.validateAll;
var validationEvent = _props.validationEvent;
var className = _props.className;
var attributes = _objectWithoutProperties(_props, ['tag', 'errorMessage', 'model', 'onValidSubmit', 'onInvalidSubmit', 'validate', 'validateOne', 'validateAll', 'validationEvent', 'className']);
var classes = (0, _classnames2.default)(className, this.state.submitted ? 'av-submitted' : false, Object.keys(this.state.invalidInputs).length > 0 ? 'av-invalid' : 'av-valid');
if (Tag !== 'form' && Tag !== _reactstrap.Form) {
attributes.onKeyDown = this.handleNonFormSubmission;
}
return _react2.default.createElement(Tag, _extends({ noValidate: true,
action: '#'
}, attributes, {
className: classes,
onSubmit: this.handleSubmit }));
};
AvForm.prototype.getValues = function getValues() {
var _this2 = this;
return Object.keys(this._inputs).reduce(function (values, inputName) {
(0, _lodash4.default)(values, inputName, _this2.getValue(inputName));
return values;
}, {});
};
AvForm.prototype.submit = function submit() {
this.handleSubmit.apply(this, arguments);
};
AvForm.prototype.reset = function reset() {
var _this3 = this;
Object.keys(this._inputs).forEach(function (inputName) {
return _this3._inputs[inputName].reset();
});
};
AvForm.prototype.validateInput = function validateInput(name) {
this.validateOne(name, this.getValues());
};
AvForm.prototype.getInputState = function getInputState(inputName) {
var errorMessage = this.isTouched(inputName) && this.hasError(inputName);
var error = !!errorMessage;
var color = void 0;
if (error) {
color = 'danger';
if (errorMessage === true) {
errorMessage = 'This field is invalid';
}
}
return { color: color, error: error, errorMessage: errorMessage };
};
AvForm.prototype.hasError = function hasError(inputName) {
return inputName ? !!this.state.invalidInputs[inputName] : Object.keys(this.state.invalidInputs).length > 0;
};
AvForm.prototype.isDirty = function isDirty(inputName) {
return inputName ? !!this.state.dirtyInputs[inputName] : Object.keys(this.state.dirtyInputs).length > 0;
};
AvForm.prototype.isTouched = function isTouched(inputName) {
return inputName ? !!this.state.touchedInputs[inputName] : Object.keys(this.state.touchedInputs).length > 0;
};
AvForm.prototype.isBad = function isBad(inputName) {
return inputName ? !!this.state.badInputs[inputName] : Object.keys(this.state.badInputs).length > 0;
};
AvForm.prototype.setError = function setError(inputName) {
var error = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
var errText = arguments.length <= 2 || arguments[2] === undefined ? error : arguments[2];
if (error && !(0, _lodash6.default)(errText) && typeof errText !== 'boolean') {
errText = errText + '';
}
var currentError = this.hasError(inputName);
if (currentError === errText) return;
var invalidInputs = this.state.invalidInputs;
if (error) {
invalidInputs[inputName] = errText || true;
} else {
delete invalidInputs[inputName];
}
invalidInputs = _extends({}, this.state.invalidInputs);
this.setState({ invalidInputs: invalidInputs });
};
AvForm.prototype.setDirty = function setDirty(inputs) {
var dirty = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
var dirtyInputs = this.state.dirtyInputs;
if (!Array.isArray(inputs)) {
inputs = [inputs];
}
inputs.forEach(function (inputName) {
if (dirty) {
dirtyInputs[inputName] = true;
} else {
delete dirtyInputs[inputName];
}
});
dirtyInputs = _extends({}, this.state.dirtyInputs);
this.setState({ dirtyInputs: dirtyInputs });
};
AvForm.prototype.setTouched = function setTouched(inputs) {
var touched = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
var touchedInputs = this.state.touchedInputs;
if (!Array.isArray(inputs)) {
inputs = [inputs];
}
inputs.forEach(function (inputName) {
if (touched) {
touchedInputs[inputName] = true;
} else {
delete touchedInputs[inputName];
}
});
touchedInputs = _extends({}, this.state.touchedInputs);
this.setState({ touchedInputs: touchedInputs });
};
AvForm.prototype.setBad = function setBad(inputs) {
var isBad = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
var badInputs = this.state.badInputs;
if (!Array.isArray(inputs)) {
inputs = [inputs];
}
inputs.forEach(function (inputName) {
if (isBad) {
badInputs[inputName] = true;
} else {
delete badInputs[inputName];
}
});
badInputs = _extends({}, this.state.badInputs);
this.setState({ badInputs: badInputs });
};
AvForm.prototype.validateOne = function validateOne(inputName, context) {
var input = this._inputs[inputName];
if (Array.isArray(input)) {
throw new Error('Multiple inputs cannot use the same name: "' + inputName + '"');
}
var value = (0, _lodash2.default)(context, inputName);
var validate = input.validations;
var isValid = true;
var result = void 0;
var error = void 0;
if (typeof validate === 'function') {
result = validate(value, context, input);
} else if ((typeof validate === 'undefined' ? 'undefined' : _typeof(validate)) === 'object') {
result = this._validators[inputName](value, context);
} else {
result = true;
}
if (result !== true) {
isValid = false;
if ((0, _lodash6.default)(result)) {
error = result;
}
}
this.setError(inputName, !isValid, error);
return isValid;
};
AvForm.prototype.validateAll = function validateAll(context) {
var _this4 = this;
var errors = [];
var isValid = true;
Object.keys(this._inputs).forEach(function (inputName) {
if (!_this4.validateOne(inputName, context)) {
isValid = false;
errors.push(inputName);
}
});
if (this.props.validate) {
var formLevelValidation = this.props.validate;
if (!Array.isArray(formLevelValidation)) {
formLevelValidation = [formLevelValidation];
}
if (!formLevelValidation.every(function (validationFn) {
return validationFn(context);
})) {
isValid = false;
errors.push('*');
}
}
return {
isValid: isValid,
errors: errors
};
};
AvForm.prototype.compileValidationRules = function compileValidationRules(input, ruleProp) {
var _this5 = this;
return function (val, context) {
if (_this5.isBad(input.props.name)) {
return false;
}
var result = true;
var ruleResult = void 0;
Object.keys(ruleProp).some(function (rule) {
if (typeof ruleProp[rule] === 'function') {
ruleResult = ruleProp[rule](val, context, input);
} else {
if (typeof _AvValidator2.default[rule] !== 'function') {
throw new Error('Invalid input validation rule: "' + rule + '"');
}
ruleResult = _AvValidator2.default[rule](val, context, ruleProp[rule], input);
}
if (result === true && ruleResult !== true) {
result = (0, _lodash6.default)(ruleResult) && ruleResult || getInputErrorMessage(input, rule) || getInputErrorMessage(_this5, rule) || false;
}
return result !== true;
});
return result;
};
};
AvForm.prototype.getDefaultValue = function getDefaultValue(inputName) {
return (0, _lodash2.default)(this.props.model, inputName);
};
AvForm.prototype.getValue = function getValue(inputName) {
var input = this._inputs[inputName];
if (Array.isArray(input)) {
throw new Error('Multiple inputs cannot use the same name: "' + inputName + '"');
}
return input.getValue();
};
AvForm.prototype.handleSubmit = function handleSubmit(e) {
if (e && typeof e.preventDefault === 'function') {
e.preventDefault();
}
var values = this.getValues();
var _validateAll = this.validateAll(values);
var isValid = _validateAll.isValid;
var errors = _validateAll.errors;
this.setTouched(Object.keys(this._inputs));
this.props.onSubmit(e, errors, values);
if (isValid) {
this.props.onValidSubmit(e, values);
} else {
this.props.onInvalidSubmit(e, errors, values);
}
!this.state.submitted && this.setState({ submitted: true });
};
return AvForm;
}(_AvInputContainer2.default);
AvForm.childContextTypes = {
FormCtrl: _react.PropTypes.object.isRequired
};
AvForm.contextTypes = {
FormCtrl: _react.PropTypes.object
};
AvForm.propTypes = {
tag: _react.PropTypes.oneOfType([_react.PropTypes.func, _react.PropTypes.string]),
className: _react.PropTypes.string,
model: _react.PropTypes.object,
method: _react.PropTypes.oneOf(['get', 'post']),
onSubmit: _react.PropTypes.func,
validate: _react.PropTypes.oneOfType([_react.PropTypes.func, _react.PropTypes.array]),
onValidSubmit: _react.PropTypes.func,
onInvalidSubmit: _react.PropTypes.func,
validationEvent: _react.PropTypes.oneOf(['onInput', 'onChange', 'onBlur', 'onFocus']),
errorMessage: _react.PropTypes.oneOfType([_react.PropTypes.object, _react.PropTypes.string, _react.PropTypes.node])
};
AvForm.defaultProps = {
tag: _reactstrap.Form,
model: {},
validationEvent: 'onChange',
method: 'get',
onSubmit: function onSubmit() {},
onKeyDown: function onKeyDown() {},
onValidSubmit: function onValidSubmit() {},
onInvalidSubmit: function onInvalidSubmit() {}
};
exports.default = AvForm;