I'm trying to add custom validation logic to my react-bootstrap
forms, but isInvalid
doesn't seem to be respected. As soon as validated={true}
is set on the form, it always validates non-empty strings, regardless of isValid
or isInvalid
. The invalid message is displayed, but the field shows as green. See here:
Here is the offending code:
<Form noValidate validated={formValidated} id="bidForm">
<Form.Group className="mb-3" controlId="formBasicBidding">
<Form.Label>Bid Amount</Form.Label>
<InputGroup hasValidation className="mb-3">
<InputGroup.Text id="inputGroupPrepend">$</InputGroup.Text>
<Form.Control
required
value={bidAmount}
isInvalid={!(parseInt(bidAmount) > 0) && formValidated}
onChange={e => setBidAmount(e.target.value)}
/>
<InputGroup.Text id="inputGroupAppend">.00</InputGroup.Text>
<Form.Control.Feedback type="invalid">
Please select a dollar amount {`>`} 0
</Form.Control.Feedback>
</InputGroup>
</Form.Group>
<...>
</Form>
I was able to get it to work using a pattern=
regex on the input, but I'm planning to do more complex validation where a regex won't be sufficient. How can I get react-bootstrap
to follow isValid
and isInvalid
properly? Thanks!
CodePudding user response:
The docs don't do a great job of making this clear, but the form-level validated
attribute hooks directly into HTML5's native validation library and can't be used simultaneously with other validation techniques. So if you're using the native option and an input doesn't violate any of the native validation options (
The best solution here is to use either the native HTML5 validation option (detailed here) or roll your own (with or without a helper library like Formik), but not both simultaneously.
If you're trying to avoid validating until the input is actually in a "dirty" state (e.g. the user filled it out or submitted the form), you can do something like this (CodePen here):
<Form.Control
required
value={bidAmount}
isInvalid={!(parseInt(bidAmount) > 0) && (bidAmount.length || formSubmitted)}
onChange={(e) => setBidAmount(e.target.value)}
/>