Reputation: 10182
I'm currently rendering input controls like so:
renderField = function({ input, label, name, type, meta: { touched, error, warning } }) {
return (
<FormGroup>
<FormControl {...input} type={type} placeholder={label} />
{touched && error && <span className="error-text">{error}</span>}
</FormGroup>
);
}
render() {
const { handleSubmit, pristine, error } = this.props;
return (
<form onSubmit={handleSubmit(this.onSubmit)} className="profile-form">
<Field name="first_name" component={this.renderField} type="text" label="First Name" />
<Field name="last_name" component={this.renderField} type="text" label="Last Name" />
<Field name="bio" component={this.renderField} type="text" label="Bio" />
...
<Button bsStyle="primary" type="submit" disabled={pristine}>Save Changes</Button>
</form>
);
}
I want to change the bio field to be a textarea control instead of an input. Is it possible to do this within my renderField
function. I'd like to do it there instead of having to replicate for another function such as renderTextArea
since that would duplicate a lot of the arguments and bootstrap markup.
I'm not seeing any examples of this in the docs or searches but maybe I'm thinking about it wrong.
Upvotes: 1
Views: 4792
Reputation: 958
You could also use Control
with FormControl
straightaway.
export const InputFieldComponent = ({
id,
type,
label,
fieldObject,
placeHolder,
maxLength,
srOnly,
messages, validators, onChange}: Props) => (
<FormGroup controlId={id} validationState={fieldObject.valid ? 'success' : 'error'>
<ControlLabel srOnly={srOnly}>{label}</ControlLabel>
<Control
model={`.${id}`}
type={type}
placeHolder={ placeHolder || label }
component={FormControl}
maxLength={maxLength}
validators={validators}
onChange={onChange}
>
<FormControl.Feedback> <FaCheck /> </FormControl.Feedback>
<Errors
show="touched"
model={`.${id}`}
wrapper={ (v) => <HelpBlock>{v}</HelpBlock> }
messages={messages}
/>
</FormGroup>
);
InputFieldComponent.defaultProps = {
messages: {},
srOnly: false,
type: 'text',
maxLength: 255
}
export default InputFieldComponent;
Upvotes: 0
Reputation: 10182
thanks to @elmeister for the comment to lead in the right direction. I was missing the componentClass prop, so on the bio field I just needed to change to
<Field name="bio" component={this.renderField} type="text" label="Bio" componentClass="textarea" />
and then in my renderField method I needed to add componentClass as an argument and add that prop to the FormControl
component. I didn't need to change input to field btw, i think componentClass just overrides it when passed in.
renderField = ({ input, label, name, type, componentClass, meta: { touched, error, warning } }) => {
return (
<FormGroup>
<ControlLabel>{label}</ControlLabel>
<FormControl {...input} componentClass={componentClass} type={type} placeholder={label} />
{touched && error && <span className="error-text">{error}</span>}
</FormGroup>
);
}
Upvotes: 1