验证
通过 HTML5 表单验证,使用浏览器默认行为或自定义样式和 JavaScript,为用户提供有价值的、可操作的反馈。
原生 HTML5 表单验证
对于原生 HTML 表单验证,在我们所有支持的浏览器中可用,:valid
和 :invalid
伪选择器用于应用验证样式以及显示反馈消息。
Bootstrap 将 :valid
和 :invalid
样式范围限定在父 .was-validated
类,通常应用于 <Form>
(您可以使用 validated
属性作为快捷方式)。否则,任何没有值的必填字段在页面加载时都会显示为无效。这样,您可以选择何时激活它们(通常是在尝试提交表单后)。
注意!
浏览器在 form
上默认提供自己的验证 UI。您可以通过在 <Form>
或 <form>
元素中添加 HTML noValidate
属性来禁用默认 UI。
结果
加载中...
实时编辑器
import { useState } from 'react';import Button from 'react-bootstrap/Button';import Col from 'react-bootstrap/Col';import Form from 'react-bootstrap/Form';import InputGroup from 'react-bootstrap/InputGroup';import Row from 'react-bootstrap/Row';function FormExample() {const [validated, setValidated] = useState(false);const handleSubmit = (event) => {const form = event.currentTarget;if (form.checkValidity() === false) {event.preventDefault();event.stopPropagation();}setValidated(true);};return (<Form noValidate validated={validated} onSubmit={handleSubmit}><Row className="mb-3"><Form.Group as={Col} md="4" controlId="validationCustom01"><Form.Label>First name</Form.Label><Form.Controlrequiredtype="text"placeholder="First name"defaultValue="Mark"/><Form.Control.Feedback>Looks good!</Form.Control.Feedback></Form.Group><Form.Group as={Col} md="4" controlId="validationCustom02"><Form.Label>Last name</Form.Label><Form.Controlrequiredtype="text"placeholder="Last name"defaultValue="Otto"/><Form.Control.Feedback>Looks good!</Form.Control.Feedback></Form.Group><Form.Group as={Col} md="4" controlId="validationCustomUsername"><Form.Label>Username</Form.Label><InputGroup hasValidation><InputGroup.Text id="inputGroupPrepend">@</InputGroup.Text><Form.Controltype="text"placeholder="Username"aria-describedby="inputGroupPrepend"required/><Form.Control.Feedback type="invalid">Please choose a username.</Form.Control.Feedback></InputGroup></Form.Group></Row><Row className="mb-3"><Form.Group as={Col} md="6" controlId="validationCustom03"><Form.Label>City</Form.Label><Form.Control type="text" placeholder="City" required /><Form.Control.Feedback type="invalid">Please provide a valid city.</Form.Control.Feedback></Form.Group><Form.Group as={Col} md="3" controlId="validationCustom04"><Form.Label>State</Form.Label><Form.Control type="text" placeholder="State" required /><Form.Control.Feedback type="invalid">Please provide a valid state.</Form.Control.Feedback></Form.Group><Form.Group as={Col} md="3" controlId="validationCustom05"><Form.Label>Zip</Form.Label><Form.Control type="text" placeholder="Zip" required /><Form.Control.Feedback type="invalid">Please provide a valid zip.</Form.Control.Feedback></Form.Group></Row><Form.Group className="mb-3"><Form.Checkrequiredlabel="Agree to terms and conditions"feedback="You must agree before submitting."feedbackType="invalid"/></Form.Group><Button type="submit">Submit form</Button></Form>);}export default FormExample;
表单库和服务器渲染样式
在许多情况下(尤其是在 React 中),使用 Formik 或 react-formal 等库来处理表单验证非常有利。在这些情况下,可以将 isValid
和 isInvalid
属性添加到表单控件以手动应用验证样式。以下是一个与 Formik 集成的快速示例。
结果
加载中...
实时编辑器
import Button from 'react-bootstrap/Button';import Col from 'react-bootstrap/Col';import Form from 'react-bootstrap/Form';import InputGroup from 'react-bootstrap/InputGroup';import Row from 'react-bootstrap/Row';import * as formik from 'formik';import * as yup from 'yup';function FormExample() {const { Formik } = formik;const schema = yup.object().shape({firstName: yup.string().required(),lastName: yup.string().required(),username: yup.string().required(),city: yup.string().required(),state: yup.string().required(),zip: yup.string().required(),terms: yup.bool().required().oneOf([true], 'Terms must be accepted'),});return (<FormikvalidationSchema={schema}onSubmit={console.log}initialValues={{firstName: 'Mark',lastName: 'Otto',username: '',city: '',state: '',zip: '',terms: false,}}>{({ handleSubmit, handleChange, values, touched, errors }) => (<Form noValidate onSubmit={handleSubmit}><Row className="mb-3"><Form.Group as={Col} md="4" controlId="validationFormik01"><Form.Label>First name</Form.Label><Form.Controltype="text"name="firstName"value={values.firstName}onChange={handleChange}isValid={touched.firstName && !errors.firstName}/><Form.Control.Feedback>Looks good!</Form.Control.Feedback></Form.Group><Form.Group as={Col} md="4" controlId="validationFormik02"><Form.Label>Last name</Form.Label><Form.Controltype="text"name="lastName"value={values.lastName}onChange={handleChange}isValid={touched.lastName && !errors.lastName}/><Form.Control.Feedback>Looks good!</Form.Control.Feedback></Form.Group><Form.Group as={Col} md="4" controlId="validationFormikUsername"><Form.Label>Username</Form.Label><InputGroup hasValidation><InputGroup.Text id="inputGroupPrepend">@</InputGroup.Text><Form.Controltype="text"placeholder="Username"aria-describedby="inputGroupPrepend"name="username"value={values.username}onChange={handleChange}isInvalid={!!errors.username}/><Form.Control.Feedback type="invalid">{errors.username}</Form.Control.Feedback></InputGroup></Form.Group></Row><Row className="mb-3"><Form.Group as={Col} md="6" controlId="validationFormik03"><Form.Label>City</Form.Label><Form.Controltype="text"placeholder="City"name="city"value={values.city}onChange={handleChange}isInvalid={!!errors.city}/><Form.Control.Feedback type="invalid">{errors.city}</Form.Control.Feedback></Form.Group><Form.Group as={Col} md="3" controlId="validationFormik04"><Form.Label>State</Form.Label><Form.Controltype="text"placeholder="State"name="state"value={values.state}onChange={handleChange}isInvalid={!!errors.state}/><Form.Control.Feedback type="invalid">{errors.state}</Form.Control.Feedback></Form.Group><Form.Group as={Col} md="3" controlId="validationFormik05"><Form.Label>Zip</Form.Label><Form.Controltype="text"placeholder="Zip"name="zip"value={values.zip}onChange={handleChange}isInvalid={!!errors.zip}/><Form.Control.Feedback type="invalid">{errors.zip}</Form.Control.Feedback></Form.Group></Row><Form.Group className="mb-3"><Form.Checkrequiredname="terms"label="Agree to terms and conditions"onChange={handleChange}isInvalid={!!errors.terms}feedback={errors.terms}feedbackType="invalid"id="validationFormik0"/></Form.Group><Button type="submit">Submit form</Button></Form>)}</Formik>);}export default FormExample;
工具提示
如果您的表单布局允许,您可以使用 tooltip
属性在样式化的工具提示中显示验证反馈。确保父元素具有 position: relative
以进行工具提示定位。在下面的示例中,我们的列类已经具有此属性,但您的项目可能需要其他设置。
结果
加载中...
实时编辑器
import Button from 'react-bootstrap/Button';import Col from 'react-bootstrap/Col';import Form from 'react-bootstrap/Form';import InputGroup from 'react-bootstrap/InputGroup';import Row from 'react-bootstrap/Row';import * as formik from 'formik';import * as yup from 'yup';function FormExample() {const { Formik } = formik;const schema = yup.object().shape({firstName: yup.string().required(),lastName: yup.string().required(),username: yup.string().required(),city: yup.string().required(),state: yup.string().required(),zip: yup.string().required(),file: yup.mixed().required(),terms: yup.bool().required().oneOf([true], 'terms must be accepted'),});return (<FormikvalidationSchema={schema}onSubmit={console.log}initialValues={{firstName: 'Mark',lastName: 'Otto',username: '',city: '',state: '',zip: '',file: null,terms: false,}}>{({ handleSubmit, handleChange, values, touched, errors }) => (<Form noValidate onSubmit={handleSubmit}><Row className="mb-3"><Form.Groupas={Col}md="4"controlId="validationFormik101"className="position-relative"><Form.Label>First name</Form.Label><Form.Controltype="text"name="firstName"value={values.firstName}onChange={handleChange}isValid={touched.firstName && !errors.firstName}/><Form.Control.Feedback tooltip>Looks good!</Form.Control.Feedback></Form.Group><Form.Groupas={Col}md="4"controlId="validationFormik102"className="position-relative"><Form.Label>Last name</Form.Label><Form.Controltype="text"name="lastName"value={values.lastName}onChange={handleChange}isValid={touched.lastName && !errors.lastName}/><Form.Control.Feedback tooltip>Looks good!</Form.Control.Feedback></Form.Group><Form.Group as={Col} md="4" controlId="validationFormikUsername2"><Form.Label>Username</Form.Label><InputGroup hasValidation><InputGroup.Text id="inputGroupPrepend">@</InputGroup.Text><Form.Controltype="text"placeholder="Username"aria-describedby="inputGroupPrepend"name="username"value={values.username}onChange={handleChange}isInvalid={!!errors.username}/><Form.Control.Feedback type="invalid" tooltip>{errors.username}</Form.Control.Feedback></InputGroup></Form.Group></Row><Row className="mb-3"><Form.Groupas={Col}md="6"controlId="validationFormik103"className="position-relative"><Form.Label>City</Form.Label><Form.Controltype="text"placeholder="City"name="city"value={values.city}onChange={handleChange}isInvalid={!!errors.city}/><Form.Control.Feedback type="invalid" tooltip>{errors.city}</Form.Control.Feedback></Form.Group><Form.Groupas={Col}md="3"controlId="validationFormik104"className="position-relative"><Form.Label>State</Form.Label><Form.Controltype="text"placeholder="State"name="state"value={values.state}onChange={handleChange}isInvalid={!!errors.state}/><Form.Control.Feedback type="invalid" tooltip>{errors.state}</Form.Control.Feedback></Form.Group><Form.Groupas={Col}md="3"controlId="validationFormik105"className="position-relative"><Form.Label>Zip</Form.Label><Form.Controltype="text"placeholder="Zip"name="zip"value={values.zip}onChange={handleChange}isInvalid={!!errors.zip}/><Form.Control.Feedback type="invalid" tooltip>{errors.zip}</Form.Control.Feedback></Form.Group></Row><Form.Group className="position-relative mb-3"><Form.Label>File</Form.Label><Form.Controltype="file"requiredname="file"onChange={handleChange}isInvalid={!!errors.file}/><Form.Control.Feedback type="invalid" tooltip>{errors.file}</Form.Control.Feedback></Form.Group><Form.Group className="position-relative mb-3"><Form.Checkrequiredname="terms"label="Agree to terms and conditions"onChange={handleChange}isInvalid={!!errors.terms}feedback={errors.terms}feedbackType="invalid"id="validationFormik106"feedbackTooltip/></Form.Group><Button type="submit">Submit form</Button></Form>)}</Formik>);}export default FormExample;
输入组验证
为了在具有验证的 <InputGroup>
中正确显示圆角,<InputGroup>
需要 hasValidation
属性。
结果
加载中...
实时编辑器
import Form from 'react-bootstrap/Form';import InputGroup from 'react-bootstrap/InputGroup';function ValidationInputGroupExample() {return (<InputGroup hasValidation><InputGroup.Text>@</InputGroup.Text><Form.Control type="text" required isInvalid /><Form.Control.Feedback type="invalid">Please choose a username.</Form.Control.Feedback></InputGroup>);}export default ValidationInputGroupExample;