const $vv = require('path_to_$vv')
//$vv.init => return Validator Instance
//$vv.addRule
//$vv.dictionary
//$vv.isValidAll
//$vv.validateAll
//$vv.observeAll
for ie9 or above
all password input are replaced with text input for visual check
if you have any problem, let me know at kelly.kh.woo@gmail.com
reset methods resets dirty and touched as well
<label class="input-row">
<span class="input-label">required
<span class="sym-required"></span></span>
<p><input type="text" class="ex0-a"></p>
</label>
<label class="input-row">
<span class="input-label">email</span>
<p><input type="text" class="ex0-b"></p>
</label>
<label class="input-row">
<span class="input-label">password</span>
<p><input type="text" class="ex0-c"></p>
</label>
<label class="input-row">
<span class="input-label">minLen</span>
<p><input type="text" class="ex0-d"></p>
</label>
<label class="input-row">
<span class="input-label">maxLen</span>
<p><input type="text" class="ex0-e"></p>
</label>
<label class="input-row">
<span class="input-label">minNum</span>
<p><input type="number" class="ex0-f"></p>
</label>
<label class="input-row">
<span class="input-label">maxNum</span>
<p><input type="number" class="ex0-g"></p>
</label>
var a = $vv.init('.ex0-a', {
rules: [ 'required'],
event: 'input'
})
var b = $vv.init('.ex0-b', {
rules: [ 'email' ]
})
var c = $vv.init('.ex0-c', {
rules: [ 'password' ]
})
var d = $vv.init('.ex0-d', {
rules: [ {minLen: 10} ]
})
var e = $vv.init('.ex0-e', {
rules: [ {maxLen: 5} ]
})
var f = $vv.init('.ex0-f', {
rules: [ {minNum: 3000} ]
})
var g = $vv.init('.ex0-g', {
rules: [ {maxNum: 50} ]
})
<label class="input-row">
<span class="input-label">custom password</span>
<p><input type="text" class="ex1-a"></p>
</label>
<label class="input-row">
<span class="input-label">confirm</span>
<p><input type="text" class="ex1-b"></p>
</label>
$vv.addRule({
pwHasLower: function (value) {
return /[a-z]/.test(value)
},
pwHasUpper: function (value) {
return /[A-Z]/.test(value)
},
pwHasDigit: function (value) {
return /[0-9]/.test(value)
},
pwHasSpecial: function (value) {
return /[@$!%*?+\-_]/.test(value)
}
})
$vv.dictionary({
pwHasLower: 'LowerCase',
pwHasUpper: 'UpperCase',
pwHasDigit: 'Digits',
pwHasSpecial: 'Special Character(@$!%*?+-_)'
})
var a = $vv.init('.ex1-a', {
rules: [ 'required', 'pwHasLower', 'pwHasUpper', 'pwHasDigit', 'pwHasSpecial', {
minLen: 8,
maxLen: 14
} ],
event: 'input',
display: function (errors) {
var str = '';
if ( errors.length ) {
var err = errors.reduce(function (p, c) {
if ( /^pwH/.test(c[ 0 ]) ) {
p[ 0 ].push(c)
} else {
p[ 1 ].push(c)
}
return p
}, [ [], [] ]);
str = err[ 0 ].length ? 'it needs ' + err[ 0 ].reduce(function (p, v) {
p.push('' + v[ 1 ] + '');
return p;
}, []).join(', ') + '
' : '';
str += err[ 1 ].map(function (v) {
return '' + v[ 1 ] + '
';
}).join('');
}
this.showMessage(str);
}
})
var b = $vv.init('.ex1-b', {
rules: [ {
'confirm': a
} ]
})
<label class="input-row">
<span class="input-label">number(Float, Int) only</span>
<p><input type="text" class="ex2-a"></p>
</label>
<label class="input-row">
<span class="input-label">add comma after 3 digits (like cash)</span>
<p><input type="text" class="ex2-b"></p>
</label>
var a = $vv.init(document.querySelector('.ex2-a'), {
rules: [ 'required', { minNum: 200 } ],
formatter: function (value) {
return value.replace(/(^0(?!\.)|[^\d.])/g, '').replace(/^(\d+\.\d*)(\.)$/, '$1') || 0;
}
})
var a = $vv.init(document.querySelector('.ex2-b'), {
rules: [ 'required', { minNum: 1000 } ],
formatter: function (value) {
return value.replace(/\D|^0/g, '').replace(/\B(?=(\d{3})+(?!\d))/g, ',') || 0;
}
})
refineValue removes -, so minlength calculates only numbers when it validates
<label class="input-row">
<span class="input-label">mobile number(maxLen:11)</span>
<p><input type="text" class="ex4-a"></p>
</label>
<div style="text-align: center;padding: 30px 0 0">
<button type="button" class="get-value-button btn-green">getValue</button>
</div>
var a = $vv.init(document.querySelector('.ex4-a'), {
rules: [ 'numeric', {maxLen: 11}],
formatter: function(value){
return value.replace(/[^0-9]/g,'').replace(/\B(?=\d{4}\b)/,'-')
.replace(/\B(?=\d{4}-\d{4}\b)/,'-')
},
refineValue:function(value){
return value.replace(/-/g,'');
}
});
var btn= document.querySelector('.get-value-button')
btn.addEventListener('click', function () {
alert('the value returned from refineValue : '+a.getValue());
})
<label class="input-row">
<span class="input-label">basic text<span class="sym-required"></span></span>
<input type="text" class="a">
</label>
<dl class="input-row">
<dt class="input-label">radio<span class="sym-required"></span></dt>
<dd class="input-inline col3">
<label class="input-row"><input type="radio" name="hey" class="b"><span
class="input-label-inline">radio1</span></label>
<label class="input-row"><input type="radio" name="hey" class="b1"><span
class="input-label-inline">radio2</span></label>
<label class="input-row"><input type="radio" name="hey" class="b2"><span
class="input-label-inline">radio3</span>
</label>
<div id="radioMsg" class="msg-box"></div>
</dd>
</dl>
<label class="input-row">
<span class="input-label">select<span class="sym-required"></span></span>
<select class="c">
<option value="">default</option>
<option value="hey">ddd</option>
</select>
</label>
<label class="input-row">
<span class="input-label">checkbox<span class="sym-required"></span></span>
<input type="checkbox" class="d"><span class="input-label-inline">check please</span>
</label>
<div style="text-align: center;padding: 30px 0 0">
<button type="button" class="validate-all btn-green">ValidateAll</button>
<button type="button" disabled class="observe-all btn-green">ObserveAll</button>
</div>
var a = $vv.init('.a', {
rules: [ 'required' ],
formatter: function (value) {
// return value;
}
});
var b = $vv.init('.b', {
rules: [ 'required' ],
msgBox: document.querySelector('#radioMsg')
})
var c = $vv.init('.c', {
rules: [ 'required' ],
formatter: function (value) {
return value;
}
})
var d = $vv.init('.d', {
rules: [ 'required' ]
})
//reactive validate
function suffice () {
this.removeEventListener('click', suffice, false);
this.classList.add('btn-processing');
var $this = this
setTimeout(function () {
alert('Thank you for the submit');
$vv.resetAll(a, b, c, d);
$this.classList.remove('btn-processing')
}, 2000)
}
var btnObserve = document.querySelector('.observe-all');
btnObserve.addEventListener('click',function () {
b.reset();
alert('unchecked radio button');
}, false);
$vv.observeAll(a, b, c, d, function (r, a, b, c, d) {
if ( r ) {
btnObserve.disabled = false;
} else {
btnObserve.disabled = true;
}
})
//manual validate
var btnValidate = document.querySelector('.validate-all');
var isValidating = false;
btnValidate.addEventListener('click', validateForm, false)
function validateForm (e) {
if ( isValidating ) {
return;
}
var valid = $vv.validateAll(a, b, c, d);
if ( valid.success ) {
isValidating = true;
btnValidate.classList.add('btn-processing');
setTimeout(function () {
alert('thank you for the submit');
$vv.resetAll.bind(null, a, b, c, d);
btnValidate.classList.remove('btn-processing');
isValidating = false;
}, 2000)
} else {
valid.failedFields[ 0 ].$el.focus();
}
}
const $vv = require('path_to_$vv')
//$vv.init => return Validator Instance
//$vv.addRule
//$vv.dictionary
//$vv.isValidAll
//$vv.validateAll
//$vv.observeAll
//$vv.init(element, options)
let input = $vv.init('.a', {
rules: [ 'required', 'password',
{
'confirm': validatorInstance,
'minLen': 4
//object can include parameters
} ],
msgBox: domObject,
display: function(errors){
// this refers to Validator Object
},
formatter: function(value) {
},
refineValue: function(value) {
},
event: 'change'
});
init method returns Validator Instance
var validateRule = function(value, args) {
//this binds to Validator Object
return boolean
}
//how to add rules
$vv.addRule(name, validateRule, errMessage)
//multiple
$vv.addRule({name1: validateRule1,
name2: validateRule2,
name3: validateRule3})
addRule adds global rules, is able to pass multiple rules as an object and in this case can't put messages together
var returnMessageFn = function(rulename, dictionary) {
return 'error message to be displayed';
}
var returnMessageStr ='error message can be string data';
var errMessage = returnMessageFn || returnMessageStr;
//how to add error message
$vv.dictionary(name, errMessage)
//also multiple can be applied by passing object of messages
$vv.dictionary({name1: errMessage1,
name2: errMessage2,
name3: errMessage3})
dictionary adds global errorMessages and error message can be string or function returning string.
is able to pass multiple messages as an object
var a = $vv.init(...)
var b = $vv.init(...)
var btn = document.querySelector('button')
btn.addEventListener('click',function(){
if($vv.isValidAll(a,b)) {
...
}
}, false)
isValidAll doesn't provoke error messages
it simply returns the value in form of boolean
var a = $vv.init(...)
var b = $vv.init(...)
var btn = document.querySelector('button')
btn.addEventListener('click',function(){
var valid = $vv.validateAll(a,b)
if( valid.success) {
...
} else {
...
}
}, false)
it provokes all the error messages regardless its dirty or touched status
var a = $vv.init(...)
var b = $vv.init(...)
var btn = document.querySelector('button')
$vv.observeAll(a,b, function(valid) {
if(valid) {
btn.classList.add('btn-red')
} else {
btn.classList.remove('btn-red')
}
})
observeAll does reactive work to its validator instances' value
take one function to call when value changes,
can be used for UI mutation
//default config object
default = {
boxClass: 'msg-box', // msg-box class, no padding, no styling should be applied
msgClass: 'msg-box-msg', // div inside msg-box
errorClass: 'is-error',
interval: 500,
waiver: 'dirty',
event: 'change',
//_config.countBlank:false => uncount errors(except required) when string is ''
getDefaultMsg: function (rule) {
return rule + ' : entered wrong'
},
display: function (errors) {
// override function to display error message
}
}
$vv.config({event:'input',countBlank:true....})