How to show validation errors on form using React - reactjs

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 &&

Related

Ant.design does not detect custom input component in Form.Item React

So, the main problem is, that antd form does not detect my custom input based on antd standard input:
There is a piece of form code (AddProduct):
<Form.Item
className="m-t-10"
name="price"
rules={[
{
required: true,
message: `${t('FORM.ERR.SHOP.PRICE')}`,
},
]}
>
<CurrencyInput size="small" placeholder={t('FORM.SHOP.PRICE_VAT')} name="price" />
</Form.Item>
There is my custom input (CurrencyInput):
return (
<Input size={props.size} placeholder={props.placeholder} name={props.name} type="number" prefix={settings[6].value} />
)
The problem is when I try to submit the form it does not detect currency input, throws err that this field is required. Any ideas are it possible to implement custom input, basically, it's more HOC than custom input
You need to pass to your custom component all props, because Form.Item pass to there onChange and value props
function CustomInput({size, placehodler, name, ...restProps}) {
return (
<Input size={size} placeholder={placeholder} name={name}
type="number" prefix={settings[6].value} {...restProps} />
)
}

Conditionally Checking for Errors with Formik Field Component

I have set up the following form using Formik:
const RenderForm = ({ errors, isSubmitting, isValid, touched }) => {
return (
<Form>
<h3>Sign Up</h3>
<Email
name="email"
error={touched.email && errors.email ? 'error' : null}
/>
<Password
name="password"
error={touched.password && errors.password ? 'error' : null}
/>
<Button disabled={!isValid || isSubmitting} type="submit">
Submit
</Button>
{/* {errors.firebaseErrorMessage && ( */}
{/* <Help>{errors.firebaseErrorMessage}</Help> */}
{/* )} */}
</Form>
)
}
The Email component and the Password components are just wrappers for the Formik Field Component. I want to be able to add a red border a particular field if it fails validation.
To do that, I have set up a conditional for the error prop. IF it is touched AND IF the error is passed, then it renders that prop with a value of 'error'.
Now there are a few problems with this.
FIRST PROBLEM
I don't need to render a value of 'error' (or any other value) to the error attribute. I just need to have the attribute 'error' itself (without any value) and then it will be styled appropriately.
SECOND PROBLEM
It's a bit annoying to write out the same conditional test for each field. I would like to know if there is something like the ErrorMessage component, except for a prop. Basically, something like this:
<Email name="email" errorProp />
<Password name="password" errorProp />
The idea being that errorProp will set an attribute of 'error' if an error exists and nothing if an error does not exist.
So here is my question...
How can I create my own errorProp or, at the very least, simplify what I am trying to do?
Thanks.

Why are all my checkboxes in redux form linked

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

How to update the state in react outside a render method using a function

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.

Redux-Form—Create Password Field with »retype«

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).

Resources