{"id":16541787,"url":"https://github.com/itzg/nextjs-bootstrap-validation","last_synced_at":"2025-04-04T20:45:30.778Z","repository":{"id":42806796,"uuid":"270351385","full_name":"itzg/nextjs-bootstrap-validation","owner":"itzg","description":null,"archived":false,"fork":false,"pushed_at":"2023-03-04T22:55:35.000Z","size":647,"stargazers_count":2,"open_issues_count":3,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-10T05:25:29.302Z","etag":null,"topics":["bootstrap-react","form-validation","html5","reactjs"],"latest_commit_sha":null,"homepage":"https://nextjs-bootstrap-validation.now.sh/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/itzg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-07T15:39:00.000Z","updated_at":"2023-08-02T11:46:36.000Z","dependencies_parsed_at":"2023-02-06T12:15:48.666Z","dependency_job_id":null,"html_url":"https://github.com/itzg/nextjs-bootstrap-validation","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzg%2Fnextjs-bootstrap-validation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzg%2Fnextjs-bootstrap-validation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzg%2Fnextjs-bootstrap-validation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzg%2Fnextjs-bootstrap-validation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itzg","download_url":"https://codeload.github.com/itzg/nextjs-bootstrap-validation/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247249601,"owners_count":20908211,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bootstrap-react","form-validation","html5","reactjs"],"created_at":"2024-10-11T18:55:53.140Z","updated_at":"2025-04-04T20:45:30.758Z","avatar_url":"https://github.com/itzg.png","language":"JavaScript","readme":"# Next.js with react-bootstrap and form validation\n\n[Starting from this example](https://github.com/vercel/next.js/tree/canary/examples/with-react-bootstrap), this project was my experiment to see how form validation could be done easily and effectively with [React Bootstrap](https://react-bootstrap.netlify.app/) as the UI framework.\n\nI tried two scenarios where my goal was to minimize complexity, tediousness, and stay as true to React/HTML5 as possible.\n\n[React Hook Form](https://react-hook-form.com/) is minimally intrusive, easy to use, and is fairly flexible. With React Bootstrap it only worked with the \"ref\" approach using [register](https://react-hook-form.com/api#register). The [Controller](https://react-hook-form.com/api#Controller) approach didn't work for me. The downside to the \"ref\" approach is that I'm guessing it is using an uncontrolled strategy, which is [not recommended by React](https://reactjs.org/docs/uncontrolled-components.html).\n\nThe other approach, which I ended up preferring, was to use [React Bootstrap's support for native HTML5 validation](https://react-bootstrap.netlify.app/components/forms/#forms-validation-native). It was easy to activate and not surprisingly integrates more easily with Bootstrap's `Form.Control.Feedback` component. What really sold me on this approach is that HTML5 already provides a `validationMessage`, [described here](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation#Validating_forms_using_JavaScript), that conveys a helpful description of why the field is invalid. \n\nHere is the view of the required field after the initial form submission:\n\n![](docs/empty-field.png)\n\nAs typing characters, but still below the `minLength={3}` declaration:\n\n![](docs/too-short.png)\n\nFinally, when typing at least another character the rendering flips to a positive indication and feedback removal:\n\n![](docs/valid.png)\n\nWith that knowledge I wrapped up the potential repetition in a little helper component that paired a `Form.Control` with a `Form.Control.Feedback`. That helper component made use of the `validationMessage`, the `name` on the input, and the [`invalid` event](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/invalid_event) fired by inputs during validation.\n\nUsing that helper component each input is about 10 lines, which is quite acceptable, for example:\n\n```jsx\n\u003cValidatedFormControl onChange={handleChange}\n                    value={values.yourName}\n                    name=\"yourName\"\n                    type=\"text\" placeholder=\"Enter your name\"\n                    required\n                    minLength={3}\n/\u003e\n```\n\nThat `ValidatedFormControl` doesn't require much code itself:\n```jsx\nfunction ValidatedFormControl({\n  value,\n  onChange,\n  ...props\n}) {\n  const [message, setMessage] = useState();\n  const { controlId } = useContext(FormContext);\n\n  return (\n      \u003c\u003e\n        \u003cForm.Control {...props}\n                      value={value}\n                      onChange={event =\u003e {\n                        onChange(event.target.value, event.target.name || controlId);\n                        event.target.checkValidity();\n                      }}\n                      onInvalid={event =\u003e setMessage(\n                          event.target.validationMessage)}\n        /\u003e\n        \u003cForm.Control.Feedback type=\"invalid\"\u003e\n          {message}\n        \u003c/Form.Control.Feedback\u003e\n      \u003c/\u003e\n  )\n}\n```\n\n## Deploy your own\n\nDeploy this project using [Vercel](https://vercel.com):\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/itzg/nextjs-bootstrap-validation)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitzg%2Fnextjs-bootstrap-validation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitzg%2Fnextjs-bootstrap-validation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitzg%2Fnextjs-bootstrap-validation/lists"}