RRF perform default validations, but it's not possible to disable them.
The typeMismatch is triggered on a type="email", but if you don't want to display this to the user, do server side validations or provide you own email validation logic, this is inconvenient.
Type an invalid email in the form
The typeMismatch error should not be triggered
The typeMismatch is triggered
So this is an interesting case because even with <form novalidate> and/or <input formnovalidate /> in HTML5 constraint validation, the input will still validate; i.e., .willValidate === true. This is per the spec - despite novalidate and/or formnovalidate the control is not barred from constraint validation.
However, per the HTML5 spec:
<form novalidate> will always submit, even if controls are invalid<input formnovalidate> can still be invalid, but won't prevent the form from submitting aloneTo address your issue, I added some careful (and small) logic for handling noValidate and formNoValidate:
Form noValidate:
noValidate={true}, then the <Form> _will_ submit even if the form is invalid. This is in line with the spec, and is useful when you want to liberally allow the user to submit a form but also make the user aware of any validation problems.noValidate attribute will still be passed on to the native <form>.Control formNoValidate
formNoValidate={true} on the <Control>, then HTML5 validity will not affect the field's validity.<Form> to prevent submission if any of the inputs is invalid for your own custom validators.// noValidate on Form
// handleSubmit will always be called upon submit
<Form model="user" noValidate onSubmit={handleSubmit}>
<Control.input type="email" model=".name" />
<Errors model=".name" messages={{
typeMismatch: 'Email invalid, but you can still submit'
}} />
</Form>
// formNoValidate on Control
// handleSubmit will be called if control is valid per custom validators,
// not per HTML5 constraint validation
<Form model="user" onSubmit={handleSubmit}>
<Control.input
formNoValidate
type="email"
model=".name"
validators={{isEmail}}
/>
<Errors model=".name" messages={{
typeMismatch: 'You will never see this error message',
isEmail: 'You might see this, and handleSubmit will not be called'
}} />
</Form>
// noValidate on Form and formNoValidate on Control
// handleSubmit will always be called
<Form model="user" noValidate onSubmit={handleSubmit}>
<Control.input
formNoValidate
type="email"
model=".name"
validators={{isEmail}}
/>
<Errors model=".name" messages={{
typeMismatch: 'You will never see this error message',
isEmail: 'You might see this, but handleSubmit will still be called'
}} />
</Form>
Thanks! Amazing!
Looking forward to the next release.. :)
Btw. that really good answer/description deserves a place in the documentation, at least under the FAQ..
Btw. that really good answer/description deserves a place in the documentation, at least under the FAQ..
Good call!
I tried to fork the changes, and can confirm it now works as expected.. SUPER NICE..!
Any ETA on a new release..?
Probably today or tomorrow at the latest. There's a few more fixes I want to get in.
super.. i'm running on my own fork right now, so no pressure.. :)
again, super nice with a working fix..! ⭐️
@Hi @davidkpiano,
I've just been bitten by the change made regarding noValidate. I think this is a breaking change for a 'dot' release.
I had noValidate on all my forms so that the HTML5 error messages weren't displayed as I was taking care of validation and error messages myself.
The upgrade to 1.12.1 has caused all by forms to be submittable when invalid.
I personally think this change should be reverted, or at least the property used to turn off validation should NOT be noValidate.
As a side note, I tried to add formNoValidate to my controls, but the HTML 5 error popup is still showing when I submit my empty and invalid form.
Thoughts??
Peter
@peterox The behavior seems correct -- I don't believe this is a breaking change. That is, if you use noValidate on your form, it _means_ that it can be submitted according to the HTML5 spec.
I also have problems with this update. What I need is to onSubmit to be called only when form is valid according to validators rules, but I don't want to show HTML5 messages. Form noValidate will always submit the form, and Input formNoValidate will still show HTML5 error popup. So it looks like there is no way to get what I want for example for <input type="email" />, but I guess that this is quite common usecase, unless it is possible somehow?
One of ideas would be to add new prop to Form, for example onValidSubmit. This would be in sync with HTML5 spec, because onSubmit would work as in specs, and this additional callback would be good combination with noValidate.
@klis87 I like this idea:
One of ideas would be to add new prop to Form, for example
onValidSubmit. This would be in sync with HTML5 spec, becauseonSubmitwould work as in specs, and this additional callback would be good combination withnoValidate.
@peterox what do you think of the above? The behavior would be that:
noValidate, onSubmit will _always_ be called (this is supposed to happen, according to the spec)noValidate, onValidSubmitwill never be called unless the form is 100% valid.Would that fix your concerns?
@davidkpiano that would work for me.
Though I still think this is a breaking change so should be communicated as such. i.e. v1.13.0 at least
Here's why.
Using v1.12.0 of react-redux-forms with noValidate on my form, my forms were properly validating using my supplied validators without any of the pesky HTML5 validation popups. I am using react-toolbox form components so adding the HTML5 attributes to the inputs was necessary for them to be displayed correctly.
I did an npm update which updated to 1.12.1.
My forms will now submit when invalid.
If I am in this boat then I believe many other people would also be.
I agree @peterox. I'll make the addition, add documentation, and bump the minor version up.
Sorry for the confusion. The previous behavior (quelling any HTML5 validation popups _and_ still having validation prevent submit) should not have been possible (because noValidate means "do not validate, and let the form always submit"; hiding the error messages was just a side-effect of that) so it was a bug that turned into an accidental feature. 😖
Thanks @davidkpiano. Keep up the awesome work.
@peterox Actually, I found a better solution, that is _much_ more idiomatic (that is, it doesn't require a new magical prop for React-Redux-Form).
If you want to hide native HTML5 validation errors for a form that should still consider the validity before submitting, do not use noValidate - it does not mean what you think it means.
Instead, use the native onInvalid event handler to prevent the message from showing up:
<Control.text
model="user.email"
type="email"
onInvalid={e => e.preventDefault()}
/>
I'll add this to the FAQs.
Hi @davidkpiano . I tried your idea but this is still not a workable fix.
With the onInvalid handler as above, and with the noValidate attribute removed, the HTML5 error messages don't pop up
BUT...
when I hit submit on my form that has invalid fields, my error messages used to be shown. i.e. all fields were validated.
Now, with the above handler added, when I click submit nothing happens. The fields do not show up as in error (and the form does not get submitted).
Peter
@peterox I can't replicate this. The below code works perfectly fine:
<Form model="user">
<Control.text
model=".email"
type="email"
onInvalid={e => e.preventDefault()}
/>
<Errors
model=".email"
messages={{ typeMismatch: 'that is not a valid email' }}
/>
<button>Submit!</button>
</Form>
Maybe I left off one piece of the puzzle.
I have showErrors set to 'touched'. So the initial error messages (like
required) are not shown when the form is displayed. Prior to 1.12.1 when
you clicked the submit button all fields were validated and all error
messages displayed.
With 1.12.1 and the onInvalid handler this doesn't happen.
Looking at the code validation happens on submit. My guess is that the
native browser code never fires submit when an invalid field is found.
Peter
On Mon., 19 Jun. 2017, 6:34 am David Khourshid, notifications@github.com
wrote:
@peterox https://github.com/peterox I can't replicate this. The below
code works perfectly fine:—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/davidkpiano/react-redux-form/issues/823#issuecomment-309301188,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAxGF8QlQMvF55ULEBfhez2tlFkLxSa2ks5sFYnbgaJpZM4NvUVZ
.
@peterox Interesting, can you please open up a separate issue about this? This is more a use-case that hasn't really been explored rather than a bug, but I'm keen on fixing it.
@davidkpiano I have the same issue like @peterox and I will say it here as I really think this is a bug.
I have following components:
import React from 'react';
import { Control } from 'react-redux-form';
import FormGroup from './FormGroup';
const isValid = ({ fieldValue }) => fieldValue.valid || (!fieldValue.touched && !fieldValue.asyncKeys);
const Input = props => (
<Control
{...props}
component={FormGroup}
mapProps={{ valid: isValid }}
/>
);
export default Input;
import React from 'react';
import { FormControl, FormGroup as BootstrapFormGroup, ControlLabel } from 'react-bootstrap';
import { Errors } from 'react-redux-form';
import ErrorMessages from './ErrorMessages';
const show = field => field.touched || field.asyncKeys;
const onInvalid = e => e.preventDefault();
const FormGroup = ({ valid, label, messages, ...rest }) => (
<BootstrapFormGroup validationState={valid ? null : 'error'}>
<ControlLabel>{label}</ControlLabel>
<FormControl {...rest} onInvalid={onInvalid} />
<Errors
model={rest.name}
messages={messages}
component={ErrorMessages}
show={show}
/>
</BootstrapFormGroup>
);
export default FormGroup;
The problem is, that I wanted error state and error messages to be visible only when field is touched. It won't work in the following case - you don't fill your form but just press submit immediately - show and isValid aren't called when clicking submit, so my components aren't told that fields should become touched and no message or invalid styles are being shown.
This is really a serious issue as currently there is no way to make this work, and all I can do is to revert to older version.
@klis87 Can you open a fresh issue with that?