diff --git a/packages/strapi-helper-plugin/lib/src/components/InputAddonWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputAddonWithErrors/index.js index 59ab395f20..396a156aba 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputAddonWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputAddonWithErrors/index.js @@ -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 ); } - - 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 = { diff --git a/packages/strapi-helper-plugin/lib/src/components/InputDateWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputDateWithErrors/index.js index ad21c2e685..aa35a6dc21 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputDateWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputDateWithErrors/index.js @@ -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) ?
:
; + let spacer = !isEmpty(inputDescription) ?
:
; - if (!noErrorsDescription && !isEmpty(this.state.errors)) { - spacer =
; - } + if (!noErrorsDescription && !isEmpty(this.state.errors)) { + spacer =
; + } - return ( -
-
- ); - } - - 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 ( +
+
+ ); + } } InputDateWithErrors.defaultProps = { diff --git a/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js index 35ba1deb9e..8e7903a30c 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js @@ -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
); } - - 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 = { diff --git a/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/index.js index 3abc7d999d..021b35f866 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/index.js @@ -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
); } - - 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 = { diff --git a/packages/strapi-helper-plugin/lib/src/components/InputPasswordWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputPasswordWithErrors/index.js index 77acca6641..5a692b8f2b 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputPasswordWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputPasswordWithErrors/index.js @@ -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 {
); } - - 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 = { diff --git a/packages/strapi-helper-plugin/lib/src/components/InputSearchWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputSearchWithErrors/index.js index 4b6e0d747f..81c734f4b8 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputSearchWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputSearchWithErrors/index.js @@ -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
); } - - 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 = { diff --git a/packages/strapi-helper-plugin/lib/src/components/InputTextAreaWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputTextAreaWithErrors/index.js index c3461c6038..1183bba0c2 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputTextAreaWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputTextAreaWithErrors/index.js @@ -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
); } - - 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 = { diff --git a/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/index.js index 0724d3d313..ba7aa8bcf1 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/index.js @@ -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
); } - - 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 = { diff --git a/packages/strapi-helper-plugin/lib/src/utils/inputsValidations.js b/packages/strapi-helper-plugin/lib/src/utils/inputsValidations.js new file mode 100644 index 0000000000..dda65e58e7 --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/utils/inputsValidations.js @@ -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; diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/Controller/index.js b/packages/strapi-plugin-users-permissions/admin/src/components/Controller/index.js index a25fb1af57..8d8dc7cb64 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/components/Controller/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/components/Controller/index.js @@ -10,7 +10,7 @@ import { get, map, some } from 'lodash'; import cn from 'classnames'; import { FormattedMessage } from 'react-intl'; -import InputCheckbox from 'components/InputCheckbox'; +import InputCheckbox from 'components/InputCheckboxPlugin'; import styles from './styles.scss'; class Controller extends React.Component { diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/InputCheckbox/index.js b/packages/strapi-plugin-users-permissions/admin/src/components/InputCheckboxPlugin/index.js similarity index 92% rename from packages/strapi-plugin-users-permissions/admin/src/components/InputCheckbox/index.js rename to packages/strapi-plugin-users-permissions/admin/src/components/InputCheckboxPlugin/index.js index 0c68f53240..7962b3babf 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/components/InputCheckbox/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/components/InputCheckboxPlugin/index.js @@ -1,6 +1,6 @@ /** * -* InputCheckbox +* InputCheckboxPlugin * */ @@ -10,7 +10,7 @@ import cn from 'classnames'; import styles from './styles.scss'; -class InputCheckbox extends React.Component { // eslint-disable-line react/prefer-stateless-function +class InputCheckboxPlugin extends React.Component { // eslint-disable-line react/prefer-stateless-function state = { showBackground: false, showCog: false }; componentWillReceiveProps(nextProps) { @@ -91,19 +91,19 @@ class InputCheckbox extends React.Component { // eslint-disable-line react/prefe } } -InputCheckbox.contextTypes = { +InputCheckboxPlugin.contextTypes = { onChange: PropTypes.func.isRequired, resetShouldDisplayPoliciesHint: PropTypes.func.isRequired, setInputPoliciesPath: PropTypes.func.isRequired, setShouldDisplayPolicieshint: PropTypes.func.isRequired, }; -InputCheckbox.defaultProps = { +InputCheckboxPlugin.defaultProps = { label: '', value: false, }; -InputCheckbox.propTypes = { +InputCheckboxPlugin.propTypes = { inputSelected: PropTypes.string.isRequired, isOpen: PropTypes.bool.isRequired, label: PropTypes.string, @@ -112,4 +112,4 @@ InputCheckbox.propTypes = { value: PropTypes.bool, }; -export default InputCheckbox; +export default InputCheckboxPlugin; diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/InputCheckbox/styles.scss b/packages/strapi-plugin-users-permissions/admin/src/components/InputCheckboxPlugin/styles.scss similarity index 100% rename from packages/strapi-plugin-users-permissions/admin/src/components/InputCheckbox/styles.scss rename to packages/strapi-plugin-users-permissions/admin/src/components/InputCheckboxPlugin/styles.scss diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/InputSearch/index.js b/packages/strapi-plugin-users-permissions/admin/src/components/InputSearchContainer/index.js similarity index 79% rename from packages/strapi-plugin-users-permissions/admin/src/components/InputSearch/index.js rename to packages/strapi-plugin-users-permissions/admin/src/components/InputSearchContainer/index.js index 76cd8e19da..e663988892 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/components/InputSearch/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/components/InputSearchContainer/index.js @@ -1,6 +1,6 @@ /** * -* InputSearch +* InputSearchContainer * */ @@ -10,15 +10,17 @@ import { findIndex, has, includes, isEmpty, map, toLower } from 'lodash'; import cn from 'classnames'; import PropTypes from 'prop-types'; +import Label from 'components/Label'; import InputSearchLi from 'components/InputSearchLi'; import styles from './styles.scss'; -class InputSearch extends React.Component { // eslint-disable-line react/prefer-stateless-function +class InputSearchContainer extends React.Component { // eslint-disable-line react/prefer-stateless-function state = { errors: [], filteredUsers: this.props.values, isAdding: false, + isFocused: false, users: this.props.values, value: '', autoFocus: false, @@ -38,6 +40,8 @@ class InputSearch extends React.Component { // eslint-disable-line react/prefer- } } + handleBlur = () => this.setState({ isFocused: !this.state.isFocused }); + handleChange = ({ target }) => { const filteredUsers = isEmpty(target.value) ? this.state.users @@ -54,6 +58,8 @@ class InputSearch extends React.Component { // eslint-disable-line react/prefer- this.setState({ value: target.value, filteredUsers }); } + handleFocus = () => this.setState({ isFocused: !this.state.isFocused }); + handleClick = (item) => { if (this.state.isAdding) { const id = has(item, '_id') ? '_id' : 'id'; @@ -76,18 +82,18 @@ class InputSearch extends React.Component { // eslint-disable-line react/prefer- render() { return (
- +