I have a created a TextInput component which serves as both textbox or textarea along with validation When I create a TextInput tag with handleChange event, it is not firing.
<TextInput
ref="c1"
className="form-control"
type="textarea"
rows={4}
required
errorMessage="c1is invalid"
emptyMessage="c1is required"
handleChange={this.handleSuggestedReplyChange}
value={this.state.answeredBy || ''}
/>
The handleSuggestedReplyChange is an event which is written in the template page.
import React from 'react';
import composeValidationComponent from './ValidationComponent';
class TextInput extends React.Component {
constructor(props, context) {
super(props, context);
this.displayName = 'TextInput';
}
render() {
if (this.props.type === 'textarea') {
return (
<textarea
className={this.props.className}
rows={this.props.rows}
onChange={this.props.handleChange}
value={this.props.value}
readOnly={this.props.readOnly}
/>
);
}
return (
<input
type={this.props.type}
placeholder={this.props.placeholder}
className={this.props.className}
onChange={this.props.handleChange}
value={this.props.value}
readOnly={this.props.readOnly}
/>
);
}
}
TextInput.propTypes = {
type: React.PropTypes.string,
placeholder: React.PropTypes.string,
className: React.PropTypes.string,
value: React.PropTypes.string,
rows: React.PropTypes.number,
readOnly: React.PropTypes.bool,
handleChange: React.PropTypes.func,
};
export default composeValidationComponent(TextInput, 'TextInput');
import React from 'react';
import InputError from './InputError';
export default function composeValidationComponent(Component, DisplayName) {
class ValidationComponent extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
isEmpty: true,
//value: '',
valid: false,
errorMessage: '',
errorVisible: false
};
this.handleChange = this.handleChange.bind(this);
this.validation = this.validation.bind(this);
}
handleChange(event) {
// set the state in order for it to show up on the form
this.setState({
value: event.target.value
});
}
validation(value, valid) {
let isValid = valid;
//The valid variable is optional, and true if not passed in:
if (typeof valid === 'undefined') {
isValid = true;
}
let message = '';
let errorVisible = false;
//we know how to validate text fields based on information passed through props
if (!isValid) {
// NOTE: This should never be reached since we don't handle onBlur
//This happens when the user leaves the field, but it is not valid
//(we do final validation in the parent component, then pass the result
//here for display)
message = this.props.errorMessage;
errorVisible = true;
} else if (this.props.required && value.length === 0) {
//this happens when we have a required field with no text entered
//in this case, we want the "emptyMessage" error message
message = this.props.emptyMessage;
isValid = false;
errorVisible = true;
}
//setting the state will update the display,
//causing the error message to display if there is one.
this.setState({
value,
isEmpty: message === this.props.emptyMessage,
isValid,
errorMessage: message,
errorVisible
});
return isValid;
}
render() {
return (
<div>
<Component
{ ...this.props }
{ ...this.state }
handleChange={ this.handleChange }
validation={ this.validation }
/>
<InputError
visible={this.state.errorVisible}
errorMessage={this.state.errorMessage}
/>
</div>
);
}
}
ValidationComponent.propTypes = {
className: React.PropTypes.string,
name: React.PropTypes.string,
errorMessage: React.PropTypes.string,
emptyMessage: React.PropTypes.string,
required: React.PropTypes.bool,
readOnly: React.PropTypes.bool
};
return ValidationComponent;
}
I think I see the issue. I'm assuming you're expecting this.handleSuggestedReplyChange
to be called, but it is not.
This is because of the validation class wrapper. In the render method, you are passing all props and state to the component, and then specifying a custom handleChange. That prop you provided, will override the one passed in via this.props.
To fix this, I would suggest you call this.props.handleChange()
inside ValidationComponent's handleChange.
handleChange(event) {
// set the state in order for it to show up on the form
this.setState({
value: event.target.value
});
if (this.props.handleChange) {
this.props.handleChange(event.target.value);
}
}