From 8d7d0a93bfbc228b02a2df1d6e12dcc62867d4d5 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Sun, 22 May 2016 15:25:43 -0300 Subject: [PATCH] [Ivan Diaz] - OS-#10 - Add validations [skip ci] --- .../main-home/main-home-page-login-widget.js | 4 +- client/src/core-components/form.js | 73 ++++++++++++++----- client/src/core-components/input.js | 10 +-- client/src/data/i18n-data.js | 18 ++--- client/src/data/i18n-keys.js | 5 -- client/src/data/languages/en.js | 7 ++ client/src/data/languages/es.js | 7 ++ .../lib-app/validations/email-validator.js | 11 +++ .../validations/validations-factory.js | 16 ++++ client/src/lib-app/validations/validator.js | 13 ++++ 10 files changed, 122 insertions(+), 42 deletions(-) delete mode 100644 client/src/data/i18n-keys.js create mode 100644 client/src/data/languages/en.js create mode 100644 client/src/data/languages/es.js create mode 100644 client/src/lib-app/validations/email-validator.js create mode 100644 client/src/lib-app/validations/validations-factory.js create mode 100644 client/src/lib-app/validations/validator.js diff --git a/client/src/app/main/main-home/main-home-page-login-widget.js b/client/src/app/main/main-home/main-home-page-login-widget.js index 2f24cd34..e9315f4a 100644 --- a/client/src/app/main/main-home/main-home-page-login-widget.js +++ b/client/src/app/main/main-home/main-home-page-login-widget.js @@ -33,7 +33,7 @@ let MainHomePageLoginWidget = React.createClass({
- +
@@ -53,7 +53,7 @@ let MainHomePageLoginWidget = React.createClass({
- +
diff --git a/client/src/core-components/form.js b/client/src/core-components/form.js index a407602e..c1171073 100644 --- a/client/src/core-components/form.js +++ b/client/src/core-components/form.js @@ -1,35 +1,40 @@ -import React from 'react'; -import _ from 'lodash'; +const React = require('react'); +const _ = require('lodash'); -import {reactDFS, renderChildrenWithProps} from 'lib-core/react-dfs'; +const {reactDFS, renderChildrenWithProps} = require('lib-core/react-dfs'); +const ValidationFactory = require('lib-app/validations/validations-factory'); -import Input from 'core-components/input'; -import Checkbox from 'core-components/checkbox'; +const Input = require('core-components/input'); +const Checkbox = require('core-components/checkbox'); -let Form = React.createClass({ - - validations: {}, +const Form = React.createClass({ getInitialState() { return { - form: {} + form: {}, + validations: {}, + errors: {} } }, componentDidMount() { let formState = {}; + let validations = {}; - reactDFS(this.props.children, (child) => { + reactDFS(this.props.children, function (child) { if (child.type === Input) { formState[child.props.name] = child.props.value || ''; + validations[child.props.name] = ValidationFactory.getValidator(child.props.validation || 'DEFAULT'); } else if (child.type === Checkbox) { formState[child.props.name] = child.props.checked || false; + validations[child.props.name] = ValidationFactory.getValidator(child.props.validation || 'DEFAULT'); } - }); + }.bind(this)); this.setState({ - form: formState + form: formState, + validations: validations }); }, @@ -55,37 +60,65 @@ let Form = React.createClass({ if (type === Input || type === Checkbox) { let inputName = props.name; - this.validations[inputName] = props.validation; - additionalProps = { - onChange: this.handleInputChange.bind(this, inputName, type), - value: this.state.form[inputName] || props.value + ref: inputName, + value: this.state.form[inputName] || props.value, + error: this.state.errors[inputName], + onChange: this.handleInputChange.bind(this, inputName, type) } } return additionalProps; }, - handleSubmit (event) { + handleSubmit(event) { event.preventDefault(); - if (this.props.onSubmit) { + if (this.hasFormErrors()) { + this.focusFirstErrorField(); + } else if (this.props.onSubmit) { this.props.onSubmit(this.state.form); } }, handleInputChange(inputName, type, event) { let form = _.clone(this.state.form); + let errors = _.clone(this.state.errors); + let inputValue = event.target.value; - form[inputName] = event.target.value; + form[inputName] = inputValue; + errors[inputName] = this.state.validations[inputName].validate(inputValue, form); if (type === Checkbox) { form[inputName] = event.target.checked || false; } + console.log(errors); + this.setState({ - form: form + form: form, + errors: errors }); + }, + + hasFormErrors() { + return _.some(this.validateAllFields(), (error) => error); + }, + + focusFirstErrorField() { + let firstErrorField = this.getFirstErrorField(); + + if (firstErrorField) { + this.refs[firstErrorField].focus(); + } + }, + + getFirstErrorField() { + + }, + + validateAllFields: function () { + } }); diff --git a/client/src/core-components/input.js b/client/src/core-components/input.js index 06765483..78f742e4 100644 --- a/client/src/core-components/input.js +++ b/client/src/core-components/input.js @@ -1,12 +1,12 @@ -import React from 'react'; -import classNames from 'classnames'; -import _ from 'lodash'; +const React = require('react'); +const classNames = require('classnames'); +const _ = require('lodash'); -let Input = React.createClass({ +const Input = React.createClass({ propTypes: { value: React.PropTypes.string, - validation: React.PropTypes.func, + validation: React.PropTypes.string, onChange: React.PropTypes.func, inputType: React.PropTypes.string, password: React.PropTypes.bool diff --git a/client/src/data/i18n-data.js b/client/src/data/i18n-data.js index 34c7ad82..eafa26dd 100644 --- a/client/src/data/i18n-data.js +++ b/client/src/data/i18n-data.js @@ -1,15 +1,13 @@ -import keys from 'data/i18n-keys' +const englishLanguage = require('data/languages/en'); +const spanishLanguage = require('data/languages/es'); -let languages = [ - 'us', - 'es' -]; +const languages = { + 'us': englishLanguage, + 'es': spanishLanguage +}; - -let i18nData = function (key, lang) { - let langIndex = languages.indexOf(lang); - - return keys[key][langIndex]; +const i18nData = function (key, lang) { + return languages[lang][key]; }; export default i18nData diff --git a/client/src/data/i18n-keys.js b/client/src/data/i18n-keys.js deleted file mode 100644 index bdb5a198..00000000 --- a/client/src/data/i18n-keys.js +++ /dev/null @@ -1,5 +0,0 @@ -export default { - 'SUBMIT': ['Submit', 'Enviar'], - 'LOG_IN': ['Log in', 'Ingresar'], - 'SIGN_UP': ['Sign up', 'Registrarse'] -}; \ No newline at end of file diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js new file mode 100644 index 00000000..c7d9b592 --- /dev/null +++ b/client/src/data/languages/en.js @@ -0,0 +1,7 @@ +export default { + 'SUBMIT': 'Submit', + 'LOG_IN': 'Log in', + 'SIGN_UP': 'Sign up', + 'ERROR_EMPTY': 'Invalid value', + 'ERROR_EMAIL': 'Invalid email' +}; \ No newline at end of file diff --git a/client/src/data/languages/es.js b/client/src/data/languages/es.js new file mode 100644 index 00000000..8f565699 --- /dev/null +++ b/client/src/data/languages/es.js @@ -0,0 +1,7 @@ +export default { + 'SUBMIT': 'Enviar', + 'LOG_IN': 'Ingresar', + 'SIGN_UP': 'Registrarse', + 'ERROR_EMPTY': 'Valor invalido', + 'ERROR_EMAIL': 'Email invalido' +}; \ No newline at end of file diff --git a/client/src/lib-app/validations/email-validator.js b/client/src/lib-app/validations/email-validator.js new file mode 100644 index 00000000..e1b7cb52 --- /dev/null +++ b/client/src/lib-app/validations/email-validator.js @@ -0,0 +1,11 @@ +const Validator = require('lib-app/validations/validator'); + +class EmailValidator extends Validator { + + validate(value, form) { + if (!value.length) return this.getError('ERROR_EMPTY'); + if (value.indexOf('@') === -1) return this.getError('ERROR_EMAIL'); + } +} + +export default EmailValidator; \ No newline at end of file diff --git a/client/src/lib-app/validations/validations-factory.js b/client/src/lib-app/validations/validations-factory.js new file mode 100644 index 00000000..77c98652 --- /dev/null +++ b/client/src/lib-app/validations/validations-factory.js @@ -0,0 +1,16 @@ +const Validator = require('lib-app/validations/validator'); +const EmailValidator = require('lib-app/validations/email-validator'); + +let validators = { + 'DEFAULT': new Validator(), + 'EMAIL': new EmailValidator() +}; + +class ValidatorFactory { + + static getValidator(validatorKey) { + return validators[validatorKey]; + } +} + +export default ValidatorFactory; \ No newline at end of file diff --git a/client/src/lib-app/validations/validator.js b/client/src/lib-app/validations/validator.js new file mode 100644 index 00000000..62659891 --- /dev/null +++ b/client/src/lib-app/validations/validator.js @@ -0,0 +1,13 @@ +const i18n = require('lib-app/i18n'); + +class Validator { + validate(value, form) { + if (!value.length) return this.getError('ERROR_EMPTY'); + } + + getError(errorKey) { + return i18n(errorKey); + } +} + +export default Validator \ No newline at end of file