{"id":25485498,"url":"https://github.com/tarponjargon/js-simple-validations","last_synced_at":"2025-04-09T20:05:36.884Z","repository":{"id":57283622,"uuid":"128422432","full_name":"tarponjargon/js-simple-validations","owner":"tarponjargon","description":"Dead Simple HTML Form Validator.  No Javascript required.","archived":false,"fork":false,"pushed_at":"2019-04-11T02:58:22.000Z","size":620,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-09T20:05:30.835Z","etag":null,"topics":["data-attribute-html","form","forms","javascript","javascript-library","validation","validation-library"],"latest_commit_sha":null,"homepage":"","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/tarponjargon.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":"2018-04-06T17:02:10.000Z","updated_at":"2024-12-05T14:47:45.000Z","dependencies_parsed_at":"2022-09-04T18:53:16.954Z","dependency_job_id":null,"html_url":"https://github.com/tarponjargon/js-simple-validations","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/tarponjargon%2Fjs-simple-validations","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarponjargon%2Fjs-simple-validations/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarponjargon%2Fjs-simple-validations/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarponjargon%2Fjs-simple-validations/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tarponjargon","download_url":"https://codeload.github.com/tarponjargon/js-simple-validations/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248103872,"owners_count":21048245,"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":["data-attribute-html","form","forms","javascript","javascript-library","validation","validation-library"],"created_at":"2025-02-18T18:36:33.060Z","updated_at":"2025-04-09T20:05:36.851Z","avatar_url":"https://github.com/tarponjargon.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Simple Validations\nAnother form validation library! There are already some [good ones out there](https://www.google.com/search?q=javascript%20form%20validation%20library), but most depend on other libraries, or require you to get your hands dirty.  Use Simple Validations (JSV) when don't want to mess with *any* Javascript, CSS or dependencies (aren't forms painful enough already?)   Think of it as enhanced [HTML5 form validations](https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation).\n\n![enter image description here](https://i.imgur.com/C0cDlOx.gif)\n\n - Validates as you type\n - No dependency on any other library or framework (vanilla JS)\n - Configures with HTML, using data attributes (write no JS, unless you want)\n - No separate styling needed (unless you want to customize)\n - Promise-based and debounced\n - Supports async validations\n - ES5-compatible, tested back to IE11\n - Can be used for multiple forms on a page\n - Only 10kb gzipped\n\n\u003ca href=\"https://codepen.io/tarponjargon/pen/mLeQMg/\"\u003eTry it out on CodePen\u003c/a\u003e\n\n## Documentation\n1. [How it works](#howitworks)\n2. [Installation](#installation)\n3. [Quick Setup](#quicksetup)\n4. [Validation Types](#validationtypes)\n5. [Customizing Validation Messages](#validationmessages)\n6. [Containers and Styling](#containersandstyling)\n7. [Form Configuration](#formlevelconfig)\n8. [Field Configuration](#fieldlevelconfig)\n9. [App Configuration](#appconfig)\n10. [Custom Validators](#customvalidators)\n11. [Callbacks](#callbacks)\n12. [Testing](#testing)\n13. [Acknowledgements](#acknowledgements)\n\n\u003ca name=\"howitworks\"\u003e\u003c/a\u003e\n## How it Works\n\nJSV listens for `input`, `change` and `focusout` events on each field in the form, and the `submit` event on the form itself.  Validations are triggered on each of those events.  When all fields pass validation, the form is in a \"valid\" state and can be submitted.  \n\nTo avoid you having to write *any* Javascript, JSV instantiates and attaches to form elements when the page is ready.  JSV is intended for use with \"traditional\" server-side rendered HTML forms.  So if you're using a framework or otherwise creating your forms with Javascript, it probably won't work.  \n\n\u003ca name=\"installation\"\u003e\u003c/a\u003e\n## Installation\nDownload the [javascript file](https://raw.githubusercontent.com/tarponjargon/js-simple-validations/master/dist/js-simple-validations.js), or just include this script tag in your HTML:\n\n    \u003cscript src=\"https://unpkg.com/js-simple-validations@0.2.9/dist/js-simple-validations.js\"\u003e\u003c/script\u003e\n\nOr install with npm:\n\n    npm install js-simple-validations --save-dev\n\nThen import into your bundle with:\n\n\timport SimpleValidations from 'js-simple-validations';\n\n\u003ca name=\"quicksetup\"\u003e\u003c/a\u003e\n## Quick Setup\n\nOn your form(s) add this `data-jsv-form=\"true\"` to any form(s) you want to validate:\n\n    \u003cform action=\"/processform\" method=\"POST\" data-jsv-form=\"true\"\u003e\n\nFor each field in the form you want to validate, specify the field [validation type(s)](#validationtypes) like `data-jsv-validators=\"[TYPE]\"`\n\n    \u003cinput type=\"text\" name=\"firstname\" data-jsv-validators=\"require\" /\u003e\n\nOr apply multiple types like:\n\n    \u003cinput type=\"text\" name=\"email\" data-jsv-validators=\"require, email\" /\u003e\n\n*That's all you need to do* (unless you want to [customize](#validationmessages))\n\n\u003ca name=\"validationtypes\"\u003e\u003c/a\u003e\n## Validation Types\n\n**require**\n\nInput value exists and is not all whitespace.  \n\n    \u003cinput type=\"text\" name=\"firstname\" data-jsv-validators=\"require\" /\u003e\n\nIf `require` is not specified, other validators will only trigger *if* there's a value entered, by design.  So always use `require` (with others, optionally) if you require *some* input in the field.\n\n**email**\n\nInputted value is a properly-formatted email.\n\n    \u003cinput type=\"text\" name=\"email\" data-jsv-validators=\"email\" /\u003e\n\n**url**\n\nInputted value is a properly-formatted URL.\n\n    \u003cinput type=\"text\" name=\"website\" data-jsv-validators=\"url\" /\u003e\n\n**number**\n\nInput is a number (decimals OK).\n\n    \u003cinput type=\"number\" name=\"children\" data-jsv-validators=\"number\" /\u003e\n\n**length**\n\nCharacter length of the inputted value must be within a range.  Specify character lengths in `data-jsv-min` and `data-jsv-max`.\n\n\t\u003cinput type=\"text\" name=\"username\" data-jsv-validators=\"length\" data-jsv-min=\"6\" jsv-length-max=\"20\" /\u003e\n\n**exact**\n\nThere must be an exact number of characters entered.  Specify in `data-jsv-exact`.\n\n\t\u003cinput type=\"text\" name=\"username\" data-jsv-validators=\"exact\" data-jsv-exact=\"12\" /\u003e\n\n**numberexact**\n\nInputted value is a number this many characters long.  Specify in `data-jsv-exact`.\n\n\t\u003cinput type=\"number\" name=\"custno\" data-jsv-validators=\"numberexact\" data-jsv-exact=\"12\" /\u003e\n\n**numberrange**\n\nInputted value is a number is between (or equals) `data-jsv-min` to `data-jsv-max`\n\n\t\u003cinput type=\"number\" name=\"age\" data-jsv-validators=\"numberrange\" data-jsv-min=\"1\" data-jsv-max=\"120\" /\u003e\n\n**contains**\n\nInput contains this string.  Specify in `data-jsv-contains`.  Case-insensitive.\n\n    \u003c!--make sure value contains (or IS) the word \"twelve\"--\u003e\n\t\u003cinput type=\"text\" name=\"userInput\" data-jsv-validators=\"contains\" data-jsv-contains=\"twelve\" /\u003e\n\n**zipcode**\n\nInputted value is a properly-formatted US zip code (plus 4 optional, but validated if entered)\n\n\t\u003cinput type=\"text\" name=\"zipcode\" data-jsv-validators=\"zipcode\" /\u003e\n\n**phone**\n\nInputted value is a properly-formatted phone number.  This is a fairly liberal validation and will accept international numbers.\n\n\t\u003c!-- examples of valid input:\n\t\t773-555-1212\n\t\t(330) 555-1212\n\t\t5045551212\n\t\t+1-555-532-3455\n\t\t+33-6-79-91-25-49\n\t--!\u003e   \n\t\u003cinput type=\"text\" name=\"phone\" data-jsv-validators=\"phone\" /\u003e\n\n**creditcard**\n\nInputted value is a properly-formatted credit card number using the [Luhn Algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm).\n\n    \u003cinput type=\"text\" name=\"cardno\" data-jsv-validators=\"creditcard\" /\u003e\n\n**pattern**\n\nValidate input against a custom regular expression specified in `data-jsv-pattern`.  \n\n     \u003cinput type=\"text\" name=\"birthdate\" data-jsv-validators=\"pattern\" data-jsv-pattern=\"^\\d{4}\\-\\d{2}\\-\\d{2}$\" placeholder=\"Enter a date in the format YYYY-MM-DD\" /\u003e\n\n**compare**\n\nCompare inputted value against the value of another field.  Specify the `name` of the field to compare to in `data-jsv-compare`.  Case sensitive.\n\n    \u003c!-- validates if the value entered into ConfirmPassword matches the value entered into Password--\u003e\n    \u003cinput type=\"password\" name=\"ConfirmPassword\" data-jsv-validators=\"compare\" data-jsv-compare=\"Password\" placeholder=\"Confirm Password\" /\u003e\n\n**dependent**\n\nWill not validate until fields specified in `data-jsv-dependents` (comma delimited if more than one) are validated first.  \n\n    \u003cinput type=\"password\" name=\"ConfirmPassword\" data-jsv-validators=\"dependent, require\" data-jsv-dependents=\"Login, Password\" /\u003e\n\n**expireddate**\n\nChecks if year, month and day (optional) combined field values are in the past.  The year field in the form is specified with `data-jsv-expiredate=\"year\"`, month, `data-jsv-expiredate=\"month\"` and (optional) day `data-jsv-expiredate=\"day\"`.  All get the `expireddate` validator.\n\n\t\u003cselect name=\"expirationMonth\" data-jsv-validators=\"expireddate\" data-jsv-expiredate=\"month\"\u003e\n\t\t\u003coption value=\"\"\u003eSelect Month\u003c/option\u003e\n\t\t\u003coption value=\"1\"\u003eJanuary\u003c/option\u003e\n\t\t...\n\t\u003c/select\u003e\n\t\u003cselect name=\"expirationYear\" data-jsv-validators=\"expireddate\" data-jsv-expiredate=\"year\"\u003e\n\t\t\u003coption value=\"\"\u003eSelect Year\u003c/option\u003e\n\t\t\u003coption value=\"2019\"\u003e2019\u003c/option\u003e\n\t\t...\n\t\u003c/select\u003e\nField values should be numbers like \"12\" rather than names like \"December\" (therefore, best used with select boxes).\n\n\u003ca href=\"ajaxvalidator\"\u003e\u003c/a\u003e\n**ajax**\n\nAn AJAX GET request is made to the endpoint in `data-jsv-ajax-endpoint`.  The field's name is used as the key, and the input as its value.  \n\nIf the JSON response has the key specified in `data-jsv-ajax-key` and that matches `data-jsv-ajax-value`, the field validates.  \n\n\t\u003c!--generates an AJAX request to /username_check?Login=[input]\n\tvalidates if the JSON response looks like:\n\t{ \"usernameAvailable\": true }\n\t--\u003e\n    \u003cinput  \n    \ttype=\"text\"\n    \tname=\"Login\"\n    \tdata-jsv-validators=\"ajax\"\n    \tdata-jsv-ajax-endpoint=\"/username_check\"\n    \tdata-jsv-ajax-key=\"usernameAvailable\"\n    \tdata-jsv-ajax-value=\"true\"\n    /\u003e\n   If `data-jsv-ajax-value` is left empty, the input is used to match.\n\n**requiremin**\n\nUsed to validate radio buttons and checkboxes (multiple form elements with the same `name`).  Validates that the minimum number specified in `data-jsv-min-selected` have been selected.  All elements with the same `name` should have the `requiremin` validator and the same number in `data-jsv-min-selected`.\n\n\t\u003c!--Validates that both checkboxes have been checked--\u003e\n\t\u003clabel\u003eAgree to terms of service?\u003c/label\u003e\n\t\u003cinput\n\t\tdata-jsv-validators=\"requiremin\"\n\t\tdata-jsv-min-selected=\"2\"\n\t\ttype=\"checkbox\"\n\t\tname=\"terms\"\n\t\tvalue=\"1\"\n\t/\u003e\n\n\t\u003clabel\u003eAgree to more stuff?\u003c/label\u003e\n\t\u003cinput\n\t\tdata-jsv-validators=\"requiremin\"\n\t\tdata-jsv-min-selected=\"2\"\n\t\ttype=\"checkbox\"\n\t\tname=\"terms\"\n\t\tvalue=\"2\"\n\t/\u003e\n\n\u003ca name=\"validationmessages\"\u003e\u003c/a\u003e\n## Customizing Validation Messages\n\nYou can customize the error message for each validator in the field itself.  The format is:\n\n    data-jsv-field-error-[validator]=\"[custom error message]\"\n\nExample of a custom error messages for validators on a credit card field:\n\n\t\u003cinput\n\t\tname=\"cardNumber\"\n\t\ttype=\"text\"\n\t\tdata-jsv-validators=\"require, creditcard\"\n\t\tdata-jsv-field-error-require=\"Please enter a credit card number (no spaces)\"\n\t\tdata-jsv-field-error-creditcard=\"Please check your credit card number\"\n\t/\u003e\n\nLooks like this on invalid input:\n\n![enter image description here](https://i.imgur.com/V9rOqBL.png)\n\n\u003ca name=\"containersandstyling\"\u003e\u003c/a\u003e\n## Containers and Styling\n\nJSV applies containers and styles automatically.  There's nothing you need to do, the exception being radio buttons and some checkboxes (see [below](#radiobuttons)).\n\nYou can override the styles if you wish.  Each form gets an error container with the class `validate-form-error-message`.  Each input field is wrapped in a validation container with the class `validate-input` so that the it can be styled as *valid* or *invalid*.  A sibling container with class `validate-field-error-message` immediately follows, where error messages appear.  The CSS is included but can be overridden in your own stylesheet if desired.\n\n![enter image description here](https://i.imgur.com/mdvVl24.png)\n\n\u003ca name=\"radiobuttons\"\u003e\u003c/a\u003e\n*\u0026nbsp;Multiple form elements with the same `name` - like radio buttons or multi-value checkboxes - need to have the error message container and validation container (optional) added to the form manually.\n\nPut this container where you want to target your error messages for the group of elements:\n\n    \u003cdiv class=\"validate-field-error-message\" id=\"[YOUR ID NAME]\"\u003e\u003c/div\u003e\n\nThen link each element of the group to the message target by adding the message target's ID to the element's data-jsv-message-target data attribute:\n\n    data-jsv-message-target=\"[YOUR ID NAME]\"\n\nBelow is a full example of a multi-value checkbox with the error message and the optional validation container specified:\n\n\t\t\u003c!-- Example of multi-value checkbox inputs that have the\n\t\t     validation and error containers added.  Note addition\n\t\t     of the \".validate-input\" and \".validate-field-error-message\"\n\t\t     elements.  Link the inputs to the containers by specifying\n\t\t     the IDs in \"data-jsv-message-target\" and \"data-jsv-validation-target\"\n\t\t     data attributes. --\u003e\n\n\t\t\u003cdiv class=\"validate-input\" id=\"checkboxvalidate\"\u003e\n\t\t\t\u003cinput\n\t\t\t\tdata-jsv-validators=\"requiremin\"\n\t\t\t\tdata-jsv-min-selected=\"2\"\n\t\t\t\tid=\"test-terms-service\"\n\t\t\t\tdata-jsv-message-target=\"checkbox-invalid\"\n\t\t\t\tdata-jsv-validation-target=\"checkboxvalidate\"\n\t\t\t\ttype=\"checkbox\"\n\t\t\t\tname=\"terms\"\n\t\t\t\tvalue=\"yes\"\n\t\t\t/\u003e\n\t\t\t\u003clabel for=\"test-terms-service\"\u003eAgree to terms of service?\u003c/label\u003e\n\n\t\t\t\u003cinput\n\t\t\t\tdata-jsv-validators=\"requiremin\"\n\t\t\t\tdata-jsv-min-selected=\"2\"\n\t\t\t\tid=\"test-terms-service-more\"\n\t\t\t\tdata-jsv-message-target=\"checkbox-invalid\"\n\t\t\t\tdata-jsv-validation-target=\"checkboxvalidate\"\n\t\t\t\ttype=\"checkbox\"\n\t\t\t\tname=\"terms\"\n\t\t\t\tvalue=\"more\"\n\t\t\t/\u003e\n\t\t\t\u003clabel for=\"test-terms-service-more\"\u003eAgree to more stuff?\u003c/label\u003e\t\t\n\t\t\t\u003cdiv class=\"validate-field-error-message\" id=\"checkbox-invalid\"\u003e\u003c/div\u003e\n\t\t\u003c/div\u003e\nLooks like:\n\n![enter image description here](https://i.imgur.com/KUlN1cy.png)\n\n\u003ca name=\"formlevelconfig\"\u003e\u003c/a\u003e\n## Form Configuration\n\nThe following data attributes can be added to the `\u003cform\u003e` tag\n\n| Attribute  | Description |\n|--------------------------|---|\n| `data-jsv-form=\"true\"` *(required)* | Attaches JSV to the form  |\n| `data-jsv-disable-icons=\"true\\|false\"` | Toggles field validation icons for all elements of the form  |\n| `data-jsv-disable-invalid=\"true\\|false\"` | Toggles disabling of the `\u003cbutton\u003e` element for valid and invalid form states  |\n| `data-jsv-form-invalid-message=\"[MESSAGE]\"` | Message to show in the form-level error container upon submit of an invalid form  |\n| `data-jsv-form-incomplete-tooltip=\"[MESSAGE]\"` | Message that appears in a tooltip when customer hovers the `\u003cbutton\u003e` element of an invalid form |\n| `data-jsv-submit-handler=\"[JAVASCRIPT FUNCTION NAME]\"` | If you want to handle submit of the form with Javascript, the specified function will be called upon submit of a valid form.  It's called with the arguments: `event`, `form` (the entire form element) and the string '`valid`'.  If no function is specified, the form submits normally.  |\n| `data-jsv-form-invalid-callback=\"[JAVASCRIPT FUNCTION NAME]\"` | If specified, the function is called when a form is submitted but is not valid.  Arguments: `event`, `form` (the entire form element) and the string '`invalid`'.  |\n| `data-jsv-form-valid-callback=\"[JAVASCRIPT FUNCTION NAME]\"` \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;| If specified, the function is called when a form becomes valid.  If used, be prepared for the possibility that it can be called many times.  Also, this is not to be used as a submit handler.  Arguments: `event`, `form` (the entire form element) and the string '`valid`'. \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;  |\n\n\u003ca name=\"fieldlevelconfig\"\u003e\u003c/a\u003e\n## Field Configuration\nThe following attributes can be added to the form field elements (like `\u003cinput\u003e)`:\n\n| Attribute | Description |\n|--|--|\n| `data-jsv-validators=\"[VALIDATORS]\"` (*required*)| One, or a comma-separated list of the [validations](#validationtypes) to add to this field.  If multiple, they are evaluated left to right |\n| `data-jsv-field-error-[VALIDATOR]=\"[MESSAGE]\"` | Specify the error message for a particular validator on this field.  See [Customizing Validation Messages](#validationmessages). |\n| `data-jsv-message-target=\"[ID]\"` | Specify a target for field invalid error messages. Required for use with radio buttons and multi-value checkboxes, but can also be used to override default automatic behavior on any field. [Details](#radiobuttons) |\n| `data-jsv-validation-target=\"[ID]\"` | Specify a target for field validation container. Recommended for use with radio buttons and multi-value checkboxes, but can also be used to override default automatic behavior on any field. [Details](#radiobuttons) |\n| `data-jsv-disable-icon=\"true\\|false\"` | Toggles disabling of valid or invalid icon for this field only. |\n| `data-jsv-debounce=\"[MILLISECONDS]\"` | Wait for [MILLISECONDS] before triggering any validations on this field. |\n| `data-jsv-field-invalid-callback-[VALIDATOR]=\"[JAVASCRIPT FUNCTION NAME]\"` | If specified, the function is called when [VALIDATOR] is triggered but is invalid. Arguments: `event`, `form`, `name`, name of the last validation performed, The string '`invalid`', the error message.|\n| `data-jsv-field-valid-callback-[VALIDATOR]=\"[JAVASCRIPT FUNCTION NAME]\"` \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;|  If specified, the function is called when [VALIDATOR] is triggered and returns valid. Arguments: `event`, `form`, `name`, name of the last validation performed, The string '`valid`'. \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; |\n\n\u003ca name=\"appconfig\"\u003e\u003c/a\u003e\n## App Configuration\nFurther configuration of JSV can be done by declaring a `validateOptions` object in the window (before JSV instantiates), with a '`cfg`' key:\n\n    var window.validateOptions = {\n    \tcfg: { // config options }\n    };\n\nAny [configuration settings](https://github.com/tarponjargon/js-simple-validations/blob/master/src/config.js) can be customized, though there are only a few that make sense to change:\n\n| Config Key | Description |\n|--|--|\n| `\"useCss\": true\\|false` | Toggles injection of the built-in CSS for UI valid/invalid states.  If you want to add your own CSS to the window, set to `false` |\n| `\"useTooltip\": true\\|false` | Toggles enabling of a tooltip that appears over the `\u003cbutton\u003e` element when the form is in an invalid state. |\n| `\"isValidColor\": \"[HEX COLOR]\"` | Customize the color for the field valid state.  Default: `#13bd3a` (green) |\n| `\"isInvalidColor\": \"[HEX COLOR]\"` | Customize the color for the field valid state.  Default: `#ff0000` (red) |\n| `\"isValidIcon\": \"[UNICODE]\"` | Customize the field valid icon unicode character.  Default: `\\\\2713` ([checkmark](https://www.compart.com/en/unicode/U+2713))|\n| `\"isInvalidIcon\": \"[UNICODE]\"` | Customize the field invalid icon unicode character.  Default: `\\\\2716` ([heavy multiplication X](https://www.compart.com/en/unicode/U+2716)) |\n| `\"fieldErrorFont\": \"[FONT DECLARATION]\"` | Use unified CSS font \"[shorthand](https://css-tricks.com/almanac/properties/f/font/)\" format.  Default: `normal 12px Helvetica, Arial, sans-serif`  |\n| `\"formShowMessages\": true\\|false` | If false, no form-level error messages will be shown when a form submit is attempted on an invalid form. |\n| `\"safeStringInput\": true\\|false` | If true, all inputted values are passed through a basic XSS sanitizer. |\n| `\"safeEndpoints\": true\\|false` | If true, endpoints can only be relative urls (i.e. no http:// allowed) |\n| `\"ajaxTimeout\": [MILLISECONDS]` | Time out an AJAX request after [MILLISECONDS].  Default: 8000 |\n| `\"debounceDefault\": [MILLISECONDS]` \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; | Wait time before any validations are triggered.  Allows user to type without being bothered by error messages.  Default: 300. \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;|\n\n\nNOTE If modifying config settings other than the ones above: [form](#formlevelconfig) and [field](#fieldlevelconfig)-level configuration data attributes always takes precedence over config settings.  \n\n\u003ca name=\"customvalidators\"\u003e\u003c/a\u003e\n## Custom Validators\nYou can write your own validators for JSV by declaring a `validateOptions` object in the window (before JSV instantiates), with a '`customValidators`' key:\n\n    var window.validateOptions = {\n    \tcfg: { // any app config options (see previous section) },\n    \tcustomValidators: {\n\t\t\t\"[VALIDATOR NAME]\": { // name of custom validator\n\t\t\t\t\"events\": [], // experimental - array of events this validator should fire on, [] = default\n\t\t\t\t\"validator\": function(field, value, validator) { // required\n\t\t\t\t\treturn new Promise(function(resolve, reject) { // required\n\n\t\t\t\t\t\t// start custom validator code\n\t\t\t\t\t\tif (true) {\n\t\t\t\t\t\t\tresolve(); // required();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treject(\"[MESSAGE]\"); // required, include message in reject\n\t\t\t\t\t\t}\t\t\n\t\t\t\t\t\t// end custom validator code\n\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n    \t}\n    };\n\nValidations are promises, so the custom validation must also be a promise with a `resolve` and `reject`.  See the bottom of the [demo form](https://github.com/tarponjargon/js-simple-validations/blob/master/demo.html) for a working example of a custom validator.\n\n\u003ca name=\"callbacks\"\u003e\u003c/a\u003e\n## Callbacks\n\nCallbacks to custom window functions can be configured for the following events:\n\n - Field validator returns invalid\n - Field validator returns valid\n - Form becomes valid\n - Form submit occurs, form is invalid\n - Form submit occurs, form is valid\n\nSee [form](#formlevelconfig) and [field](#fieldlevelconfig) configuration to see how to specify callback functions, and how they are triggered.  Also see examples of usage at the bottom of the [demo form](https://github.com/tarponjargon/js-simple-validations/blob/master/demo.html).\n\nJSV listens for for and prevents the form `submit` event to perform a final validation.  If the form is valid, it continues `submit` and the submission happens using the default `method` and `action` on the form\n\n**Use cases**\n\n*AJAX form submit* - To use AJAX to submit the form, you'll want to configure `data-jsv-submit-handler=\"[FUNCTION]\"` on the `\u003cform\u003e` element.  When the form `submit` happens and the form is valid, the function specified in `data-jsv-submit-handler` is called with the arguments: `event` object, `form` object and the string '`valid`'.\n\n*Username does not exist* - Let's assume you're working on a user login form and you want to set up an [AJAX validator](#ajaxvalidator) to check that the username entered exists before the form is even submitted.  A potential use for the \"field invalid\" callback on the ajax validator is: if the username does not exist, call a function that performs UI changes to direct the user to the sign-up form.\n\n\u003ca name=\"testing\"\u003e\u003c/a\u003e\n## Testing\nThere is an E2E test suite that uses Jest and Puppeteer.  To perform the tests on the demo form, you can run the following commands:\n\n    git clone https://github.com/tarponjargon/js-simple-validations.git\n\tcd js-simple-validations\n    npm install\n    npm test\n\n\u003ca name=\"acknowledgements\"\u003e\u003c/a\u003e\n## Acknowledgements\nThe idea behind JSV is to basically mimic some of the functionality of [ember-cp-validations](https://github.com/offirgolan/ember-cp-validations) using vanilla JS.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftarponjargon%2Fjs-simple-validations","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftarponjargon%2Fjs-simple-validations","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftarponjargon%2Fjs-simple-validations/lists"}