Easily customizable library for validation
scenarios in svelte
components.
Need to validate just a few simple inputs? Or need to build a huge form with dynamic steps? No problems. Svelidation was born for it!
create an issue and describe your thoughts. Anything possible. Welcome!
Something doesn't work as expected? Any functionality is missing? Or, maybe, you have an idea/suggestion to make Svelidation better? Feel free toQuick example
; // 1. create an instanceconst createForm createEntry = ; // 2. create a validation modelconst errorsStore valueStore useInput = ;
<!-- 3. use it in template --> {#if $errorsStore.includes('required')} This field is required {/if} Submit
Check more examples on the demo page
install
npm i -S svelidation
FAQ
What a dollar sign ($) means?
This is a specific Svelte reactive statements. Check here details
How can I use my own email regExp for validation?
Easy. Just update email type rule with ensureType API
;const createEntry = ; // extend existing type with custom rule;
How can I create simple email+password form without all that complicated stuff?
{#if $emailErrors.length}Field is invalid{/if} {#if $passwordErrors.length}Field is invalid{/if} submit
How to activate validation just on form submit without any side-inputs-events?
The only thing you need to do - disable input events, because submit validation works by default
<!-- html -->
How to validate multi-steps form with different inputs on each step?
Nothing special to do here. Just create all inputs entries and bind it to inputs with use
directive, and svelidation will validates only visible (created in DOM) inputs. Check DYNAMIC STEPS example
What if I don't have DOM? Can I validate pure data?
Yes. You have few options
- Use
includeAllEntries
option
const validate validateValueStore createEntry = ;const errors1 value1 = ;const errors2 value2 = ; // validate all created entriesconst allErrors = ; // or validate specific entry valueconst firstEntryErrors = ;
- Use
true
as parameter invalidate
api
const validate = ; // ...create some entries // validate all created entriesconst allErrors = ;
How can I clear errors manually?
Use clearErrors API
How can I get all entries values not just after success validation?
Use getValues API
How to hide warnings in the console?
How can I create my own validation rule or custom type?
Use ensureRule / ensureType API
Do I have an option to avoid set required: true to every field?
Yes. Use presence: 'required' option
Is possible to avoid false positive validation of spaces-only-strings, but still to make users possible to use spaces at the start or end of their passwords (or another specific field)?
Yes. That is why trim option was created.
If you set trim: true
, validator will trim all values before check. It will not change value itself, but trim it for check purpose.
Then, you can set trim: false
for specific field, to avoid trim.
const createEntry = ; // trim all values before validationconst passwordEntry = ;
And, of course, you are able to do an opposite. Leave trim
options default (false), and set
trim: true`for specific field
This lib can't do the things what I need
Not a problem! Create an issue and describe your needs. Will check this out
basic types
Combination of type/rules is using in here
string
check string length
{ type: 'string', min: 3 }
{ type: 'string', max: 3 }
{ type: 'string', between: [4, 10] }
email
{ type: 'email' }
number
check number value
{ type: 'number', min: 3 }
{ type: 'number', max: 3 }
{ type: 'number', between: [4, 10] }
boolean
{ type: 'boolean' }
array
check array length and specific element
{ type: 'array', min: 3 }
{ type: 'array', max: 3 }
{ type: 'array', includes: 3 }
global rules
equal
equality with value (in case of array it sorta and stringifies it), could take a function as equal value
{ type: 'string', equal: 'my-custrom-string' }
{ type: 'string', equal: value => (value === myFunction()) }
match
match textual value form by regExp
{ type: 'number', match: '202\d' }
required
check value exists
{ type: 'email', required: true }
options
// default values;
-
validateOnEvents: { [key: string]: boolean }
- object of input events to validate input value
- possible events:
change
,input
,blur
-
clearErrorsOnEvents: { [key: string]: boolean }
- object of events to clear errors
- possible events:
reset
,focus
-
listenInputEvents: number
- specific option for control input events
0
: dont allow input events1
: allow input events always2
: allow input events after first validation run
- specific option for control input events
-
presence: string
- Default inputs presence. If we set it to
required
- all inputs will be validated as required by default - This options equals
optional
by default, this means that all fields in validation are optional and will be validated in case of having value, or having another validation rules
- Default inputs presence. If we set it to
-
trim: boolean
- allow validator trim textual values before check
- (!!!) it doesn't trim value itself, just for check purpose
-
includeAllEntries: boolean
- By default validation works for entries that were assigned with inputs by
use
svelte directive. This option makes possible to validate ALL entries in validation
- By default validation works for entries that were assigned with inputs by
-
useCustomErrorsStore(errorsArray, entryParams): errorsStore
- optional method to make possible to use custom errorsStore structure. By default this is array of strings. This method can override default store with any you want
errorsArray
- default array of errors stringsentryParam
- (check here)- check
CUSTOM ERRORS
example on demo page
-
warningsEnabled: boolean
- option that makes warnings in dev mode visible.
true
by default
- option that makes warnings in dev mode visible.
-
getValues(): values
- optional method to build own values result
- default
getValues
implementation returnsMap
structureMap{ [entryParams.id || entryParams]: value }
- example#1
{ type: 'string' }
getValues
result will looks like this:Map{ { type: 'string' }: '' }
- example#2
{ type: 'string', id: 'login' }
getValues
result will looks like this:Map{ login: '' }
entries
- array of entries params and values- result of
getValues
will passed to onSuccess option for form increateForm
API (check here) - check two
get values
examples on the demo page
validateOnEvents
, clearErrorsOnEvents
, presence
and trim
behavior could be overrided by any input for itself in createEntry
API (check here)
validation level API
;const createEntry createEntries createForm validateValueStore validate clearErrors getValues } = ;
createEntry(entryParams)
Create validation entry
const errorsStore valueStore inputFunctionForUse = ;
errorsStore
, valueStore
used for bind errors and value stores in templates. One more time. THIS IS SVELTE STORES. You might see something like errors[]
below in this readme - this is just a array with strings
inputFunctionForUse
function for use
svelte directive on input, to assign its events to validation process
<!-- or -->
This is the place where clearErrorsOnEvents
and validateOnEvents
options could be overrided for specific input
entryParams
Check list of types/rules here
// entryParams type // required value // initial value, required for some types of fields id // optional param for getValues method // other rules, like min/max/required... trim // works like trim option for createSvelidation function, but on input level required optional // makes possible to override presence option of createSvelidation function
createEntries(entryParams[] | {[key: string]: entryParams})
Additional way to create a few entries at the time
const first: firstErrorsStore firstValueStore firstInput second: secondErrorsStore secondValueStore secondInput } =
const firstErrorsStore firstValueStore firstInput secondErrorsStore secondValueStore secondInput =
createForm
Function for form use
This function makes subscribe on submit/reset form events for validation/clearErrors by default
<!-- or -->
An object with callbacks could be used as param in use
function
onSubmit(submitEvent, errors[])
- every form submit attempt. errors[]
- array of all errors store values. Not array of stores, but array of store errors.
onFail(errors[])
- on every failed validation (when errors.length > 0
)
onSuccess(values)
- when there aren't any errors. Get values
(check here) as result
clearErrors(includeNoFormElements: boolean)
Manually clear all errors stores
;
Only argument same as in validate
validate(includeNoFormElements: boolean): allValidationErrors[]
Manually validate stores
const allErrors = ;
Only argument makes possible to validate all created entries.
Without this param validation will check inputs assigned to nodes only (inputFunctionForUse
- check createEntry
API)
Return array of all errors store values
validateValueStore(valueStore): errors[]
Manually validate value store
const emailErrorsStore emailValueStore = ;const errors = ; // array of string, not errorsStores!!!
Returns errors store value
getValues(entries): values
advanced API
;
ensureRule(ruleName: string, ruleFunction)
ruleFunction: (value, entryParams): boolean
Allows to add your own global (will be available for any type) rules
;const createEntry validate = ; const myRuleFunction = { // entryParams === { type: 'string'... } // entryParams.myRule === 'my rule value...' return entryParamstype === 'string';} ; const stringErrors stringValue = ; const numberErrors numberValue = ; console; // [{ number: ['myRule'] }]
resetRule(ruleName?: string)
Remove custom rule. If calls without ruleName
- it will remove all custom global rules
;const createEntry validate = ; ; const numberErrors numberValue = ; console; // [{ number: ['myRule'] }];console; // [] - there in no rule like myRule, so no validation, no errors
ensureType(typeName: string, typeRules)
typeRules: { [key: string]: ruleFunction }
ruleFunction: (value, entryParams): boolean
Extend existing/add new type to validator. In case of creating new type, there is one clause. typeRules
has to have method named type
. This is a basic and required method for every type and it calls everytime we validate type. And if it return false
- current entry validation stops with type
error
;const createEntry validate validateValueStore = ; // extend existing type with custom rule; const stringErrors stringValue = ; console; // ['between5and10'] // create new type with its own rules; const myErrors myValue = ; console; // ['anotherRule', 'min']
resetType(typeName?: string)
Work same as resetRule
, but on the type level
omg :) I hope noone will need to use methods below
Ok, so what are you saying? Spies? O_o
Yes. Spies. Spy.
By design, this is a function to observe validation process and get into it.
Spy can observe types, global rules, specific rule of specific type. Spy can observe everything! Literally. Just create a global spy and it will observe every validation. Every rule, every type, everything will be in its hands.
If you need to prevent something, or update value somehow - special spy is the place.
You need to know just one thing. Spy has god power, but it has to give this power to the next spy. And there will always be next spy, even if its not your spy.
So, lets dive into examples
addSpy(spyFunction, spyParams?): removeSpyFunction
Method to add spy in the validation process
spyFunction(value, entryParams, next, abort): errors[]
next(nextValue, mixedParams?: entryParamsLike)
abort()
spyParams?: { ruleName?: string, type?: string }
;const createEntry validateValueStore = ; const stringErrors stringValue = ; const removeSpy = ; ;// LOG: >> 'spying!'
First of all, take a look at the line with next(value)
call. This is VERY IMPORTANT LINE in spies paradigm. Remember? Spy has god power, but it has to give this power to next spy. This.
next(value, params)
- is the function witch spy have to call with any value spy wants. This new value will be taken by next validation rules or another spies (until type validation ends). Almost same with the params. But params will be merged with original for next validators. So the value will replace the original one, params will be merged
And it can returns errors, that will be merged with validation errors
;const createEntry validateValueStore = ; const stringErrors stringValue = ; const removeSpy = ; ; console;// ["error-from-spy", "myRule"]// first is from spy, second from our rule, that always return false
What happens if we will not call next
? Validation process will stop and return existing errors for the moment.
abort()
method - its an emergency brake. If it calls - validation stop and return nothing.
And last, but not least spyParams?: { ruleName?: string, type?: string }
. This is an optional object to describe spy's field of responsibilty.
{ ruleName: 'min', type: 'string' }
- spy for specific rule in specific type. Will be called each time, when current pair rule-type check{ ruleName: 'match' }
- spy for specific rule. Will be called with eachruleName
check{ type: 'array' }
- spy for EVERY validation of specific type. Will be called once pertype
.undefined
- spy for everything. Will be called once before every validation.
So, for example if you create spies:
; // 1; // 2; // 3; // 4 // run validation for a { type: 'string', min: 5 }// each spy will be called once // run validation for a { type: 'string', min: 5 }, { type: 'string', max: 5 }// 3 and 4 will be called once.// 1 and 2 - twice, because we validate 2 entries (1st spy), and 2 strings (2nd spy) // run validation for a { type: 'string', min: 5 }, { type: 'email', required: true }// 1 - twice, because we validate 2 entries// 2, 3 and 4 will be called once
Last thing about the spies.
If you create a spy that will observe type
method of any type - remember, that returning an error from that spy will stop current entry validation because type
method fails, so there is no point to continue validation
To remove your spy - just call removeSpyFunction
that returns addSpy
method.
And to remove all spies...
removeSpies(params?: { type?: string, ruleName?: string })
This is an easy one after addSpy
:). It just removes all spies depends on params.
{type: 'string', ruleName: 'min'}
- remove all spies for specific rule in specific type{runeName: 'match'}
- remove all spies for specific global rule{type: 'string'}
- remove all spies for specific typeundefined
- remove all spies at all
scripts
npm run build
- build demo and library files intodist
npm run dev
- run dev server from dist folder with demo page by defaultnpm run test
- run all tests on production version of buildnpm run e2e
- e2e testing of lib file fromdist
npm run e2e:dev
- dev server frome2e/dist
folder with tests name in paramsnpm run unit
- unit testing ofspec.js
files inlib
npm run unit:dev
- dev server for unit testingnpm run eslint
- lint source code
TODO
- demo examples
- complete readme
- unit tests
- e2e tests
- builder demo
- eslint
- add comments in the code