const
customValidator
=
function
(
)
{
return
{
validate
:
function
(
input
)
{
// input.element presents the field element
// input.elements presents all field elements
// input.field is the field name
// input.value is the field value
// input.options is the validator options
// Has to return an object
return
{
// Required property
// valid: true indicates that the field passes your custom validator
// valid: false, otherwise.
valid
:
...
,
// Optional: include a custom error message
message
:
...
,
// Optional: include a meta data that can be used by the library later
meta
:
{
key
:
value
,
...
}
,
}
;
}
,
}
;
}
;
const
strongPassword
=
function
(
)
{
return
{
validate
:
function
(
input
)
{
const
value
=
input
.
value
;
if
(
value
===
''
)
{
return
{
valid
:
true
,
}
;
}
// Check the password strength
if
(
value
.
length
<
8
)
{
return
{
valid
:
false
,
}
;
}
// The password does not contain any uppercase character
if
(
value
===
value
.
toLowerCase
(
)
)
{
return
{
valid
:
false
,
}
;
}
// The password does not contain any uppercase character
if
(
value
===
value
.
toUpperCase
(
)
)
{
return
{
valid
:
false
,
}
;
}
// The password does not contain any digit
if
(
value
.
search
(
/
[0-9]
/
)
<
0
)
{
return
{
valid
:
false
,
}
;
}
return
{
valid
:
true
,
}
;
}
,
}
;
}
;
FormValidation.validators
namespace
const
strongPassword
=
function
(
)
{
...
}
;
// Register the validator
FormValidation
.
validators
.
checkPassword
=
strongPassword
;
// Use new validator
FormValidation
.
formValidation
(
document
.
getElementById
(
'demoForm'
)
,
{
fields
:
{
pwd
:
{
validators
:
{
notEmpty
:
{
message
:
'The password is required and cannot be empty'
}
,
// checkPassword is name of new validator
checkPassword
:
{
message
:
'The password is too weak'
}
,
}
}
}
,
}
)
;
checkPassword
which is implemented by the
strongPassword
function. Since the validators are distinct by the names, the new validator name (
checkPassword
, in the example above) has to be different with
built-in validators
.
FormValidation
namespace doesn't exist. For example, when the library is used with ES6 module.
const
strongPassword
=
function
(
)
{
...
}
;
// Use new validator
FormValidation
.
formValidation
(
document
.
getElementById
(
'demoForm'
)
,
{
fields
:
{
pwd
:
{
validators
:
{
notEmpty
:
{
message
:
'The password is required and cannot be empty'
}
,
// checkPassword is name of new validator
checkPassword
:
{
message
:
'The password is too weak'
}
,
}
}
}
,
}
)
// Register the validator
.
registerValidator
(
'checkPassword'
,
strongPassword
)
;
false
if the password doesn't satisfy any of conditions we define. The limitation here is that the user don't know which condition the password doesn't pass. It informs the same
The password is too weak
message all the times.
const
customValidator
=
function
(
)
{
return
{
validate
:
function
(
input
)
{
// ... Do your logic checking
if
(
...
)
{
return
{
valid
:
true
,
// or false
message
:
'The error message'
,
}
;
}
return
{
valid
:
false
,
// or true
message
:
'Other error message'
,
}
;
}
,
}
;
}
;
const
strongPassword
=
function
(
)
{
return
{
validate
:
function
(
input
)
{
const
value
=
input
.
value
;
if
(
value
===
''
)
{
return
{
valid
:
true
,
}
;
}
// Check the password strength
if
(
value
.
length
<
8
)
{
return
{
valid
:
false
,
message
:
'The password must be more than 8 characters long'
,
}
;
}
// The password does not contain any uppercase character
if
(
value
===
value
.
toLowerCase
(
)
)
{
return
{
valid
:
false
,
message
:
'The password must contain at least one upper case character'
,
}
;
}
// The password does not contain any uppercase character
if
(
value
===
value
.
toUpperCase
(
)
)
{
return
{
valid
:
false
,
message
:
'The password must contain at least one lower case character'
,
}
;
}
// The password does not contain any digit
if
(
value
.
search
(
/
[0-9]
/
)
<
0
)
{
return
{
valid
:
false
,
message
:
'The password must contain at least one digit'
,
}
;
}
return
{
valid
:
true
,
}
;
}
,
}
;
}
;
const
result
=
zxcvbn
(
password
)
;
// The password strength score. See the following table for available values
result
.
score
;
// Explain why the password is weak. "This is a top-10 common password", for example
result
.
feedback
.
warning
;
score
is an integer number between 0 and 4 that indicates the strength level:
| Score | Description |
|---|---|
| 0 | Too guessable: risky password |
| 1 | Very guessable: protection from throttled online attacks |
| 2 | Somewhat guessable: protection from unthrottled online attacks |
| 3 | Safely unguessable: moderate protection from offline slow-hash scenario |
| 4 | Very unguessable: strong protection from offline slow-hash scenario |
const
strongPassword
=
function
(
)
{
return
{
validate
:
function
(
input
)
{
// input.value is the field value
// input.options are the validator options
const
value
=
input
.
value
;
if
(
value
===
''
)
{
return
{
valid
:
true
,
}
;
}
const
result
=
zxcvbn
(
value
)
;
const
score
=
result
.
score
;
const
message
=
result
.
feedback
.
warning
||
'The password is weak'
;
// By default, the password is treat as invalid if the score is smaller than 3
// We allow user to change this number via options.minimalScore
const
minimalScore
=
input
.
options
&&
input
.
options
.
minimalScore
?
input
.
options
.
minimalScore
:
3
;
if
(
score
<
minimalScore
)
{
return
{
valid
:
false
,
// Yeah, this will be set as error message
message
:
message
,
meta
:
{
// This meta data will be used later
score
:
score
,
}
,
}
;
}
}
,
}
;
}
;
<
input
type
=
"
password
"
class
=
"
form-control
"
name
=
"
pwd
"
autocomplete
=
"
off
"
/>
<
div
class
=
"
progress mt-2
"
id
=
"
progressBar
"
style
=
"
opacity
:
0
;
"
>
<
div
class
=
"
progress-bar progress-bar-striped progress-bar-animate
"
style
=
"
width
:
100
%
"
>
div
>
div
>
FormValidation
.
formValidation
(
document
.
getElementById
(
'demoForm'
)
,
{
fields
:
{
...
}
,
plugins
:
{
...
}
,
}
)
.
registerValidator
(
'checkPassword'
,
strongPassword
)
.
on
(
'core.validator.validated'
,
function
(
e
)
{
if
(
e
.
field
===
'pwd'
&&
e
.
validator
===
'checkPassword'
)
{
const
progressBar
=
document
.
getElementById
(
'progressBar'
)
;
if
(
e
.
result
.
meta
)
{
// Get the score which is a number between 0 and 4
const
score
=
e
.
result
.
meta
.
score
;
// Update the width of progress bar
const
width
=
(
score
===
0
)
?
'1%'
:
score
*
25
+
'%'
;
progressBar
.
style
.
opacity
=
1
;
progressBar
.
style
.
width
=
width
;
}
else
{
progressBar
.
style
.
opacity
=
0
;
progressBar
.
style
.
width
=
'0%'
;
}
}
}
)
;