react-validation-mixin
Version:
Simple Validation Mixin for React.
179 lines (129 loc) • 7.17 kB
JavaScript
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; };
exports.default = validationMixin;
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _invariant = require('invariant');
var _invariant2 = _interopRequireDefault(_invariant);
var _lodash = require('lodash.result');
var _lodash2 = _interopRequireDefault(_lodash);
var _validationFactory = require('../validationFactory');
var _validationFactory2 = _interopRequireDefault(_validationFactory);
var _reactDisplayName = require('react-display-name');
var _reactDisplayName2 = _interopRequireDefault(_reactDisplayName);
var _utils = require('../utils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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; }
function validationMixin(strategy) {
var validator = (0, _validationFactory2.default)(strategy);
return function wrappedComponentFn(WrappedComponent) {
(0, _invariant2.default)((0, _utils.defined)(WrappedComponent), 'Component was not provided to the Validator. Export you Component with "export default validator(strategy)(Component);"');
var Validation = function (_React$Component) {
_inherits(Validation, _React$Component);
function Validation(props, context) {
_classCallCheck(this, Validation);
var _this = _possibleConstructorReturn(this, _React$Component.call(this, props, context));
_this.render = _this.render.bind(_this);
_this.validate = _this.validate.bind(_this);
_this.isValid = _this.isValid.bind(_this);
_this.getValidationMessages = _this.getValidationMessages.bind(_this);
_this.clearValidations = _this.clearValidations.bind(_this);
_this.handleValidation = _this.handleValidation.bind(_this);
_this._invokeCallback = _this._invokeCallback.bind(_this);
_this.state = { errors: {} };
return _this;
}
/* Get current validation messages for a specified key or entire form.
*
* @param {?String} key to get messages, or entire form if key is undefined.
* @return {Array}
*/
Validation.prototype.getValidationMessages = function getValidationMessages(key) {
return validator.getValidationMessages(this.state.errors, key) || [];
};
/* Convenience method to validate a key via an event handler. Useful for
* onBlur, onClick, onChange, etc...
*
* @param {?String} State key to validate
* @return {function} validation event handler
*/
Validation.prototype.handleValidation = function handleValidation(key, callback) {
var _this2 = this;
return function () {
_this2.validate(key, callback);
};
};
/* Method to validate single form key or entire form against the component data.
*
* @param {String|Function} key to validate, or error-first containing the validation errors if any.
* @param {?Function} error-first callback containing the validation errors if any.
*/
Validation.prototype.validate = function validate() /* [key], callback */{
var _this3 = this;
var fallback = arguments.length <= 1 && typeof arguments[0] === 'function' ? arguments[0] : undefined;
var key = arguments.length <= 1 && typeof arguments[0] === 'function' ? undefined : arguments[0];
var callback = arguments.length <= 2 && typeof arguments[1] === 'function' ? arguments[1] : fallback;
var data = (0, _lodash2.default)(this.refs.component, 'getValidatorData');
var schema = (0, _lodash2.default)(this.refs.component, 'validatorTypes');
(0, _invariant2.default)((0, _utils.defined)(data), 'Data was not provided to the Validator. Implement "getValidatorData" to return data.');
(0, _invariant2.default)((0, _utils.defined)(schema), 'A schema was not provided to the Validator. Implement "validatorTypes" to return a validation schema.');
var options = {
key: key,
prevErrors: this.state.errors
};
validator.validate(data, schema, options, function (nextErrors) {
_this3.setState({ errors: _extends({}, nextErrors) }, _this3._invokeCallback.bind(_this3, key, callback));
});
};
/* Clear all previous validations
*
* @return {void}
*/
Validation.prototype.clearValidations = function clearValidations(callback) {
return this.setState({
errors: {}
}, callback);
};
/* Check current validity for a specified key or entire form.
*
* @param {?String} key to check validity (entire form if undefined).
* @return {Boolean}.
*/
Validation.prototype.isValid = function isValid(key) {
return validator.isValid(this.state.errors, key);
};
/* Private method that handles executing users callback on validation
*
* @param {Object} errors object keyed on data field names.
* @param {Function} error-first callback containing the validation errors if any.
*/
Validation.prototype._invokeCallback = function _invokeCallback(key, callback) {
if (typeof callback !== 'function') {
return;
}
if (this.isValid(key)) {
callback();
} else {
callback(this.state.errors);
}
};
Validation.prototype.render = function render() {
return _react2.default.createElement(WrappedComponent, _extends({
ref: 'component',
errors: this.state.errors,
validate: this.validate,
isValid: this.isValid,
getValidationMessages: this.getValidationMessages,
clearValidations: this.clearValidations,
handleValidation: this.handleValidation
}, this.props));
};
return Validation;
}(_react2.default.Component);
Validation.displayName = 'Validation(' + (0, _reactDisplayName2.default)(WrappedComponent) + ')';
return Validation;
};
}
;