{"id":16788739,"url":"https://github.com/markmead/alpinejs-form-validation","last_synced_at":"2025-07-17T13:33:14.487Z","repository":{"id":45971631,"uuid":"514839815","full_name":"markmead/alpinejs-form-validation","owner":"markmead","description":"Adds client side form/input validation powered by Alpine JS ✅","archived":false,"fork":false,"pushed_at":"2025-03-07T08:13:41.000Z","size":29,"stargazers_count":30,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-04T02:11:24.271Z","etag":null,"topics":["alpine-js","alpinejs","alpinejs-plugin","form-validation","javascript","javascript-validation","validation"],"latest_commit_sha":null,"homepage":"https://js.hyperui.dev/examples/form-validation","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/markmead.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-17T12:40:10.000Z","updated_at":"2025-03-18T17:43:59.000Z","dependencies_parsed_at":"2024-06-04T20:59:20.861Z","dependency_job_id":"22bf831a-2d3d-4575-9c68-3a3d8ff327d3","html_url":"https://github.com/markmead/alpinejs-form-validation","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/markmead/alpinejs-form-validation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmead%2Falpinejs-form-validation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmead%2Falpinejs-form-validation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmead%2Falpinejs-form-validation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmead%2Falpinejs-form-validation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/markmead","download_url":"https://codeload.github.com/markmead/alpinejs-form-validation/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmead%2Falpinejs-form-validation/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265611288,"owners_count":23797852,"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":["alpine-js","alpinejs","alpinejs-plugin","form-validation","javascript","javascript-validation","validation"],"created_at":"2024-10-13T08:24:34.141Z","updated_at":"2025-07-17T13:33:14.468Z","avatar_url":"https://github.com/markmead.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Alpine JS Form Validation\n\nAdd client side form validation with Alpine JS 🎉\n\n## Install\n\n### With a CDN\n\n```html\n\u003cscript\n  defer\n  src=\"https://unpkg.com/alpinejs-form-validation@latest/dist/validation.min.js\"\n\u003e\u003c/script\u003e\n\n\u003cscript defer src=\"https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js\"\u003e\u003c/script\u003e\n```\n\n### With a Package Manager\n\n```shell\nyarn add -D alpinejs-form-validation\n\nnpm install -D alpinejs-form-validation\n```\n\n```js\nimport Alpine from 'alpinejs'\nimport validation from 'alpinejs-form-validation'\n\nAlpine.plugin(validation)\n\nAlpine.start()\n```\n\n## Example\n\n_This example uses Tailwind CSS for styling but that is not mandatory._\n\n```html\n\u003cform\n  @submit.prevent=\"$dispatch('validate')\"\n  x-data=\"{ contactName: '', contactAge: '', contactMessage: '', contactTerms: false }\"\n  class=\"max-w-xl mx-auto space-y-4\"\n\u003e\n  \u003cdiv\n    x-data=\"{ required: false }\"\n    @error=\"required = $valid($event.detail, 'required')\"\n  \u003e\n    \u003clabel for=\"contactName\" class=\"font-medium\"\u003e Name \u003c/label\u003e\n\n    \u003cinput\n      id=\"contactName\"\n      type=\"text\"\n      x-model=\"contactName\"\n      x-validation.required=\"contactName\"\n      class=\"w-full mt-1 rounded data-[validation-valid=true]:border-green-500 data-[validation-valid=false]:border-red-500\"\n    /\u003e\n\n    \u003csmall x-cloak x-show=\"required\" class=\"text-red-600 mt-1 block\"\u003e\n      Need a name\n    \u003c/small\u003e\n  \u003c/div\u003e\n\n  \u003cdiv\n    x-data=\"{ minAge: false, maxAge: false }\"\n    @error=\"\n      minAge = $valid($event.detail, 'min')\n      maxAge = $valid($event.detail, 'max')\n    \"\n  \u003e\n    \u003clabel for=\"contactAge\" class=\"font-medium\"\u003e Age \u003c/label\u003e\n\n    \u003cinput\n      id=\"contactAge\"\n      type=\"number\"\n      x-model=\"contactAge\"\n      x-validation.min.18.max.24=\"contactAge\"\n      class=\"w-full rounded mt-1 data-[validation-valid=true]:border-green-500 data-[validation-valid=false]:border-red-500\"\n    /\u003e\n\n    \u003csmall x-cloak x-show=\"minAge\" class=\"text-red-600 mt-1 block\"\u003e\n      Must be at least 18 years old\n    \u003c/small\u003e\n\n    \u003csmall x-cloak x-show=\"maxAge\" class=\"text-red-600 mt-1 block\"\u003e\n      Can't be older than 24 years old\n    \u003c/small\u003e\n  \u003c/div\u003e\n\n  \u003cdiv\n    x-data=\"{ minLetters: false, maxLetters: false }\"\n    @error=\"\n      minLetters = $valid($event.detail, 'minLength')\n      maxLetters = $valid($event.detail, 'maxLength')\n    \"\n  \u003e\n    \u003clabel for=\"contactMessage\" class=\"font-medium\"\u003e Message \u003c/label\u003e\n\n    \u003ctextarea\n      id=\"contactMessage\"\n      x-model=\"contactMessage\"\n      x-validation.min:length.10.max:length.50=\"contactMessage\"\n      class=\"rounded w-full mt-1 data-[validation-valid=true]:border-green-500 data-[validation-valid=false]:border-red-500\"\n    \u003e\u003c/textarea\u003e\n\n    \u003csmall x-cloak x-show=\"minLetters\" class=\"text-red-600 mt-1 block\"\u003e\n      Must be at least 10 characters\n    \u003c/small\u003e\n\n    \u003csmall x-cloak x-show=\"maxLetters\" class=\"text-red-600 mt-1 block\"\u003e\n      Can't be more than 50 characters\n    \u003c/small\u003e\n  \u003c/div\u003e\n\n  \u003cdiv\n    x-data=\"{ isAccepted: false }\"\n    @error=\"isAccepted = $valid($event.detail, 'checked')\"\n  \u003e\n    \u003clabel for=\"contactTerms\" class=\"inline-flex items-center gap-2\"\u003e\n      \u003cinput\n        id=\"contactTerms\"\n        type=\"checkbox\"\n        value=\"true\"\n        x-model=\"contactTerms\"\n        x-validation.checked=\"contactTerms\"\n        class=\"size-5 rounded data-[validation-valid=false]:border-red-500\"\n      /\u003e\n\n      \u003cspan class=\"font-medium\"\u003eI accept the terms and conditions\u003c/span\u003e\n    \u003c/label\u003e\n\n    \u003csmall x-cloak x-show=\"isAccepted\" class=\"text-red-600 mt-1 block\"\u003e\n      Must accept\n    \u003c/small\u003e\n  \u003c/div\u003e\n\n  \u003cbutton class=\"px-5 py-2.5 rounded bg-blue-600 font-medium text-white\"\u003e\n    Submit\n  \u003c/button\u003e\n\u003c/form\u003e\n```\n\n### Functionality\n\nBreaking down the example we have the following.\n\n#### `$dispatch('validate')`\n\nEmitting the event `validate` will trigger each input within the element that\nthe event was emitted from to run through the validation checks.\n\n#### `x-validation.required=\"contactName\"`\n\nHere we are setting up the directive `x-validation` and passing the modifier\n`required` which says, the value of `contactName` must exist to pass validation.\n\n**Validation Options**\n\n- `required`\n- `min.X` (Where \"X\" is an integer)\n- `max.X` (Where \"X\" is an integer)\n- `min:length.X` (Where \"X\" is an integer)\n- `max:length.X` (Where \"X\" is an integer)\n\n#### `@error=\"required = $valid($event.detail, 'required')\"`\n\nHere we have a few things going on.\n\nWe're listing for the `@error` event which is emitted once the input has run\nthrough the validation checks. We're then setting `required` to either\ntrue/false based on the response from the magic helper `$valid`.\n\n**`$valid`**\n\nThis is a magic helper which returns true/false based on the validation status\nof the input. You pass in the `$event.detail` which comes from the `@error`\nevent and the validation option, in the example that's `required`.\n\n### Styling\n\nYou could style the inputs like this:\n\n```css\n[data-validation-valid='false'] {\n  border-color: red;\n}\n\n[data-validation-valid='true'] {\n  border-color: green;\n}\n```\n\n### Stats\n\n![](https://img.shields.io/bundlephobia/min/alpinejs-form-validation)\n![](https://img.shields.io/npm/v/alpinejs-form-validation)\n![](https://img.shields.io/npm/dt/alpinejs-form-validation)\n![](https://img.shields.io/github/license/markmead/alpinejs-form-validation)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkmead%2Falpinejs-form-validation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarkmead%2Falpinejs-form-validation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkmead%2Falpinejs-form-validation/lists"}