Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async validations #408

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3f828f6
Form(setInputValidationErrors): ignore fields not in validationErrors
LeoIannacone Nov 25, 2016
ff7b83b
Validate fields async (#2)
LeoIannacone Nov 29, 2016
2872d6a
Main: do not set state of umounted components
LeoIannacone Dec 2, 2016
6bf4a80
Main: return model on change
LeoIannacone Dec 7, 2016
318666e
Mixin: do not set state after unmounted
LeoIannacone Dec 28, 2016
127160e
Merge remote-tracking branch 'christianalfoni/master'
LeoIannacone Jun 27, 2017
617a140
Main: run form validation after all validation finished via Promise
LeoIannacone Aug 21, 2017
841b21f
Main: do not setState if component unmounted
LeoIannacone Aug 22, 2017
a8b8827
Fix setState for component
LeoIannacone Aug 22, 2017
e99ff3a
Skip validation where there is no need to validate.
Dec 22, 2020
4a1d91a
Merge pull request #5 from plentific/formsy-validation-fix
vonpo Dec 23, 2020
9148fd0
Add UNSAFE_ prefix to componentWillMount methods to remove deprecatio…
Jan 26, 2022
79d0e73
Merge pull request #6 from plentific/fix-componentwillmount-warning
Jan 26, 2022
51542af
change preparation script name to fix installation
Feb 4, 2022
e82d6f6
Merge pull request #7 from plentific/fix-componentwillmount-warning
Feb 4, 2022
a835a95
Use the prepack script
fbarbare Aug 28, 2024
34ea24b
Update package.json
fbarbare Aug 28, 2024
b6bc20c
Add sources to the repo
fbarbare Aug 28, 2024
d6996c8
Add sources to the repo
fbarbare Aug 28, 2024
156b7fc
Revert the script change in favor of pushing built files to the repo
fbarbare Aug 28, 2024
85b2a33
Merge pull request #8 from plentific/fb/update-package-manager
fbarbare Sep 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
node_modules
lib
33 changes: 33 additions & 0 deletions lib/Decorator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';

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 React = global.React || require('react');
var createReactClass = require('create-react-class');
var Mixin = require('./Mixin.js');
module.exports = function () {
return function (Component) {
return createReactClass({
mixins: [Mixin],
render: function render() {
return React.createElement(Component, _extends({
setValidations: this.setValidations,
setValue: this.setValue,
resetValue: this.resetValue,
getValue: this.getValue,
hasValue: this.hasValue,
getErrorMessage: this.getErrorMessage,
getErrorMessages: this.getErrorMessages,
isFormDisabled: this.isFormDisabled,
isValid: this.isValid,
isPristine: this.isPristine,
isFormSubmitted: this.isFormSubmitted,
isRequired: this.isRequired,
showRequired: this.showRequired,
showError: this.showError,
isValidValue: this.isValidValue
}, this.props));
}
});
};
};
44 changes: 44 additions & 0 deletions lib/HOC.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use strict';

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 React = global.React || require('react');
var createReactClass = require('create-react-class');
var Mixin = require('./Mixin.js');
module.exports = function (Component) {
return createReactClass({
displayName: 'Formsy(' + getDisplayName(Component) + ')',
mixins: [Mixin],

render: function render() {
var innerRef = this.props.innerRef;

var propsForElement = _extends({
setValidations: this.setValidations,
setValue: this.setValue,
resetValue: this.resetValue,
getValue: this.getValue,
hasValue: this.hasValue,
getErrorMessage: this.getErrorMessage,
getErrorMessages: this.getErrorMessages,
isFormDisabled: this.isFormDisabled,
isValid: this.isValid,
isPristine: this.isPristine,
isFormSubmitted: this.isFormSubmitted,
isRequired: this.isRequired,
showRequired: this.showRequired,
showError: this.showError,
isValidValue: this.isValidValue
}, this.props);

if (innerRef) {
propsForElement.ref = innerRef;
}
return React.createElement(Component, propsForElement);
}
});
};

function getDisplayName(Component) {
return Component.displayName || Component.name || (typeof Component === 'string' ? Component : 'Component');
}
180 changes: 180 additions & 0 deletions lib/Mixin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
'use strict';

var PropTypes = require('prop-types');
var utils = require('./utils.js');
var React = global.React || require('react');

var convertValidationsToObject = function convertValidationsToObject(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 getInitialState() {
return {
_value: this.props.value,
_isRequired: false,
_isValid: true,
_isPristine: true,
_pristineValue: this.props.value,
_validationError: [],
_externalError: null,
_formSubmitted: false
};
},
contextTypes: {
formsy: PropTypes.object // What about required?
},
getDefaultProps: function getDefaultProps() {
return {
validationError: '',
validationErrors: {}
};
},

UNSAFE_componentWillMount: function UNSAFE_componentWillMount() {
this.canSetValue = true;
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 componentWillReceiveProps(nextProps) {
this.setValidations(nextProps.validations, nextProps.required);
},

componentDidUpdate: function componentDidUpdate(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 componentWillUnmount() {
this.context.formsy.detachFromForm(this);
this.canSetValue = false;
//this.props._detachFromForm(this);
},

setValidations: function setValidations(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 setValue(value) {
if (!this.canSetValue) {
return;
}
this.setState({
_value: value,
_isPristine: false
}, function () {
this.context.formsy.validate(this);
//this.props._validate(this);
}.bind(this));
},
resetValue: function resetValue() {
this.setState({
_value: this.state._pristineValue,
_isPristine: true
}, function () {
this.context.formsy.validate(this);
//this.props._validate(this);
});
},
getValue: function getValue() {
return this.state._value;
},
hasValue: function hasValue() {
return this.state._value !== '';
},
getErrorMessage: function getErrorMessage() {
var messages = this.getErrorMessages();
return messages.length ? messages[0] : null;
},
getErrorMessages: function getErrorMessages() {
return !this.isValid() || this.showRequired() ? this.state._externalError || this.state._validationError || [] : [];
},
isFormDisabled: function isFormDisabled() {
return this.context.formsy.isFormDisabled();
//return this.props._isFormDisabled();
},
isValid: function isValid() {
return this.state._isValid;
},
isPristine: function isPristine() {
return this.state._isPristine;
},
isFormSubmitted: function isFormSubmitted() {
return this.state._formSubmitted;
},
isRequired: function isRequired() {
return !!this.props.required;
},
showRequired: function showRequired() {
return this.state._isRequired;
},
showError: function showError() {
return !this.showRequired() && !this.isValid();
},
isValidValue: function isValidValue(value) {
return this.context.formsy.isValidValue.call(null, this, value);
//return this.props._isValidValue.call(null, this, value);
}
};
Loading