zent
Version:
一套前端设计语言和基于React的实现
409 lines (328 loc) • 12 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _extends3 = require('babel-runtime/helpers/extends');
var _extends4 = _interopRequireDefault(_extends3);
var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _react = require('react');
var _isEqual = require('lodash/isEqual');
var _isEqual2 = _interopRequireDefault(_isEqual);
var _omit = require('lodash/omit');
var _omit2 = _interopRequireDefault(_omit);
var _assign = require('lodash/assign');
var _assign2 = _interopRequireDefault(_assign);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _utils = require('./utils');
var _unknownProps = require('./unknownProps');
var _unknownProps2 = _interopRequireDefault(_unknownProps);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var Field = function (_Component) {
(0, _inherits3['default'])(Field, _Component);
// validationError为默认错误提示
// validationErrors为指定校验规则所对应的错误提示
function Field(props, context) {
(0, _classCallCheck3['default'])(this, Field);
var _this = (0, _possibleConstructorReturn3['default'])(this, (Field.__proto__ || Object.getPrototypeOf(Field)).call(this, props, context));
_initialiseProps.call(_this);
if (!context.zentForm) {
throw new Error('Field must be in zent-form');
}
_this.state = {
_value: props.value,
_isValid: true,
_isDirty: false,
_isValidating: false,
_initialValue: props.value,
_validationError: [],
_externalError: null,
_asyncValidated: false
};
_this._name = (0, _utils.prefixName)(context.zentForm, props.name);
_this._validations = props.validations || {};
return _this;
}
(0, _createClass3['default'])(Field, [{
key: 'shouldComponentUpdate',
value: function shouldComponentUpdate(nextProps, nextState) {
return !(0, _isEqual2['default'])(nextState, this.state) || !(0, _isEqual2['default'])(nextProps, this.props);
}
}, {
key: 'componentWillMount',
value: function componentWillMount() {
if (!this.props.name) {
throw new Error('Form Field requires a name property when used');
}
var zentForm = this.context.zentForm;
zentForm.attachToForm(this);
this._name = (0, _utils.prefixName)(zentForm, this.props.name);
if (this.context.zentForm.getSubFieldArray) {
var currentValue = this.context.zentForm.getSubFieldArray(this._name);
currentValue && this.setState({
_value: currentValue
});
}
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
if ('validations' in nextProps) {
this._validations = nextProps.validations;
}
this._name = (0, _utils.prefixName)(this.context.zentForm, nextProps.name);
if (this.context.zentForm.getSubFieldArray) {
var currentValue = this.context.zentForm.getSubFieldArray(this._name);
currentValue && this.setState({
_value: currentValue
});
}
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate(prevProps) {
// 支持props中的value动态更新
if (!(0, _isEqual2['default'])(this.props.value, prevProps.value)) {
this.setValue(this.props.value);
}
// 动态改变validation方法,重新校验
// if (!isEqual(this.props.validations, prevProps.validations)) {
// this.context.zentForm.validate(this);
// }
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.context.zentForm.detachFromForm(this);
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _props = this.props,
component = _props.component,
rest = (0, _objectWithoutProperties3['default'])(_props, ['component']);
var passableProps = this.processProps((0, _extends4['default'])({}, rest, {
ref: function ref(_ref) {
_this2.wrappedComponent = _ref;
},
name: this.getName(),
isTouched: this.isDirty(),
isDirty: this.isDirty(),
isValid: this.isValid(),
isAsyncValidated: this.isAsyncValidated,
isActive: this.isActive(),
value: this.format(this.getValue()),
error: this.getErrorMessage(),
errors: this.getErrorMessages(),
onChange: this.handleChange,
onBlur: this.handleBlur,
onFocus: this.handleFocus
}));
// 原生的标签不能传非标准属性进去
if (typeof component === 'string') {
return (0, _react.createElement)(component, (0, _extends4['default'])({}, (0, _omit2['default'])(passableProps, _unknownProps2['default'])));
}
return (0, _react.createElement)(component, passableProps);
}
}]);
return Field;
}(_react.Component); /* eslint-disable no-underscore-dangle */
Field.propTypes = {
name: _propTypes2['default'].string.isRequired,
component: _propTypes2['default'].oneOfType([_propTypes2['default'].func, _propTypes2['default'].string]).isRequired,
normalize: _propTypes2['default'].func,
format: _propTypes2['default'].func,
validationError: _propTypes2['default'].string,
validationErrors: _propTypes2['default'].object,
validateOnBlur: _propTypes2['default'].bool,
validateOnChange: _propTypes2['default'].bool,
clearErrorOnFocus: _propTypes2['default'].bool
};
Field.defaultProps = {
value: '',
validationError: '',
validationErrors: {},
validateOnBlur: true,
validateOnChange: true,
clearErrorOnFocus: true
};
Field.contextTypes = {
zentForm: _propTypes2['default'].object
};
var _initialiseProps = function _initialiseProps() {
var _this3 = this;
this.isDirty = function () {
return _this3.state._isDirty;
};
this.isValid = function () {
return _this3.state._isValid;
};
this.isValidating = function () {
return _this3.state._isValidating;
};
this.isActive = function () {
return _this3.state._active;
};
this.getInitialValue = function () {
return _this3.state._initialValue;
};
this.getValue = function () {
return _this3.state._value;
};
this.getName = function () {
return _this3._name;
};
this.isAsyncValidated = function () {
return _this3.state._asyncValidated;
};
this.setValue = function (value) {
var needValidate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
_this3.setState({
_value: value,
_isDirty: needValidate
}, function () {
_this3.context.zentForm.validate(_this3);
});
};
this.resetValue = function () {
_this3.setState({
_value: _this3.state._initialValue,
_isDirty: false
}, function () {
_this3.context.zentForm.validate(_this3);
});
};
this.setInitialValue = function (value) {
_this3.setState({
_value: value || _this3.state._initialValue,
_initialValue: value || _this3.state._initialValue,
_isDirty: false
}, function () {
_this3.context.zentForm.validate(_this3);
});
};
this.getWrappedComponent = function () {
return _this3.wrappedComponent;
};
this.getErrorMessage = function () {
var errors = _this3.getErrorMessages();
return errors.length ? errors[0] : null;
};
this.getErrorMessages = function () {
var _state = _this3.state,
_externalError = _state._externalError,
_validationError = _state._validationError;
return !_this3.isValid() ? _externalError || _validationError || [] : [];
};
this.normalize = function (value) {
var normalize = _this3.props.normalize;
if (!normalize) {
return value;
}
var previousValues = _this3.context.zentForm.getFormValues();
var previousValue = _this3.getValue();
var nextValues = (0, _extends4['default'])({}, previousValues, (0, _defineProperty3['default'])({}, _this3.getName(), value));
return normalize(value, previousValue, nextValues, previousValues);
};
this.format = function (value) {
var format = _this3.props.format;
if (!format) {
return value;
}
return format(value);
};
this.handleChange = function (event) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { merge: false };
var _props2 = _this3.props,
onChange = _props2.onChange,
validateOnChange = _props2.validateOnChange;
var previousValue = _this3.getValue();
var currentValue = options.merge ? (0, _utils.getCurrentValue)((0, _utils.getValue)(event), previousValue) : (0, _utils.getValue)(event);
var newValue = _this3.normalize(currentValue);
var preventSetValue = false;
// 在传入的onChange中可以按需阻止更新value值
if (onChange) {
onChange(event, newValue, previousValue, function () {
return preventSetValue = true;
});
}
if (!preventSetValue) {
_this3.setValue(newValue, validateOnChange);
_this3.context.zentForm.onChangeFieldArray && _this3.context.zentForm.onChangeFieldArray(_this3._name, newValue);
}
};
this.handleFocus = function (event) {
var _props3 = _this3.props,
onFocus = _props3.onFocus,
clearErrorOnFocus = _props3.clearErrorOnFocus;
var data = {
_active: true
};
if (onFocus) {
onFocus(event);
}
if (clearErrorOnFocus) {
(0, _assign2['default'])(data, {
_isValid: true,
_validationError: [],
_externalError: null
});
}
_this3.setState(data);
};
this.handleBlur = function (event) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { merge: false };
var _props4 = _this3.props,
onBlur = _props4.onBlur,
asyncValidation = _props4.asyncValidation,
validateOnBlur = _props4.validateOnBlur;
var previousValue = _this3.getValue();
var currentValue = options.merge ? (0, _utils.getCurrentValue)((0, _utils.getValue)(event), previousValue) : (0, _utils.getValue)(event);
var newValue = _this3.normalize(currentValue);
var preventSetValue = false;
if (onBlur) {
onBlur(event, newValue, previousValue, function () {
return preventSetValue = true;
});
}
_this3.setState({
_active: false
});
if (!preventSetValue) {
_this3.setValue(newValue, validateOnBlur);
if (asyncValidation) {
_this3.context.zentForm.asyncValidate(_this3, newValue);
}
}
};
this.processProps = function (props) {
var type = props.type,
value = props.value,
rest = (0, _objectWithoutProperties3['default'])(props, ['type', 'value']);
if (type === 'checkbox') {
return (0, _extends4['default'])({}, rest, {
checked: !!value,
type: type
});
}
if (type === 'file') {
return (0, _extends4['default'])({}, rest, {
type: type
});
}
return props;
};
};
exports['default'] = Field;