I am trying to create a form with redux-form however I've run into a problem where when I check 1 of my checkboxes they all get checked.
I've created my checkboxes in a form element which gets returned like this:
<div>
<label>Content Type</label>
{contentTypes.map(type=> {
return(
<Field
label={type.name}
name='content-type'
component={this.renderField}
content_type={type.type}
type='checkbox'
value='text'
/>
)
})}
</div>
the renderField function looks like this:
renderField({label, type, value, input, content_type}) {
return(
<div className='form-group'>
<label>{label}</label>
<input
{...input}
className='form-control'
type={type}
value={content_type}
name={input.name}
/>
</div>
)
}
I swapped out value for content_type because everytime this runs value is undefined. I'm incredibly new to redux form so if I'm doing something beyond wrong please tell me.
name='content-type'
you need to give them unique names
Related
I am using a redux-form to submit data that user enters into a form-input to an api. The inputs of the redux-form are for editing the values of existing data in the form.So,what I want is to populate the input values of the form with the previous(existing) value which comes from the api.So,I used props to get the existing values and assign those values to the component state.And when the input changes, then I am changing the state for that input using setState. Now,the issue that I am facing is, since I am using redux-form, I am using Field component which comes from redux-form.So,this is how my render() method looks like:
render() {
const { handleSubmit } = this.props;
return (
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
<Field
label="Title for Post"
name="title"
component={this.renderField}
/>
<Field
label="Post Content"
name="body"
component={this.renderField}
/>
);
}
And the renderField() method which is used above looks as shown below:
renderField(field) {
return(
<div className="title-design">
<label className="label-design"> {field.label} </label>
<input
type="text"
className="title-input"
{...field.input}
value={this.state.title}
onChange={this.onInputChange}
/>
<div className="text-help has-danger">
{field.meta.touched ? field.meta.error : ''}
</div>
</div>
)
}
And the onInputChange() method looks like:
onInputChange(event) {
this.setState({title: event.target.value})
}
So,since my input is in the renderField() method,so when I try to type something in the input,I do not see the state updated(because my renderField() method is used as a prop and it is not in the render method,so state is not being updated), and that is the reason why my input is not working properly.I mean I am not able to insert or delete values in the input.
But,if I use the input as shown below inside my render method,it works properly as expected.
<input
type="text"
className="title-input"
value={this.state.title}
onChange={this.onInputChange}
/>
But,I don't know how to pass the values with only input as shown above to a redux-form.So, how to proceed with this? Can anyone please help me figure out?Thanks in advance.
I have created a radio component but when clicked it does'nt show checked
here is the code
import React from 'react';
import classnames from 'classnames';
const RadioButton = (field) => {
const inputClasses = classnames('form-group has-feedback ',{
'has-error': field.meta.touched && field.meta.error,
});
console.log(field.input.value)
return(
<div className={inputClasses}>
<label className="radio-inline custom-radio nowrap">
<input
type="radio"
name={field.id}
onClick={e => field.input.onChange(field.val)}
/>
<span>{field.label}</span>
</label>
</div>
);
};
export default RadioButton;
here is the field:
<Field
component={RadioButton}
label ="Yes"
name="person.gender"
id="person.gender"
val={true}
/>
<Field
component={RadioButton}
label ="No"
name="person.gender"
id="person.gender"
val={false}
/>
So, how to get default value that is the initial value?
i want to get default value
<Field
component={RadioButton}
label ="No"
name="court.lit"
id="court.lit"
val={field.val}
defaultChecked={false}
/>
If you want to share the value from parent Field component you have to pass its value to the child. Then pass to RadioButton component.
<input
type="radio"
name={field.id}
value={field.val}
onClick={e => field.input.onChange(field.val)}
/>
but when clicked it does'nt show checked
You missed the value field
When using the redux-form library (which I assume is the case given your use of field.meta and field.input), you generally want to follow this pattern:
<input
{...field.input}
// your fields here
/>
This way, the onChange, value, and other fields are set for you.
After submitting a form I'm running validation and returning an array of errors. I'm using map to break the array into a group of objects, however, I'm having trouble figuring out how to use this.state.errors to show the errors on the form under the right FormControl field. Any help here would be great.
What errors look like after array is broken into
Object {name: "name.first", type: "required", value: undefined}
Object {name: "name.last", type: "required", value: undefined}
React component with form
getValidationState() {
var errors = this.state.errors;
if (!$.isEmptyObject(errors))
{
console.log("sefsefsdf");
errors.map(element => {
var errors = element;
});
}
if(errors) return 'error';
}
render() {
return (
<form onSubmit={this.handleSubmit.bind(this)}>
<FormGroup
validationState={this.getValidationState()} >
<FormControl
type="text"
name="firstName"
value={this.state.firstName}
placeholder="First name"
onChange={this.handleChange}
/>
<FormControl.Feedback />
{this.state.errors && <HelpBlock>{this.state.errors}</HelpBlock>}
</FormGroup>
<FormGroup >
<FormControl
type="text"
name="lastName"
value={this.state.lastName}
placeholder="Last name"
onChange={this.handleChange}
/>
</FormGroup>
<FormGroup >
<Button type="submit">
Save
</Button>
</FormGroup>
</form>
)
}
UPDATE
So unless I've misunderstood your question, you simply need to map your errors array. Like so:
{this.state.errors &&
<HelpBlock>
{this.state.errors.map((error, i) => <p key={i}>{error.value}</p>}
</HelpBlock>
}
This will return a <p> tag containing the error message. You can obviously change the element to something else.
For more about this, have a look at Array.map() over at MDN.
edit: If errors isn't an array initially, you'll get an error that map isn't a function. Make sure that the errors array is initialized as an array and nothing else. However, you can make an extra check in your code to assure it's an array:
{this.state.errors && this.state.errors.length &&
This doesn't only check that errors exists and is truthy, but that the property length exists as well. This will prevent errors on the common mistakes, however if errors for some reason is a string, the condition will be true as well. If you want a more solid solution, you could do:
{this.state.errors instanceof Array &&
I am building a redux form and I would like to create a »Retype Password« field which is rendered next to the password field. I have this code:
const renderRow = (field) => {
return (
<div className={`form-row ${field.type}`}>
<label>{field.label}</label>
<Field field={field} component={renderPassword} name={field.name} />
</div>
);
}
const renderPassword = ({field, input, meta: { error, touched }}) => {
return (
<div className="password-inputs-wrap">
<input type="password" {...input} />
<input type="password" {...input} name="password-retype" />
{touched && error && <RenderError error={error} />}
</div>
);
}
Right now this renders two password fields, but changing one, changes the other at the same time.
The renderRow is a bit simplified here, since the component for that field is not hard coded as show here. So this password field is an exception, since it consists of two <input>s. For all other fields, which consist of a single <input>/<select />, etc, it works fine.
How can I »decouple« this retype <input> from the first one?
You need two fields (two Fields).
I'd like to confirm if this structure is right.
I need to set default value for the checkbox, so I've used the checked={input.value}. I also need to set it to be disabled, then I've passed the disabled prop:
// Using the Checkbox component
<Field
name="completed"
label="Completed"
disabled={this.props.disableCompleted}
component={Checkbox}
/>
function Checkbox({ input, label, disabled }) {
return (
<div className="form-group">
<label className="mt-checkbox">
<input
type="checkbox"
disabled={disabled}
checked={input.value}
{...input} /> {label}
<span></span>
</label>
</div>
);
}
Is there any better way to do this?
Your implementation for enabling/disabling a checkbox is correct.
For displaying the default checked value for a checkbox you'll need to use defaultChecked. In your example, you're not passing down a input value to Checkbox (I see only disabled and label). Make sure you are and that it's a boolean value. Then you should be good to go.