Curious, but not 100% on whether this is what you're looking for? Try vuejs-form out for yourself before installing -- here's some live examples ready for you to tinker away at!
importformfrom'vuejs-form'exportdefault{data: ()=>({form: form({email: '',password: '',password_confirmation: ''}).rules({email: 'email|min:5|required',password: 'required|min:5|confirmed'}).messages({'email.email': 'Email field must be an email (durr)','password.confirmed': 'Whoops, :attribute value does not match :confirmed value',}),}),methods: {submit(){if(this.form.validate().errors().any())return;alert('Success, form is validated!');console.log('form all(): ',this.form.all());console.log('form except(): ',this.form.except('password_confirmation'));},}}
importformfrom'vuejs-form'exportdefault{data: ()=>({form: form({email: '',password: '',confirm_password: ''}).rules({email: 'email|min:5|required',password: 'same:confirm_password',confirm_password: 'min:6|required',}).messages({'email.required': ':attribute is required','email.email': ':attribute must be a valid email','email.min': ':attribute may not have less than :min characters','password.same': 'Whoops, :attribute does not match the :same field',}),}),watch: {/*-------------------------------------------------------------- * When Should Your Form "Validate", Providing Error Messages? *-------------------------------------------------------------- * Form validates every time form data is updated. To * display errors on form submit, remove watcher & * move "this.form.validate()" over to submit() *-------------------------------------------------------------- */['form.data']: {deep: true,immediate: false,handler: (now,old)=>{this.form.validate();},}},methods: {failed(){console.log('errors: ',this.form.errors().all());},passed(){console.log('data: ',this.form.all());console.log('wrapped data: ',this.form.wrap('data'));},submit(){returnthis.form.errors().any() ? this.failed() : this.passed();},}}
All rules have global default error messages shown when rule fails validation.
Optionally, you are able to override the global defaults rule messages
Simply use the form(data).rules(set).messages({ '{field}.{rule}': 'custom message for failing rule on field' });
letdata={email: ['required','email']}form({email: 'chad'}).rules({email: ['required','email']}).messages({'email.required': 'Email field is called email, needa make it an email (Hence Email Field Name, dont worry ~ we added validation just in case you forgot to make the email field an email)'})
Check current form data against associated form rules
IMPORTANT: form MUST call validate() method before retrieving current errors
COMMON GOTCHA!!!!
This wont get the current form errors
The form.validate() method was Never called
letdata={name: ''};letrules={name: 'required'};form(data).rules(rules).errors().list();// --------------------------------------------// Form SHOULD fail, but errors list is empty// --------------------------------------------// Output: []// --------------------------------------------
What's the reason?
Retrieving errors before validating form data
would retrieve our error messages Api instance, but it hasn't been filled with our forms error messages.
form.validate() compares form data against form rules, populating our form errors with failing rule messages.
Validate THEN resolve the errors (Using forms fluent api)
letdata={name: ''};letrules={name: 'required'};form(data).rules(rules).validate().errors().list();// Output: ['Name field is required']// Again, we'll need to validate before retrieving our // errors to validate that the values passes our given rulesform.name='hello world';form.errors().list();// Output: ['Name field is required']form.validate().errors().list();// Output: [];
Fluently call validate() before calling errors() is simple and to the point.
At first, this may seem like a tedious extra step. Many may wonder why we don't simply auto-validate the data?
Reason for form.validate().errors() Instead of simply form.errors() triggering the validation.
Some other developers may only want to validate data on form submission
Many validation rules can be abstracted using the form Api to simply disable the ability to submit a button
EX:
Then within submit() method simply run if (this.form.validate().errors().any()) return;
That allows the option to set up vuejs-form more like a traditional Form, and avoid many complexities that come along with maintaining the status of our reactive state
etc...
Form Has Validator
Determine if form has a validator instance attached to it
form.hasValidator();// true or false
Form Set Validator
Set Validator Instance
Optionally import the validator instance itself, and extend its functionality validator().macro(add_method, method).
Then use form macros to track the current step form.macro(add_method, method).
vuejs-validators.js Also has validator life cycle hooks documented that are available here, but only documented within vuejs-form.js. Very helpful for multi-step forms
This form rule does not verify that the input is of the "integer" variable type, only that the input is a string or numeric value that contains an integer.
Output:
[
'name field is required',
'email field must be an email address',
'email field is required'
]
Set Errors
Set all errors
letdata={name: ''};letrules={name: 'required'};form(data).rules(rules).validate();form.errors().list();// Output: ['name is a required field']form.errors().set({notice: ['set this random error message']});form.errors().list()
Output: ['set this random error message']
Forget Errors
Forget errors and reset them to empty
letdata={name: ''};letrules={name: 'required'};form(data).rules(rules).validate().errors().list();// Output: ['Name is a required field']form.errors().forget();form.errors().list();
Output: ['name is a required field', 'name must be longer than 3 characters']
Add Error
Add error message for a specific field
letdata={name: ''};letrules={name: 'required|min:3'};form(data).rules(rules).validate().add('name','four failures in a row. Two more failures before your locked out');form.errors().list('name');
Output: ['name is a required field', 'name must be longer than 3 characters', 'four failures in a row. Two more failures before your locked out']
Allows you to overwrite pre-defined macro and over write core error message bag functions (Use With Caution)
letexample=form({name: ''}).rules({name: 'required|min:3'}).validate();example.errors().get('name');// Outputs: "Name is a required field"example.errors().forceMacro('get',function(field){if(this.has(field)){returnthis.list(field).join(', ')+'.';}});example.errors().get('name');// Outputs: "Name is a required field, name must have at least 3 characters."
[all](#all
[boolean](#boolean
[empty](#empty
[except](#except
[fill](#fill
[filled](#filled
[forceMacro](#forcemacro
[forget](#forget
[has](#has
[hasAny](#hasany
[input](#input
[keys](#keys
[macro](#macro
[make](#make
[missing](#missing
[only](#only
[set](#set
[toArray](#toarray
[wrap](#wrap
all()
The all method returns the underlying input object represented by the form:
constform=require('vuejs-form');form().macro('shortcut',()=>{returnthis.validate().errors().list();});letexample=form({name: ''}).rules({name: 'required'});example.shortcut();// Output: ['Name is a required field'];
Extend Validator Using Macros
const{ form, validator }=require('vuejs-form');validator().macro('translate',({ dictionary, locale })=>{if(!Object.keys(dictionary).includes(locale)){console.warn(`Translation dictionary does not include passed ${locale}`);returnthis;}constlanguage=Object.keys(this.messages);constdictionary_words=key=>Object.keys(dictionary[locale]).includes(key);language.filter(dictionary_words).forEach(key=>{this.messages[key]=dictionary[`${locale}.${key}`]});returnthis;});letexample=form({name: ''}).rules({name: 'required'});letlocale='ru';letdictionary={ru: {email: "Эл.почта"}};example.validator().translate({ locale, dictionary });
Allows you to overwrite pre-defined macro and over write core error message bag functions (Use With Caution)
letexample=form({name: ''}).rules({name: 'required|min:3'}).validate();example.errors().get('name');// Outputs: "Name is a required field"example.errors().forceMacro('get',function(field){if(this.has(field)){returnthis.list(field).join(', ')+'.';}});example.errors().get('name');// Outputs: "Name is a required field, name must have at least 3 characters."
Extending: Custom Error Messages
This has nothing to do with the error messages Api
These are the literal string output a rule message will display when it fails
Here we'll customize error messages for specific rules on any given field
Globally, each rule provides a default error message
Easily override rule's default error message
Simply pass 'messages' to our validator
Only override messages you want to
letdata={name: '',email: ''};letrules={name: ['min:3','max:12','string','required'],email: ['email','required']};letcustomMessages={'name.min': 'Whoops! :attribute is less than :min characters','name.required': 'Wha oh, doesnt look like there any value for your :attribute field','email.email': 'Really? Email is called Email...it has to be an email...',};form(data).rules(rules).messages(customMessages).validate().errors().all();
letexample=form({name: 'timmy'}).rules({name: 'uppercase'});example.validator().extend('uppercase',[':attribute must be uppercase',({ value, validator, parameters })=>value===value.toUpperCase(),]);// trueexample.validate().errors().has('name');// "Name must be uppercase"example.errors().get('name');
letexample=form({name: ''}).rules({name: ['required_with:last_name','required']});example.validator().extend({uppercase: [':attribute must be uppercase',({ value })=>value===value.toUpperCase(),],not_uppercase: [':attribute must not be uppercase',({ value })=>value!==value.toUpperCase()],required_without: [':attribute is only required when form is missing :required_without field',({ validator, parameters })=>!Object.keys(validator.data).includes(parameters[0])],required_with: [':attribute is required with the :required_with field',({ validator, parameters })=>Object.keys(validator.data).includes(parameters[0])],});
Extend Form Into Multi Step Form (Not tested, but good base to provide some ideas)
Not actually tested outside of these docs, but solid starting point
Step {{ multi.steps().currentStep }} of {{ multi.steps().count() }}
([
value === null || value === '',
Array.isArray(value) && value.length === 0,
typeof value === 'object' && Object.keys(value).length === 0
].includes(true));
return !isEmpty(this.list());
};
this.has = function (group) {
return Object.keys(this.sections).includes(group)
&& this.sections[group].length > 0
};
this.all = function () {
return this.sections;
};
this.list = function (group = false) {
return group
? this.sections[group]
: Object.keys(this.sections)
.map(group => this.sections[group])
.reduce((list, groups) => [ ...list, ...groups ], []);
};
this.get = function (group) {
if (this.has(group)) {
return this.sections[group][0];
}
};
this.add = function(group, item) {
this.sections[group] = Array.isArray(this.sections[group])
? this.sections[group]
: [];
this.sections[group].push(item);
return this;
};
this.set = function (group, items = []) {
if (typeof items === 'object') {
this.sections = items;
} else {
this.sections[group] = items;
}
};
this.forget = function (group) {
if (typeof group === 'undefined') {
this.sections = {};
} else {
this.sections[group] = [];
}
};
};
const steppable = function (form = {}) {
return new MultiStep(validator);
};
form().macro('multiple', () => {
this.steppables = steppable(this);
this.steps = function () {
return this.steppables;
};
this.first = function () {
return this.steps().get('0')
}
this.last = function () {
return this.steps().list(this.steps().count() - 1);
};
this.current = function () {
return this.steps().current();
};
return this;
});
form().multiple().steps();
/** Use macro to extend form and append vue component instance to each form step **/
form().macro('hasComponent', () => typeof this.component_is !== 'undefined');
form().macro('getComponent', () => {
this.hasComponent() ? this.component_is : `
No Component Registered On This Form Instance
`
});
form().macro('is', (vue_instance) => {
this.component_is = vue_instance;
return this;
});
form().multiple().steps();
const { name_fields, password_fields, final_step } = require('./components/forms/steps/index.js');
let multi = form({}).multiple();
multi.steps().add(0,
form({
last_name: '',
first_name: ''
})
.rules({
last_name: ['required', 'min:3', 'string', 'different:first_name'],
first_name: ['required', 'min:3', 'string', 'different:last_name']
})
.messages({
'last_name.required': 'Last name is required',
'last_name.min': 'Last name may not be less than :min characters',
'last_name.different': 'Last Name must be different than first name',
'last_name.string': 'Last Name must be a string',
'first_name.required': 'First name is required',
'first_name.min': 'First name may not be less than :min characters',
'first_name.different': 'Last Name must be different than last name',
'first_name.string': 'First name must be of the string type'
})
.is(name_fields)
);
multi.steps().add(1,
form({
password: '',
password_confirmation: '',
})
.rules({
password: ['required', 'min:5', 'string', 'confirmed'],
})
.is(password_fields)
);
multi.steps().add(2,
form({ terms_of_service: '' })
.rules({ terms_of_service: 'accepted|required' })
.messages({
'terms_of_service.accepted': "Must accept terms of service before moving on",
'terms_of_service.required': "Must accept terms of service before submitting form",
})
.is(final_step)
);
export default {
name: 'multi-step-form',
data: () => ({ multi }),
methods: {
submit() {
let data = this.multi.steps().list().reduce((data, step) => ({ ...data, ...step.all() }), {});
console.log('all data: ', form(data).all());
}
}
};">
constMultiStep=function(form){this.sections={};this.currentStep=0;this.parent=function(){returnform;};this.current=function(){if(this.has(this.currentStep)){returnthis.get(this.currentStep);}else{console.error("No current step found");}};this.currentComponent=function(){returnthis.current().component_is};this.count=function(){returnthis.list().length;};this.travel=function(to){if(this.has(to)){this.currentStep=to;returnthis.current();}else{returnconsole.error(`form step ${to} not found`);}};this.prev=function(){if(!this.isFirst()){this.currentStep=this.currentStep-1;returnthis.current();}else{console.error('already on the very first step')}};this.next=function(){if(!this.isLast()){this.currentStep=this.currentStep+1;returnthis.current();}else{console.log('last step')}};this.hasPrev=function(){returnthis.has(this.currentStep+1);};this.hasCurrent=function(){returnthis.has(this.currentStep);};this.isFirst=function(){returnthis.hasCurrent()&&!this.hasPrev()};this.isLast=function(){returnthis.hasCurrent()&&!this.hasNext();};this.hasNext=function(){returnthis.has(this.currentStep+1)};this.any=function(){constisEmpty=value=>([value===null||value==='',Array.isArray(value)&&value.length===0,typeofvalue==='object'&&Object.keys(value).length===0].includes(true));return!isEmpty(this.list());};this.has=function(group){returnObject.keys(this.sections).includes(group)&&this.sections[group].length>0};this.all=function(){returnthis.sections;};this.list=function(group=false){returngroup
? this.sections[group]
: Object.keys(this.sections).map(group=>this.sections[group]).reduce((list,groups)=>[ ...list, ...groups],[]);};this.get=function(group){if(this.has(group)){returnthis.sections[group][0];}};this.add=function(group,item){this.sections[group]=Array.isArray(this.sections[group])
? this.sections[group]
: [];this.sections[group].push(item);returnthis;};this.set=function(group,items=[]){if(typeofitems==='object'){this.sections=items;}else{this.sections[group]=items;}};this.forget=function(group){if(typeofgroup==='undefined'){this.sections={};}else{this.sections[group]=[];}};};conststeppable=function(form={}){returnnewMultiStep(validator);};form().macro('multiple',()=>{this.steppables=steppable(this);this.steps=function(){returnthis.steppables;};this.first=function(){returnthis.steps().get('0')}this.last=function(){returnthis.steps().list(this.steps().count()-1);};this.current=function(){returnthis.steps().current();};returnthis;});form().multiple().steps();/** Use macro to extend form and append vue component instance to each form step **/form().macro('hasComponent',()=>typeofthis.component_is!=='undefined');form().macro('getComponent',()=>{this.hasComponent() ? this.component_is : `
No Component Registered On This Form Instance
`});form().macro('is',(vue_instance)=>{this.component_is=vue_instance;returnthis;});form().multiple().steps();const{ name_fields, password_fields, final_step }=require('./components/forms/steps/index.js');letmulti=form({}).multiple();multi.steps().add(0,form({last_name: '',first_name: ''}).rules({last_name: ['required','min:3','string','different:first_name'],first_name: ['required','min:3','string','different:last_name']}).messages({'last_name.required': 'Last name is required','last_name.min': 'Last name may not be less than :min characters','last_name.different': 'Last Name must be different than first name','last_name.string': 'Last Name must be a string','first_name.required': 'First name is required','first_name.min': 'First name may not be less than :min characters','first_name.different': 'Last Name must be different than last name','first_name.string': 'First name must be of the string type'}).is(name_fields));multi.steps().add(1,form({password: '',password_confirmation: '',}).rules({password: ['required','min:5','string','confirmed'],}).is(password_fields));multi.steps().add(2,form({terms_of_service: ''}).rules({terms_of_service: 'accepted|required'}).messages({'terms_of_service.accepted': "Must accept terms of service before moving on",'terms_of_service.required': "Must accept terms of service before submitting form",}).is(final_step));exportdefault{name: 'multi-step-form',data: ()=>({ multi }),methods: {submit(){letdata=this.multi.steps().list().reduce((data,step)=>({ ...data, ...step.all()}),{});console.log('all data: ',form(data).all());}}};
localMacro(name, fn)Example: See multi-step form example provided for forceLocalMacro example. It provides a powerful example of possible ways to combine local and forceLocal macros.
extend instance with function
instance gains function
NOT applied to all new instances
can not overwrite core instances
can not overwrite pre-defined macros
can be applied on more than a single instance, but not automatically inherited globally Example: localMacro
Overwrite A Given Apis Core Via Force Macros
forceMacro(name, fn)
overwrite core api or existing macros
instance and constructor prototypes apply function
applies on all instances
can overwrite core functions
can overwrite pre-defined macros NOTE: This is a very powerful function, use caution and when overriding core behavior understand things depend on other things under the hood. Only use this type of macro if no other macro solves your needs
Force Macro Example
Overwrite Error Message Apis Get Method To Get A Comma List Of Messages Instead Of The First Message
letexample=form({name: ''}).rules({name: 'required|min:3'}).validate();example.errors().get('name');// 'Name field is required'example.errors().forceMacro('get',function(field){if(this.has(field)){returnthis.list(field).join(', ');}});example.errors().get('name');// 'Name field is required, Name field must be more than 3 characters'
Overwrite A Given Instances Core Via Force Local Macros
forceLocalMacro(name, fn)
overwrite instances core behavior or existing macros
instance applies function
not applied by all instances, only on single instance
can overwrite core functions
can overwrite pre-defined macros NOTE: Not quite as dangerous as forceMacro (it's only applied on one instance instead of globally across the api), it is still powerful and should be used only if localMacro doesn't solve your needs
Create A Parent Form With Multiple Child FormsExample uses localMacro & forceLocalMacro (Advanced example)
letMultiStepForm=form();MultiStepForm.localMacro('register',function(children=[]){this.current=0;const$parent=this;// Set local macros on each one of the child forms this.children=children.map(child=>{// 1. localMacro: parent() method references parent form will all stepschild.localMacro('parent',()=>$parent);// 2. forceLocalMacro: override validate() method to add in a step where child validate method populates parent() errors bag// Below we'll override the parent validate() method using a forceLocalMacro as well to two way bind this setupchild.forceLocalMacro('validate',function(){constchildForm=this;childForm.validator().validate();childForm.parent().errors().set({
...childForm.parent().errors().all(),
...childForm.errors().all(),});returnthis;})});/** Add helper methods for managing the multi-step form process **/this.step=()=>this.steps(this.current);this.steps=index=>index!=='undefined'&&this.hasStep(index) ? this.children(index) : this.children;this.hasStep=index=>typeofthis.children[index]!=='undefined';this.prevStep=()=>{this.current=this.current-1;};this.stepNumber=()=>this.current+1;this.stepsCount=()=>this.steps().length;this.hasPrevStep=()=>this.hasStep(this.current-1);this.hasNextStep=()=>this.hasStep(this.current+1);this.isLastStep=()=>this.step()===this.steps(this.stepCount());this.isFirstStep=()=>this.step()===this.steps(0);this.completedStepsCount=()=>this.stepNumber();this.remainingStepsCount=()=>this.stepsCount()-this.stepNumber();this.percentageCompleted=()=>(this.completedStepsCount()/100)*this.stepsCount();this.percentageRemaining=()=>(this.remainingStepsCount()/100)*this.stepsCount();this.next=()=>{if(this.hasNextStep())this.current=this.current+1;};this.prev=()=>{if(this.hasPrevStep())this.current=this.current-1;};this.to=index=>{if(this.hasStep(index))this.current=index;}returnthis;});/** forceLocalMacro to overwrite default all method on MultiStepForm ~ aggregating all child form data **/MultiStepForm.forceLocalMacro('all',function(){returnthis.children.reduce((data,child)=>({
...data,
...child}),{});});/** forceLocalMacro to overwrite default validate method on MultiStepForm ~ setting all error messages **/MultiStepForm.forceLocalMacro('validate',function(){this.errors().set(this.children.reduce((errors,child)=>({
...errors,
...child.validate().errors().all()}),{}));returnthis;});MultiStepForm.register([form({first_name: '',last_name: ''}).rules({first_name: 'required',last_name: 'required'}),form({email: '',phone_number: ''}).rules({email: 'required|email',phone: 'required|phone'}),form({password: null,password_confirmation: ''}).rules({password: 'required|min:7|confirmed|string '}),form({terms_of_services: null}).rules({terms_of_services: 'required|accepted'})]);MultiStepForm.validate().errors().list();
Output:
[
'First name is a required field',
'Last name is a required field',
'Email is a required field',
'Email must be an email',
'Phone number is a required field',
'Phone number must be a valid phone number',
'Password is a required field',
'Password must be at least 7 characters',
'Password must have the same value as the password confirmation field',
'Password must be a string',
'Terms Of Service is a required field',
'Terms Of Service has not been accepted, please accept to continue',
]
importformfrom'vuejs-form'constLoginForm=form({name: '',email: '',password: '',})LoginForm.name// ''LoginForm.name='sarah'LoginForm.name// 'sarah'form({name: '',email: '',password: '',}).all()// { name: 'sarah', email: '', password: '' }form({name: '',email: '',password: '',}).has('email','password')// trueform({name: '',email: '',password: '',}).has('email','something')// falseform({name: '',email: '',password: '',}).hasAny('email','something')// trueform({name: '',email: '',password: '',}).empty('email')// trueform({name: '',email: '',password: '',}).filled('email')// falseform({name: '',email: '',password: '',}).filled('name')// trueform({name: '',email: '',password: '',}).boolean('email')// falseform({name: '',email: '',password: '',}).only('email','name')// { email: '', name: '', }form({name: '',email: '',password: '',}).except('password')// { email: '', name: '' }form({name: '',email: '',password: '',}).input('password')// ''form({name: '',email: '',password: '',}).input('email','[email protected]')// '[email protected]'LoginForm.fill({name: 'tim',email: '[email protected]',password: 'secret'})LoginForm.all()// { name: 'sarah', email: '[email protected]', password: 'secret' }LoginForm.set({name: 'jamie',email: '[email protected]',password: 'password'})LoginForm.all()// { name: 'jamie', email: '[email protected]', password: 'secret' }LoginForm.keys()// ['name', 'email', 'password']LoginForm.missing('verified')// trueLoginForm.missing('email')// falseLoginForm.toArray()/** [ { key: 'name', value: 'jamie' }, { key: 'email', value: '[email protected]' }, { key: 'password', value: 'secret' } ]*/LoginForm.wrap('data')/**{ data: { name: 'jamie', email: '[email protected]', password: 'secret' }}*/LoginForm.forget('password','email')LoginForm.all()// { name: 'jamie' }/** * When dealing with HTML elements like checkboxes, your application may receive "truthy" values that are actually strings. For example, "true" or "on". For convenience, you may use the boolean method to retrieve these values as booleans. The boolean method returns true for 1, "1", true, "true", "on", and "yes". All other values will return false: * Boolean checks for*/LoginForm.boolean('name')// falseLoginForm.terms=trueLoginForm.boolean('terms')// trueLoginForm.terms='true'LoginForm.boolean('terms')// trueLoginForm.terms='yes'LoginForm.boolean('terms')// trueLoginForm.terms='on'LoginForm.boolean('terms')// trueLoginForm.terms="1"LoginForm.boolean('terms')// trueLoginForm.terms=1LoginForm.boolean('terms')// true/** Anything else will return false Ex: */LoginForm.terms='asdfsdf'LoginForm.boolean('terms')// false
Extend Form Functionality
importformfrom'vuejs-form'form().macro('count',()=>{returnthis.keys().length})form().macro('mapInto',into=>{// NOTICE: this.data is where the input object is actually storedthis.data=Object.entries(this.data).reduce((input,[key,value])=>({
...input,
...into(key,value)}),{});returnthis})constextendedForm=form({email: '[email protected]',password: 'secret',})form().macro((key,value)=>({[key]: value.split('@')})).all()/** * { email: ['example', 'gmail'], password: 'secret' } */
Contribute
PRs are welcomed to this project. If you want to improve the vuejs-form library, add functionality or improve the docs please feel free to submit a PR.
Security Vulnerabilities
If you discover a security vulnerability within Clean Code Studio Packages Or Specifically within vuejs-form, please send an e-mail to Zachary Horton via [email protected]. All security vulnerabilities will be promptly addressed.
I try to extend a custom rule, but I always get this error:
Uncaught TypeError: check.rule is not a function
at eval (validator.js:299)
at Array.reduce (<anonymous>)
at Validator.checkRulesAndFillErrorBag (validator.js:298)
at Validator.validate (validator.js:281)
at Proxy.validate (use.js:52)
at extend.html:22 Even if i try the
Even if I use this example snippet from the documentation:
<!DOCTYPE html>
<html lang="en">
<head><script src='https://unpkg.com/[email protected]/build/vuejs-form.min.js'></script></head>
<body>
<script>
let example = form({ name: 'timmy' }).rules({ name: 'uppercase' });
example.validator().extend('uppercase', [
':attribute must be uppercase',
({ value, validator, parameters }) => value === value.toUpperCase(),
]);
example.validate().errors().has('name');
</script>
</body>
</html>
The error occurs in all my browsers (Firefox 80 and Chrome 85 on Ubuntu)
I used the regex rule as mentioned in the documentation but it throws an error as shown in the attached screenshot
I tried to find out the reason and I might be wrong but I think the reason is .... ok I will explain with the help of screenshot attached below
It was expected to be working like the one, underlined with green colour, but in the regex/not_regex function, the parameters[0] (underlined with red colour) gives string value( e.g "/^.+@.+$/i"). And of course, string.test is not the function. So it gives the error.
If I have misunderstood things, please let me know. Also, Is there any other solutions to work with Regex ?
Describe the bug
Hi there! I came across an annoying issue with the initialization of my inputs. It seems like the inputs won't let you write the first character you enter in them the first time you type in them.
To Reproduce
Steps to reproduce the behavior:
Go to https://codepen.io/zhorton34/pen/zYvWZYz
Click on any input
Type only one character. Nothing happens. Type again, characters now show.
Expected behavior
Should display first keypressed character
Desktop (please complete the following information):
Node.js Pretty Top-of-the-line, Kick ass ideas (That'd would also undoubtedly take a butt load of time to implement)
NOTE: The ideas in this ticket are directly inspired from node.js, specifically the last 3 to 4 months of deep diving into electron, network, lower level operating system level craziness, and so many other rabbit wholes. As of right now, I've focused this project on being very independent (Taking a dependency minimizing, UI agnostic, extremely data-centric non-bias approach). The ideas "whoa, that'd be knarly" ideas in this ticket are just. Whoa, those are extremely cool things we could do. Many of these feature ideas however, do DEPEND ON NODE.js. That's an immediate show stopper for directly updating the vuejs-form core with these feature. These would have to be "plugged-in" as extensions for vuejs-form - not required dependencies of the core repo. With that being said, we could offer these "plug-ins" as options imports within vuejs-form given they are just vanilla node.js idea, but by no means should these node.js ideas be - by default - integragted into vuejs-form. These features, in the best case scenario, would be shipped with the core of vuejs-form, then imported and plugged-in for developers working with node.js.
Node.js DNS validation options are able to resolve the Domain Name Service Settings
- This allows for unique, extremely powerful validators
- [ ] Validate application host is accessable
- [ ] Validate application host services are accessible (Validate ssh port, mysql port, etc...)
- [ ] Validate application host name servers
- [ ] Validate application host Mx Records
- [ ] Validate application host text records
- [ ] Validate application host Cname
- [ ] Validate domain address is resolvable from ip (DNS has finalized it's propagation after setting up a new site)
- [ ] Validate/resolve ip address via DNS reverse lookup using domain
- [ ] Validate network protocols
- [ ] Validate network connections
- [ ] Validate whether securely accessing content
[ ] Validate passwords, implement encryption types, fill ***** passwords with dummy data, secrets, osSecrets, public/privateKeys, etc...
[ ] The cool and incredibly powerful opportunity that comes with developing EXTREMELY SECURE encryption and cryptography for forms is the ability to add high value form fields that REQUIRE THE UTMOST IN SECURITY but provide developers a higher value proposition to businesses when developing these high security need fields like the one's listed below
[ ] Social Security/Personal Identity Information That needs to stay Personal
[ ] Credit/Debit Cards
[ ] Bank Accounts
[ ] Insurance
[ ] etc...
[ ] More than that, we would also have opportunity to automate the generation of several encryption keys
[ ] Generate Github ssh public/private keys
[ ] Validate Github ssh public/private keys work properly utilizing Node.js's DNS core module and child_process core module
[ ] Automate creation of Https certs for browsers in local development
[ ] Validate https certs work properly in local development or on the internet, confirm that a website is using https instead of http
[ ] Integrating Web Sockets into Debugging/Inspector for real time debugging
[ ] Setting up custom repl (Interactive shell) to pull up while in development mode to interact with form faker data/tests
[ ] Node.js client/server combined with repl to allow us to create Tests with form dummy data, validation rules, and test cases as we build out our forms
[ ] Ability to directly interact with fs (File System)
Is your feature request related to a problem? Please describe.
I want to translate all required fields error messages without typing a custom message every field.
Describe the solution you'd like
Create a new a file to overwrite messages,js
Describe alternatives you've considered
The only solution I found is creating a custom message for every key in the form object.
Might be a silly question but basically I just wanted to create a new message.jsfile and import it, is that possible?