formsy-react/src/Mixin.js

136 lines
3.7 KiB
JavaScript

module.exports = {
getInitialState: function () {
var value = 'value' in this.props ? this.props.value : '';
return {
_value: value,
_isValid: true,
_isPristine: true,
_pristineValue: value
};
},
componentWillMount: function () {
var configure = function () {
this.setValidations(this.props.validations, this.props.required);
this.props._attachToForm(this);
}.bind(this);
if (!this.props.name) {
throw new Error('Form Input requires a name property when used');
}
if (!this.props._attachToForm) {
return setTimeout(function () {
if (!this.isMounted()) return;
if (!this.props._attachToForm) {
throw new Error('Form Mixin requires component to be nested in a Form');
}
configure();
}.bind(this), 0);
}
configure();
},
// We have to make the validate method is kept when new props are added
componentWillReceiveProps: function (nextProps) {
nextProps._attachToForm = this.props._attachToForm;
nextProps._detachFromForm = this.props._detachFromForm;
nextProps._validate = this.props._validate;
nextProps._isValidValue = this.props._isValidValue;
nextProps._isFormDisabled = this.props._isFormDisabled;
this.setValidations(nextProps.validations, nextProps.required);
},
componentDidUpdate: function (prevProps, prevState) {
var isValueChanged = function () {
return (
this.props.value !== prevProps.value && (
this.state._value === prevProps.value ||
// Since undefined is converted to empty string we have to
// check that specifically
(this.state._value === '' && prevProps.value === undefined)
)
);
}.bind(this);
// If validations has changed or something outside changes
// the value, set the value again running a validation
if (prevProps.validations !== this.props.validations || isValueChanged()) {
var value = 'value' in this.props ? this.props.value : '';
this.setValue(value);
}
},
// Detach it when component unmounts
componentWillUnmount: function () {
this.props._detachFromForm(this);
},
setValidations: function (validations, required) {
// Add validations to the store itself as the props object can not be modified
this._validations = validations || '';
if (required) {
this._validations = validations ? validations + ',' : '';
this._validations += 'isValue';
}
},
// We validate after the value has been set
setValue: function (value) {
this.setState({
_value: value,
_isPristine: false
}, function () {
this.props._validate(this);
}.bind(this));
},
resetValue: function () {
this.setState({
_value: this.state._pristineValue,
_isPristine: true
}, function () {
this.props._validate(this);
});
},
getValue: function () {
return this.state._value;
},
hasValue: function () {
return this.state._value !== '';
},
getErrorMessage: function () {
return this.isValid() || this.showRequired() ? null : this.state._serverError || this.props.validationError;
},
isFormDisabled: function () {
return this.props._isFormDisabled();
},
isValid: function () {
return this.state._isValid;
},
isPristine: function () {
return this.state._isPristine;
},
isRequired: function () {
return !!this.props.required;
},
showRequired: function () {
return this.isRequired() && this.state._value === '';
},
showError: function () {
return !this.showRequired() && !this.state._isValid;
},
isValidValue: function (value) {
return this.props._isValidValue.call(null, this, value);
}
};