mirror of
https://github.com/strapi/strapi.git
synced 2025-12-02 01:52:21 +00:00
Created inputsdValidations utils
Refacto input s validation logic. Fix input s initial value bug when the input is required
This commit is contained in:
parent
1e935ccddd
commit
7db50ab6e1
@ -15,6 +15,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputAddon from 'components/InputAddon';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputAddonWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
@ -24,7 +27,7 @@ class InputAddonWithErrors extends React.Component { // eslint-disable-line reac
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -35,6 +38,11 @@ class InputAddonWithErrors extends React.Component { // eslint-disable-line reac
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -50,7 +58,7 @@ class InputAddonWithErrors extends React.Component { // eslint-disable-line reac
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -135,48 +143,6 @@ class InputAddonWithErrors extends React.Component { // eslint-disable-line reac
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'maxLength': {
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'minLength': {
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'regex': {
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputAddonWithErrors.defaultProps = {
|
||||
|
||||
@ -13,150 +13,134 @@ import cn from 'classnames';
|
||||
import Label from 'components/Label';
|
||||
import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputDate from 'components/InputDate';
|
||||
import InputDate from 'components/InputDate';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputDateWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
state = { errors: [], hasInitialValue: false };
|
||||
state = { errors: [], hasInitialValue: false };
|
||||
|
||||
componentDidMount() {
|
||||
const { value, errors } = this.props;
|
||||
componentDidMount() {
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Display input error if it already has some
|
||||
if (!isEmpty(errors)) {
|
||||
this.setState({ errors });
|
||||
}
|
||||
}
|
||||
// Display input error if it already has some
|
||||
if (!isEmpty(errors)) {
|
||||
this.setState({ errors });
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
const errors = isEmpty(nextProps.errors) ? [] : nextProps.errors;
|
||||
this.setState({ errors });
|
||||
}
|
||||
}
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
/**
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
const errors = isEmpty(nextProps.errors) ? [] : nextProps.errors;
|
||||
this.setState({ errors });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the errors depending on the validations given to the input
|
||||
* @param {Object} target
|
||||
*/
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(get(target, 'value')) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(get(target, 'value')) || this.state.hasInitialValue) {
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
autoFocus,
|
||||
className,
|
||||
customBootstrapClass,
|
||||
deactivateErrorHighlight,
|
||||
disabled,
|
||||
errorsClassName,
|
||||
errorsStyle,
|
||||
inputClassName,
|
||||
inputDescription,
|
||||
inputDescriptionClassName,
|
||||
inputDescriptionStyle,
|
||||
inputStyle,
|
||||
label,
|
||||
labelClassName,
|
||||
labelStyle,
|
||||
name,
|
||||
noErrorsDescription,
|
||||
onBlur,
|
||||
onChange,
|
||||
onFocus,
|
||||
placeholder,
|
||||
style,
|
||||
tabIndex,
|
||||
value,
|
||||
} = this.props;
|
||||
const handleBlur = isFunction(onBlur) ? onBlur : this.handleBlur;
|
||||
render() {
|
||||
const {
|
||||
autoFocus,
|
||||
className,
|
||||
customBootstrapClass,
|
||||
deactivateErrorHighlight,
|
||||
disabled,
|
||||
errorsClassName,
|
||||
errorsStyle,
|
||||
inputClassName,
|
||||
inputDescription,
|
||||
inputDescriptionClassName,
|
||||
inputDescriptionStyle,
|
||||
inputStyle,
|
||||
label,
|
||||
labelClassName,
|
||||
labelStyle,
|
||||
name,
|
||||
noErrorsDescription,
|
||||
onBlur,
|
||||
onChange,
|
||||
onFocus,
|
||||
placeholder,
|
||||
style,
|
||||
tabIndex,
|
||||
value,
|
||||
} = this.props;
|
||||
const handleBlur = isFunction(onBlur) ? onBlur : this.handleBlur;
|
||||
|
||||
let spacer = !isEmpty(inputDescription) ? <div className={styles.spacer} /> : <div />;
|
||||
let spacer = !isEmpty(inputDescription) ? <div className={styles.spacer} /> : <div />;
|
||||
|
||||
if (!noErrorsDescription && !isEmpty(this.state.errors)) {
|
||||
spacer = <div />;
|
||||
}
|
||||
if (!noErrorsDescription && !isEmpty(this.state.errors)) {
|
||||
spacer = <div />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
!isEmpty(customBootstrapClass) && customBootstrapClass || 'col-md-4',
|
||||
styles.containerDate,
|
||||
!isEmpty(className) && className,
|
||||
)}
|
||||
style={style}
|
||||
>
|
||||
<Label
|
||||
className={labelClassName}
|
||||
htmlFor={name}
|
||||
message={label}
|
||||
style={labelStyle}
|
||||
/>
|
||||
<InputDate
|
||||
autoFocus={autoFocus}
|
||||
className={inputClassName}
|
||||
disabled={disabled}
|
||||
deactivateErrorHighlight={deactivateErrorHighlight}
|
||||
error={!isEmpty(this.state.errors)}
|
||||
name={name}
|
||||
onBlur={handleBlur}
|
||||
onChange={onChange}
|
||||
onFocus={onFocus}
|
||||
placeholder={placeholder}
|
||||
style={inputStyle}
|
||||
tabIndex={tabIndex}
|
||||
value={value}
|
||||
/>
|
||||
<InputDescription
|
||||
className={inputDescriptionClassName}
|
||||
message={inputDescription}
|
||||
style={inputDescriptionStyle}
|
||||
/>
|
||||
<InputErrors
|
||||
className={errorsClassName}
|
||||
errors={!noErrorsDescription && this.state.errors || []}
|
||||
style={errorsStyle}
|
||||
/>
|
||||
{spacer}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
return (
|
||||
<div className={cn(
|
||||
!isEmpty(customBootstrapClass) && customBootstrapClass || 'col-md-4',
|
||||
styles.containerDate,
|
||||
!isEmpty(className) && className,
|
||||
)}
|
||||
style={style}
|
||||
>
|
||||
<Label
|
||||
className={labelClassName}
|
||||
htmlFor={name}
|
||||
message={label}
|
||||
style={labelStyle}
|
||||
/>
|
||||
<InputDate
|
||||
autoFocus={autoFocus}
|
||||
className={inputClassName}
|
||||
disabled={disabled}
|
||||
deactivateErrorHighlight={deactivateErrorHighlight}
|
||||
error={!isEmpty(this.state.errors)}
|
||||
name={name}
|
||||
onBlur={handleBlur}
|
||||
onChange={onChange}
|
||||
onFocus={onFocus}
|
||||
placeholder={placeholder}
|
||||
style={inputStyle}
|
||||
tabIndex={tabIndex}
|
||||
value={value}
|
||||
/>
|
||||
<InputDescription
|
||||
className={inputDescriptionClassName}
|
||||
message={inputDescription}
|
||||
style={inputDescriptionStyle}
|
||||
/>
|
||||
<InputErrors
|
||||
className={errorsClassName}
|
||||
errors={!noErrorsDescription && this.state.errors || []}
|
||||
style={errorsStyle}
|
||||
/>
|
||||
{spacer}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
InputDateWithErrors.defaultProps = {
|
||||
|
||||
@ -15,6 +15,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputEmail from 'components/InputEmail';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputEmailWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
@ -24,7 +27,7 @@ class InputEmailWithErrors extends React.Component { // eslint-disable-line reac
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -35,6 +38,11 @@ class InputEmailWithErrors extends React.Component { // eslint-disable-line reac
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -50,7 +58,7 @@ class InputEmailWithErrors extends React.Component { // eslint-disable-line reac
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations, 'email');
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -131,53 +139,6 @@ class InputEmailWithErrors extends React.Component { // eslint-disable-line reac
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const emailRegex = new RegExp(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'maxLength': {
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'minLength': {
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'regex': {
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (!emailRegex.test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.email' });
|
||||
}
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputEmailWithErrors.defaultProps = {
|
||||
|
||||
@ -9,6 +9,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputNumber from 'components/InputNumber';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputNumberWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
@ -18,7 +21,7 @@ class InputNumberWithErrors extends React.Component { // eslint-disable-line rea
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -29,6 +32,11 @@ class InputNumberWithErrors extends React.Component { // eslint-disable-line rea
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -44,7 +52,7 @@ class InputNumberWithErrors extends React.Component { // eslint-disable-line rea
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -127,48 +135,6 @@ class InputNumberWithErrors extends React.Component { // eslint-disable-line rea
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'max': {
|
||||
if (parseInt(value, 10) > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.max' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'min': {
|
||||
if (parseInt(value, 10) < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.min' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'regex': {
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputNumberWithErrors.defaultProps = {
|
||||
|
||||
@ -15,6 +15,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputPassword from 'components/InputPassword';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputPasswordWithErrors extends React.Component {
|
||||
@ -24,7 +27,7 @@ class InputPasswordWithErrors extends React.Component {
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -35,6 +38,11 @@ class InputPasswordWithErrors extends React.Component {
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -50,7 +58,7 @@ class InputPasswordWithErrors extends React.Component {
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -120,48 +128,6 @@ class InputPasswordWithErrors extends React.Component {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'maxLength': {
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'minLength': {
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'regex': {
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputPasswordWithErrors.defaultProps = {
|
||||
|
||||
@ -15,6 +15,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputSearch from 'components/InputSearch';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputSearchWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
@ -24,7 +27,7 @@ class InputSearchWithErrors extends React.Component { // eslint-disable-line rea
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -35,6 +38,11 @@ class InputSearchWithErrors extends React.Component { // eslint-disable-line rea
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -50,7 +58,7 @@ class InputSearchWithErrors extends React.Component { // eslint-disable-line rea
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -131,48 +139,6 @@ class InputSearchWithErrors extends React.Component { // eslint-disable-line rea
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'maxLength': {
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'minLength': {
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'regex': {
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputSearchWithErrors.defaultProps = {
|
||||
|
||||
@ -9,6 +9,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputTextArea from 'components/InputTextArea';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputTextAreaWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
@ -18,7 +21,7 @@ class InputTextAreaWithErrors extends React.Component { // eslint-disable-line r
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -29,6 +32,11 @@ class InputTextAreaWithErrors extends React.Component { // eslint-disable-line r
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -44,7 +52,7 @@ class InputTextAreaWithErrors extends React.Component { // eslint-disable-line r
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -127,48 +135,6 @@ class InputTextAreaWithErrors extends React.Component { // eslint-disable-line r
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'maxLength': {
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'minLength': {
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'regex': {
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputTextAreaWithErrors.defaultProps = {
|
||||
|
||||
@ -9,6 +9,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputText from 'components/InputText';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputTextWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
@ -18,7 +21,7 @@ class InputTextWithErrors extends React.Component { // eslint-disable-line react
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -29,6 +32,11 @@ class InputTextWithErrors extends React.Component { // eslint-disable-line react
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -44,7 +52,7 @@ class InputTextWithErrors extends React.Component { // eslint-disable-line react
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -127,48 +135,6 @@ class InputTextWithErrors extends React.Component { // eslint-disable-line react
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'maxLength': {
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'minLength': {
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'regex': {
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputTextWithErrors.defaultProps = {
|
||||
|
||||
@ -38,7 +38,6 @@ const inputs = {
|
||||
};
|
||||
|
||||
function InputsIndex(props) {
|
||||
const inputValue = props.type === 'checkbox' || props.type === 'toggle' ? props.value || false : props.value || '';
|
||||
const type = props.type && !isEmpty(props.addon) ? 'addon' : props.type;
|
||||
const inputValue = props.type === 'checkbox' || props.type === 'toggle' ? props.value || false : props.value || '';
|
||||
const Input = inputs[type] ? inputs[type] : DefaultInputError;
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
import { includes, mapKeys, reject } from 'lodash';
|
||||
/**
|
||||
* [validateInput description]
|
||||
* @param {String || Number} value Input's value
|
||||
* @param {Object} inputValidations
|
||||
* @param {String} [type='text'] Optionnal: the input's type only for email
|
||||
* @return {Array} Array of errors to be displayed
|
||||
*/
|
||||
const validateInput = (value, inputValidations = {}, type = 'text') => {
|
||||
let errors = [];
|
||||
|
||||
const emailRegex = new RegExp(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);
|
||||
// handle i18n
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
|
||||
mapKeys(inputValidations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'max':
|
||||
if (parseInt(value, 10) > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.max' });
|
||||
}
|
||||
break;
|
||||
case 'maxLength':
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
case 'min':
|
||||
if (parseInt(value, 10) < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.min' });
|
||||
}
|
||||
break;
|
||||
case 'minLength':
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
case 'required':
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
case 'regex':
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (type === 'email' && !emailRegex.test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.email' });
|
||||
}
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
export default validateInput;
|
||||
Loading…
x
Reference in New Issue
Block a user