127 lines
3.9 KiB
JavaScript
Raw Normal View History

2017-07-10 17:55:46 +02:00
/**
*
* InputNumber
* Customization
* - deactivateErrorHighlight: bool
* allow the user to remove bootstrap class 'has-danger' on the inputText
* - customBootstrapClass : string
* overrides the default 'col-md-6' on the inputText
* - handleBlur: function
* overrides the default input validations
* - errors : array
* custom errors if set to false it deactivate error display
*
* Required
* - name : string
* - handleChange : function
* - value : string
* - validations : object
*
* Optionnal
* - description : input description
* - handleFocus : function
* - placeholder : string if set to "" nothing will display
2017-07-10 17:55:46 +02:00
*
*/
import React from 'react';
2017-07-12 18:12:07 +02:00
import { isEmpty, map, pick } from 'lodash';
2017-07-10 17:55:46 +02:00
import styles from './styles.scss';
class InputNumber extends React.Component { // eslint-disable-line react/prefer-stateless-function
constructor(props) {
super(props);
this.state = {
errors: false,
hasInitialValue: false,
2017-07-10 17:55:46 +02:00
};
}
componentDidMount() {
if (this.props.value && this.props.value.length !== '') {
this.setState({ hasInitialValue: true });
}
}
2017-07-10 17:55:46 +02:00
componentWillReceiveProps(nextProps) {
if (this.props.errors !== nextProps.errors) {
2017-07-11 15:42:54 +02:00
let errors = false;
2017-07-12 18:12:07 +02:00
if (isEmpty(nextProps.errors)) {
2017-07-11 15:42:54 +02:00
errors = nextProps.errors === true ? [] : false;
} else {
errors = nextProps.errors;
}
2017-07-10 17:55:46 +02:00
this.setState({ errors });
}
}
handleBlur = ({ target }) => {
// prevent error display if input is initially empty
if (target.value.length > 0 || this.state.hasInitialValue) {
// validates basic string validations
// add custom logic here such as alerts...
const errors = this.validate(target.value);
2017-07-11 15:42:54 +02:00
this.setState({ errors, hasInitialValue: true });
}
2017-07-10 17:55:46 +02:00
}
validate = (value) => {
2017-07-12 18:12:07 +02:00
const errors = !isEmpty(pick(this.props.validations, 'required')) && value.length > 0 ?
2017-07-10 17:55:46 +02:00
false : ['This field is required'];
return errors;
}
render() {
const inputValue = this.props.value || '';
// override default onBlur
const handleBlur = this.props.handleBlur || this.handleBlur;
// override bootStrapClass
const bootStrapClass = this.props.customBootstrapClass ? this.props.customBootstrapClass : 'col-md-4';
2017-07-10 17:55:46 +02:00
// set error class with override possibility
const bootStrapClassDanger = !this.props.deactivateErrorHighlight && this.state.errors ? 'has-danger' : '';
2017-07-10 17:55:46 +02:00
const placeholder = this.props.placeholder || `Change ${this.props.name} field`;
return (
<div className={`${styles.inputNumber} ${bootStrapClass} ${bootStrapClassDanger}`}>
2017-07-11 15:42:54 +02:00
<label htmlFor={this.props.name}>{this.props.name}</label>
2017-07-10 17:55:46 +02:00
<input
type="number"
2017-07-11 15:42:54 +02:00
name={this.props.name}
id={this.props.name}
value={inputValue}
2017-07-10 17:55:46 +02:00
onBlur={handleBlur}
onChange={this.props.handleChange}
onFocus={this.props.handleFocus}
className={`form-control ${this.state.errors? 'form-control-danger' : ''}`}
2017-07-10 17:55:46 +02:00
placeholder={placeholder}
/>
<small>{this.props.inputDescription}</small>
2017-07-12 18:12:07 +02:00
{map(this.state.errors, (error, key) => (
<div key={key} className="form-control-feedback">{error}</div>
2017-07-10 17:55:46 +02:00
))}
</div>
);
}
}
InputNumber.propTypes = {
2017-07-11 15:42:54 +02:00
customBootstrapClass: React.PropTypes.string,
deactivateErrorHighlight: React.PropTypes.bool,
2017-07-10 17:55:46 +02:00
errors: React.PropTypes.oneOfType([
React.PropTypes.bool,
React.PropTypes.array,
]),
2017-07-11 15:42:54 +02:00
handleBlur: React.PropTypes.func,
2017-07-10 17:55:46 +02:00
handleChange: React.PropTypes.func.isRequired,
handleFocus: React.PropTypes.func,
2017-07-10 17:55:46 +02:00
inputDescription: React.PropTypes.string,
name: React.PropTypes.string.isRequired,
placeholder: React.PropTypes.string,
2017-07-11 15:42:54 +02:00
validations: React.PropTypes.object.isRequired,
2017-07-10 17:55:46 +02:00
value: React.PropTypes.oneOfType([
React.PropTypes.number.isRequired,
React.PropTypes.string.isRequired,
]),
}
export default InputNumber;