Skip to content

Instantly share code, notes, and snippets.

@gilbarbara
Created January 23, 2017 12:13
Show Gist options
  • Save gilbarbara/89f8af872d812688074a3076118c668b to your computer and use it in GitHub Desktop.
Save gilbarbara/89f8af872d812688074a3076118c668b to your computer and use it in GitHub Desktop.
import React from 'react';
import { autobind } from 'core-decorators';
import { HOC } from 'formsy-react';
import { Input } from 'components/Input';
@autobind
export class InputValidate extends React.Component {
constructor(props) {
super(props);
this.state = {
focused: false,
};
}
static propTypes = {
autocomplete: React.PropTypes.string,
autofocus: React.PropTypes.bool,
checked: React.PropTypes.bool,
children: React.PropTypes.node,
disabled: React.PropTypes.bool,
getErrorMessage: React.PropTypes.func,
getValue: React.PropTypes.func,
groupClassName: React.PropTypes.string,
hasFeedback: React.PropTypes.bool,
help: React.PropTypes.string,
iconAfter: React.PropTypes.oneOfType([
React.PropTypes.element,
React.PropTypes.bool,
]),
iconBefore: React.PropTypes.oneOfType([
React.PropTypes.element,
React.PropTypes.bool,
]),
isValidValue: React.PropTypes.func,
label: React.PropTypes.string,
labelClassName: React.PropTypes.string,
name: React.PropTypes.string.isRequired,
onBlur: React.PropTypes.func,
onChange: React.PropTypes.func,
onFocus: React.PropTypes.func,
placeholder: React.PropTypes.string,
readonly: React.PropTypes.bool,
reference: React.PropTypes.string,
referenceType: React.PropTypes.string,
setValue: React.PropTypes.func,
showError: React.PropTypes.func,
type: React.PropTypes.string.isRequired,
validationIcon: React.PropTypes.bool,
validations: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.object,
]),
validationType: React.PropTypes.string,
value: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number,
]),
wrapperClassName: React.PropTypes.string,
};
static defaultProps = {
autocomplete: 'on',
autofocus: false,
disabled: false,
hasFeedback: true,
help: '',
iconAfter: false,
iconBefore: false,
label: '',
labelClassName: '',
groupClassName: '',
wrapperClassName: '',
placeholder: '',
readonly: false,
type: 'text',
validationIcon: true,
validationType: 'blur',
value: '',
};
componentDidMount() {
const { referenceType, setValue, value } = this.props;
/* istanbul ignore else */
if (this.cpf) {
$(this.cpf.refs.input).mask('000.000.000-00', { reverse: false });
}
/* istanbul ignore else */
if (this.birthdate) {
$(this.birthdate.refs.input).mask('00/00/0000');
}
/* istanbul ignore else */
if (this.phone) {
const $input = $(this.phone.refs.input);
let maskBehavior;
if (referenceType === 'countryCode') {
maskBehavior = val => (val.replace(/\D/g, '').length === 13 ? '+00 (00) 00000-0000' : '+00 (00) 0000-00009');
} else {
maskBehavior = val => (val.replace(/\D/g, '').length === 11 ? '(00) 00000-0000' : '(00) 0000-00009');
}
/* istanbul ignore next */
$input.mask(maskBehavior, {
onKeyPress: (val, e, field, options) => {
field.mask(maskBehavior.apply({}, [val]), options);
},
});
}
setValue(value);
}
componentWillReceiveProps(nextProps) {
const { setValue, validations, value } = this.props;
/* istanbul ignore else */
if (nextProps.value !== value) {
setValue(nextProps.value);
}
/* istanbul ignore else */
if (nextProps.validations !== validations) {
this._validations = `${nextProps.validations},isValue`;
}
}
changeValue(element) {
const { reference, setValue } = this.props;
let value = element.value;
/* istanbul ignore else */
if (value) {
/* istanbul ignore else */
if (['cpf'].includes(reference)) {
value = $(element).cleanVal();
}
/* istanbul ignore else */
if (element.type === 'number') {
value = String(parseInt(value, 10));
}
}
setValue(value);
}
onFocus(event) {
const { isValidValue, onFocus } = this.props;
const value = event.target.value;
const isValid = isValidValue(value);
// event.target.readOnly = false; //eslint-disable-line no-param-reassign
// console.log('InputValidate:onFocus');
this.setState({
focused: true,
});
this.changeValue(event.target);
/* istanbul ignore else */
if (typeof onFocus === 'function') {
onFocus(event.target, isValid);
}
}
onBlur(event) {
const { isValidValue, onBlur, validationType } = this.props;
const value = event.target.value;
const isValid = isValidValue(value);
// console.log('InputValidate:onBlur', isValid);
this.setState({ focused: false });
/* istanbul ignore else */
if (validationType === 'blur') {
this.changeValue(event.target);
}
/* istanbul ignore else */
if (typeof onBlur === 'function') {
onBlur(event.target, isValid);
}
}
onChange(event) {
const { getErrorMessage, isValidValue, onChange, reference, setValue, validationType } = this.props;
let value = event.target.value;
/* istanbul ignore else */
if (['cpf'].includes(reference)) {
value = $(event.target).cleanVal();
}
const isValid = isValidValue(value);
/* istanbul ignore else */
if (validationType === 'change') {
this.changeValue(event.target);
} else if (isValid || !value || (getErrorMessage() && !isValid)) {
setValue(value);
}
/* istanbul ignore else */
if (typeof onChange === 'function') {
onChange(event.target, isValid);
}
}
render() {
const {
autocomplete,
autofocus,
checked,
children,
disabled,
getErrorMessage,
getValue,
groupClassName,
hasFeedback,
help,
iconAfter,
iconBefore,
isValidValue,
label,
labelClassName,
name,
placeholder,
readonly,
reference,
showError,
type,
validationIcon,
wrapperClassName,
} = this.props;
const hasValue = (getValue() && isValidValue(getValue()) ? 'success' : null);
const validateClass = showError() ? 'danger' : hasValue;
let otherProps;
if (['checkbox', 'radio'].includes(type)) {
otherProps = {
checked,
};
}
return (
<div className={['input-validate', wrapperClassName].join(' ').trim()}>
<Input
addonAfter={iconAfter}
addonBefore={iconBefore}
autocomplete={autocomplete}
autofocus={autofocus}
disabled={disabled}
groupClassName={groupClassName + (this.state.focused ? ' is-focused' : '')}
hasFeedback={hasFeedback}
help={help}
label={label}
labelClassName={labelClassName}
name={name}
onBlur={this.onBlur}
onChange={this.onChange}
onFocus={this.onFocus}
placeholder={placeholder}
readonly={readonly}
ref={c => (this[reference] = c)}
type={type}
validationClassName={validateClass}
validationFeedback={getErrorMessage()}
validationIcon={validationIcon}
value={getValue()}
{...otherProps}
>
{children}
</Input>
</div>
);
}
}
export default HOC(InputValidate);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment