検証
ブラウザのデフォルトの動作またはカスタムスタイルとJavaScriptを介して、HTML5フォーム検証を使用して、ユーザーに価値のある、実用的なフィードバックを提供します。
ネイティブHTML5フォーム検証
ネイティブHTMLフォーム検証(サポートされているすべてのブラウザで使用可能)では、`:valid` および `:invalid` 疑似セレクターを使用して、検証スタイルを適用し、フィードバックメッセージを表示します。
Bootstrapは、`:valid` および `:invalid` スタイルのスコープを親の `.was-validated` クラスに設定します。これは通常、`<Form>` に適用されます(`validated` propをショートカットとして使用できます)。 そうしないと、値のない必須フィールドは、ページの読み込み時に無効として表示されます。 この方法では、それらをいつアクティブにするかを選択できます(通常はフォームの送信が試行された後)。
ブラウザは、デフォルトで `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;
フォームライブラリとサーバーレンダリングされたスタイル
Formikやreact-formalなどのライブラリを介してフォーム検証を処理すると便利なことがよくあります(特にReactの場合)。 そのような場合、`isValid` および `isInvalid` propをフォームコントロールに追加して、検証スタイルを手動で適用できます。 以下は、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` propを使用して、スタイル付きのツールチップに検証フィードバックを表示できます。 ツールチップの位置決めには、`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` propが必要です。
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;