var utils = require('./utils.js'); var React = global.React || require('react'); var convertValidationsToObject = function (validations) { if (typeof validations === 'string') { return validations.split(/\,(?![^{\[]*[}\]])/g).reduce(function (validations, validation) { var args = validation.split(':'); var validateMethod = args.shift(); args = args.map(function (arg) { try { return JSON.parse(arg); } catch (e) { return arg; // It is a string if it can not parse it } }); if (args.length > 1) { throw new Error('Formsy does not support multiple args on string validations. Use object format of validations instead.'); } validations[validateMethod] = args.length ? args[0] : true; return validations; }, {}); } return validations || {}; }; module.exports = { getInitialState: function () { return { _value: this.props.value, _isRequired: false, _isValid: true, _isPristine: true, _pristineValue: this.props.value, _validationError: [], _externalError: null, _formSubmitted: false }; }, contextTypes: { formsy: React.PropTypes.object // What about required? }, getDefaultProps: function () { return { validationError: '', validationErrors: {} }; }, componentWillMount: function () { var configure = function () { this.setValidations(this.props.validations, this.props.required); // Pass a function instead? this.context.formsy.attachToForm(this); //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) { this.setValidations(nextProps.validations, nextProps.required); }, componentDidUpdate: function (prevProps) { // If the value passed has changed, set it. If value is not passed it will // internally update, and this will never run if (!utils.isSame(this.props.value, prevProps.value)) { this.setValue(this.props.value); } // If validations or required is changed, run a new validation if (!utils.isSame(this.props.validations, prevProps.validations) || !utils.isSame(this.props.required, prevProps.required)) { this.context.formsy.validate(this); } }, // Detach it when component unmounts componentWillUnmount: function () { this.context.formsy.detachFromForm(this); //this.props._detachFromForm(this); }, setValidations: function (validations, required) { // Add validations to the store itself as the props object can not be modified this._validations = convertValidationsToObject(validations) || {}; this._requiredValidations = required === true ? {isDefaultRequiredValue: true} : convertValidationsToObject(required); }, // We validate after the value has been set setValue: function (value) { this.setState({ _value: value, _isPristine: false }, function () { this.context.formsy.validate(this); //this.props._validate(this); }.bind(this)); }, resetValue: function () { this.setState({ _value: this.state._pristineValue, _isPristine: true }, function () { this.context.formsy.validate(this); //this.props._validate(this); }); }, getValue: function () { return this.state._value; }, hasValue: function () { return this.state._value !== ''; }, getErrorMessage: function () { var messages = this.getErrorMessages(); return messages.length ? messages[0] : null; }, getErrorMessages: function () { return !this.isValid() || this.showRequired() ? (this.state._externalError || this.state._validationError || []) : []; }, isFormDisabled: function () { return this.context.formsy.isFormDisabled(); //return this.props._isFormDisabled(); }, isValid: function () { return this.state._isValid; }, isPristine: function () { return this.state._isPristine; }, isFormSubmitted: function () { return this.state._formSubmitted; }, isRequired: function () { return !!this.props.required; }, showRequired: function () { return this.state._isRequired; }, showError: function () { return !this.showRequired() && !this.isValid(); }, isValidValue: function (value) { return this.context.formsy.isValidValue.call(null, this, value); //return this.props._isValidValue.call(null, this, value); } };