@eixox/jetfuel-firebase-react
Version:
Our jetfuel lib to connect react to firebase
289 lines (274 loc) • 7.1 kB
JavaScript
import React from "react";
/**
* The e-mail regular expression;
*/
const email_regex = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
/**
* A generic multi purpose control class most useful for html inputs;
* This is a controlled component.
* Author: Rodrigo Portela
* Date: 2017-11-11
*/
export default class Xcontrol extends React.Component {
/**
* The default constructor;
* @param {*} props
*/
constructor(props) {
super(props);
this.state = {
value: props.value,
state: props.state,
message: props.message
};
}
/**
* Validates the required property of this control;
* Author: Rodrigo Portela
* Date: 2017-11-11
*/
validateRequired() {
if (
this.props.required &&
(!this.state.value ||
this.state.value === null ||
this.state.value === undefined ||
this.state.value === "")
) {
this.setState({
message: this.props.requiredMessage || "Por favor, preencha isso aqui.",
state: "error"
});
return false;
} else return true;
}
/**
* Validates the max length property of this control;
* Author: Rodrigo Portela
* Date: 2017-11-11
*/
validateMaxlength() {
if (
this.props.maxLength &&
this.props.maxLength > 1 &&
this.state.value &&
this.state.value.length > this.props.maxLength
) {
this.setState({
message:
this.props.maxLengthMessage ||
"Está muito grande. Só pode ter " +
this.props.maxLength +
" caracteres.",
state: "error"
});
return false;
} else return true;
}
/**
* Validates the min length property of a control;
* Author: Rodrigo Portela
* Date: 2017-11-11
*/
validateMinlength() {
if (
this.props.minLength &&
this.props.minLength > 1 &&
this.state.value &&
this.state.value.length < this.props.minLength
) {
this.setState({
message:
this.props.minLengthMessage ||
"Está muito pequeno, precisa ter pelo menos " +
this.props.minLength +
" caracteres.",
state: "error"
});
return false;
} else return true;
}
/**
* Validate the min answers property of a control;
* (The min answers property is usally the minimum size of an array of answers)
* Author: Rodrigo Portela
* Date: 2017-11-11
*/
validateMinAnswers() {
if (
this.props.minAnswers &&
this.props.minAnswers > 1 &&
this.state.value &&
this.state.value.length < this.props.minAnswers
) {
this.setState({
message:
this.props.minAnswersMessage ||
"Você precisa selecionar pelo menos " +
this.props.minAnswers +
" opções.",
state: "error"
});
return false;
} else return true;
}
/**
* Validates the max anwsers property of a control;
* (The max answers property is usualy the max size of an array of answers)
* Author: Rodrigo Portela
* Date: 2017-11-11
*/
validateMaxAnswers() {
if (
this.props.maxAnswers &&
this.props.maxAnswers > 1 &&
this.state.value &&
this.state.value.length > this.props.maxAnswers
) {
this.setState({
message:
this.props.maxAnswersMessage ||
"Você precisa selecionar no máximo " +
this.props.maxAnswers +
" opções.",
state: "error"
});
return false;
} else return true;
}
/**
* Validates the value of the control as an email;
* Author: Rodrigo Portela
* Date: 2017-11-11
*/
validateEmail() {
if (
this.props.type === "email" &&
this.state.value &&
this.state.value != null &&
!email_regex.test(this.state.value)
) {
this.setState({
message:
this.props.emailMessage || "Não é um endereço de e-mail válido.",
state: "error"
});
return false;
} else return true;
}
/**
* Validates the regex property of a control;
* Author: Rodrigo Portela
* Date: 2017-11-11
*/
validateRegex() {
if (
this.props.regex &&
this.props.regex != null &&
this.state.value &&
this.state.value != null &&
!this.props.regex.test(this.state.value)
) {
this.setState({
message: this.props.regexMessage || "Ops, formato inválido.",
state: "error"
});
return false;
} else return true;
}
/**
* Validates this control.
* Author: Rodrigo Portela
* Date: 2017-11-11
*/
validate() {
return (
this.validateRequired() &&
this.validateMaxlength() &&
this.validateMinlength() &&
this.validateMinAnswers() &&
this.validateMaxAnswers() &&
this.validateEmail() &&
this.validateRegex()
);
}
/**
* Applies any interceptor that might be present on this control;
* @param {*} value
*/
applyInterceptors(value) {
var iceptor = this.props.interceptor || this.props.interceptors;
if (iceptor && iceptor !== null && iceptor !== undefined) {
try {
if (iceptor instanceof Array) {
for (var i = 0; i < iceptor.length; i++) value = iceptor[i](value);
} else value = iceptor(value);
} catch (e) {
console.exception(e, iceptor);
}
}
return value;
}
/**
* Fires when a single line, multiline or single option input has it's value changed;
* Author: Rodrigo Portela
* Date: 2017-11-11
* @param {*} value
*/
onValueChange(value) {
this.setState({
value: this.applyInterceptors(value),
message: null,
state: "normal"
});
if (this.props.onChange) this.props.onChange(value);
}
/**
* Fires when a multi option is selected;
* Author: Rodrigo Portela
* Date: 2017-11-11
* @param {*} value
*/
onValueToggle(value) {
value = this.applyInterceptors(value);
var arrayValue = this.state.value;
if (!arrayValue || !(arrayValue instanceof Array)) {
arrayValue = [];
arrayValue.push(value);
} else {
var cindex = arrayValue.indexOf(value);
if (cindex >= 0) arrayValue.splice(cindex, 1);
else arrayValue.push(value);
}
this.setState({
value: arrayValue,
message: null,
state: "normal"
});
if (this.props.onChange) this.props.onChange(arrayValue);
}
/**
* Checks if the given option is present on the values array;
* Author: Rodrigo Portela
* Date: 2017-11-11
* @param {*} opt
*/
isValueSelected(opt) {
var av = this.state.value;
return av && av instanceof Array && av.indexOf(opt) >= 0;
}
/**
* Renders the control to the output;
* Author: Rodrigo Portela
* Date: 2017-11-11
*/
render() {
return this.props.renderer &&
this.props.renderer !== null &&
this.props.renderer !== undefined ? (
this.props.renderer.render(this)
) : (
<div>Please provide a renderer for this control.</div>
);
}
}