Home > Net >  Custom validation in react-bootstrap forms not working
Custom validation in react-bootstrap forms not working

Time:03-23

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:

enter image description 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 (enter image description here

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)}
        />
  • Related