vue-form
Version:
Form validation for Vue.js
442 lines (370 loc) • 13.9 kB
HTML
<html>
<head>
<title>vue-form example</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<style></style>
</head>
<body>
<div id="app">
<label>
<span>Non validated</span>
<input name="foo2" type="text" />
</label>
<vue-form ref="form" :state="formstate" @submit.prevent="onSubmit">
<button type="button" @click="isReq = !isReq">Toggle</button>
<button type="button" @click="changeStuff">Change stuff</button>
<br><br><br>
<validate>
<span><input v-model="model.name" name="name" type="text" :pattern="pattern" required /></span>
</validate>
<!--
<validate tag="label">
<span>Name</span>
<span>
<input v-model="model.name" name="name" type="text" is-taken required :pattern="pattern" />
</span>
<field-messages name="name">
<div slot="required">Field required</div>
<div slot="pattern">pattern no match</div>
</field-messages>
</validate>
<validate tag="label" :custom="{customval: customval}">
<span>foo</span>
<input name="foo2" type="text" v-model="model.foo2" :required="isReq" />
</validate>
<validate>
<span><input v-model="model.email" name="email" type="email" /></span>
</validate>
<md-input-container>
<validate>
<label>Name</label>
<md-input v-model="model.name" required name="name"></md-input>
<field-messages name="name" class="md-error">
<div>Success!</div>
<div slot="required">Name is a required field</div>
</field-messages>
</validate>
</md-input-container>
<validate>
<md-input-container>
<label>Name</label>
<md-input v-model="model.name" required name="name"></md-input>
</md-input-container>
<field-messages name="name">
<div>Success!</div>
<div slot="required">Name is a required field</div>
</field-messages>
</validate>-->
<!--
<validate>
<md-input-container>
<span>Error with message</span>
<md-input required v-model="model.email" name="email"></md-input>
<field-messages name="email" class="md-error">
<div>Success!</div>
<div slot="required">Email is a required field</div>
</field-messages>
</md-input-container>
</validate>
<label>
<span>component</span>
<validate>
<test required v-model="model.name" name="foobar"></test>
</validate>
</label>
<div>
<span>testbool</span>
{{model.booltest}}
<validate>
<label>Yes <input type="radio" :value="true" v-model="model.booltest" name="radio" required /></label>
<label>No <input type="radio" :value="false" v-model="model.booltest" name="radio" required bool /></label>
</validate>
</div>
<label>
<span>Email *</span>
<validate>
{{isEmailTaken}}
<input v-model="model.email" name="email" type="email" required />
</validate>
<field-messages name="email">
<div slot="required">Field is required</div>
<div slot="is-taken">This email address is already taken</div>
</field-messages>
</label>
-->
<!--
<label>
<span>Name *</span>
<validate :required="isReq" min-length="10" max-length="40" pattern="/sdfsdffd/">
<input v-model="model.name" name="name" />
</validate>
</label>
<label>
<span>Email *</span>
<validate required>
<input v-model="model.email" name="email" type="email" />
</validate>
</label>
====================
<form-error :field="formstate.name" error="required">Name is a required field 2</form-error>
<form-error :field="formstate.name" error="minlength">Min length is not satisfied</form-error>
<form-errors :field="formstate.name">
<div slot="pattern">Pattern don't match</div>
<div slot="required">Field is required</div>
<div slot="minlength">minlength not satisfied</div>
</form-errors>
<validate tag="label">
<span>testcomp</span>
<test v-model="model.testcomp" :minlength="minLength" :required="isReq" name="testcomp"></test>
</validate>
<validate tag="label" :custom="customA">
<span>foo</span>
<input name="name" type="text" v-model="model.name" :required="isReq" />
</validate>
<validate tag="div">
Checkbox array <br>
<input type="checkbox" value="Jack" v-model="multicheck" required name="multicheck"/>
<input type="checkbox" value="John" v-model="multicheck" required name="multicheck"/>
<input type="checkbox" value="Mike" v-model="multicheck" required name="multicheck"/>
</validate>
<validate tag="div">
Radios <br>
<input type="radio" value="Jack" v-model="radio" required name="radio"/>
<input type="radio" value="John" v-model="radio" required name="radio"/>
<input type="radio" value="Mike" v-model="radio" required name="radio"/>
</validate>
<validate tag="label">
<span>Name</span>
<span>
<input :minlength="3" v-model="model.name" name="name" :required="isReq" pattern="foo" />
</span>
</validate>
<label>
<span>testbool</span>
{{model.booltest}}
<validate>
<input type="radio" :value="true" v-model="model.booltest" required name="radio" bool />
<input type="radio" :value="false" v-model="model.booltest" required name="radio" bool />
</validate>
</label>
<validate :debounce="1000" tag="label" auto-label customfoo="{customA: customA, customB: customB}">
<span>foo</span>
<input class="static" :class="{'some': bool}" id="exists" name="foo" type="text" v-model="model.foo" :required="isReq" @focus="bool = !bool" />
</validate>
<field-messages name="foo" show="$dirty">
<div slot="required">Field is required</div>
</field-messages>
<validate tag="label" v-if="isReq">
<span>foo2</span>
<input name="foo2" type="text" v-model="model.foo2" :required="isReq" />
</validate>
<label>
<span>Request call back</span>
{{model.contactRequired}}
<validate><input v-model="model.contactRequired" type="checkbox" name="contactRequired" required /></validate>
</label>
-->
<!--
<form-error field="foo" error="pattern">pattern doesn't match</form-error>
<form-error field="foo" error="required">required message 2</form-error>
-->
<!--
<validate>
<test name="testcomp" v-model="model.testcomp" required></test>
</validate>
<label>
<span>Name</span>
<validate>
<input :minlength="3" v-model="model.name" name="name" :required="isReq" pattern="foo" />
</validate>
</label>
<validate tag="label" v-if="isReq">
<span>foo2</span>
<input name="foo2" type="text" v-model="model.foo2" :required="isReq" />
</validate>
<label>
<span>Email</span>
<input v-form v-model="model.email" name="email" type="email" :required="isReq" />
</label>
<label>
<span>component</span>
<test v-validate v-model="model.testcomp" :required="isReq" name="foobar"></test>
</label>
<label>
<span>Contact details <span v-if="model.contactRequired">*</span></span>
<textarea v-model="model.contact" :required="model.contactRequired" name="comments"></textarea>
</label>
<div v-if="model.contactRequired">
<p>Extra contact fields</p>
<label>
<span>3 digit code *</span>
<input v-model="model.code" name="code" type="text" pattern="[A-Za-z]{3}" required />
</label>
</div>
-->
<button type="submit">Submit</button><button type="button" @click="resetState">Reset</button>
</vue-form>
<pre>{{formstate}}</pre>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
<!--<script src="../node_modules/vue/dist/vue.js"></script>-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.js"></script>
<script src="../dist/vue-form.js"></script>
<script src="https://unpkg.com/vue-material@0.7.4/dist/vue-material.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-material@0.7.4/dist/vue-material.css">
<script>
Vue.use(VueMaterial)
Vue.use(VueForm);
/*
VueForm.addValidator('people-picker-required', function (model, attrValue, vnode){
if (model !== 'scot') {
return false;
}
return true;
});*/
var undef;
var vm = new Vue({
el: '#app',
mixins: [new VueForm({
validators: {
'customval': function(value, attrValue, vnode) {
console.log('customval -- validators', attrValue);
return !attrValue;
},
'is-taken': function(value, attrValue, vnode) {
console.log(attrValue);
return !attrValue;
}
}
})],
components: {
test: {
props: {
value: String,
minlength: Number,
required: Boolean,
name: String
},
data() {
return {
internalValue: '',
bool: false
}
},
template: '<span :class="{\'some\': bool}">TEST<input @input="update" v-model="internalValue" /></span>',
created() {
this.$watch('value', () => {
this.internalValue = this.value;
}, {
immediate: true
});
},
mounted() {
this.$el.querySelector('input').addEventListener('focus', () => {
//this.$emit('focus');
this.bool = true;
});
this.$el.querySelector('input').addEventListener('blur', () => {
//this.$emit('blur');
});
},
methods: {
update() {
this.$emit('input', this.internalValue);
}
}
}
},
data: {
isReq: true,
minLength: 5,
formstate: {},
multicheck: [],
radio: '',
bool: false,
isEmailTaken: false,
//pattern: '^\d{4}-\d{3}-\d{4}$',
//pattern: null,
//pattern: undef,
pattern: undefined,
//pattern: '',
//pattern: false,
model: {
foo: '',
foo2: '',
email: '',
name: 'name',
contact: '',
testcomp: '',
contactRequired: null,
booltest: null
}
},
methods: {
debounced: _.debounce(function(value, resolve, reject) {
console.log('do ajax');
fetch('https://httpbin.org/get').then(function(response) {
resolve(value === 'ajax')
return response.json();
});
}, 500),
customA(value) {
return new Promise((resolve, reject) => {
this.debounced(value, resolve, reject);
});
},
customval(value) {
console.log('customval -- methods');
return false;
},
customB(value) {
return new Promise((resolve, reject) => {
//this.debounced(value, resolve, reject);
fetch('https://httpbin.org/get').then(function(response) {
setTimeout(() => {
resolve(value === 'ajax');
}, 100);
return response.json();
});
});
},
customC(value, done) {
setTimeout(function() {
done(value === 'async');
}, 1000);
},
changeStuff: function() {
this.isReq = !this.isReq;
this.minLength = 10;
this.model.name = this.model.name + 'foo';
},
onSubmit: function() {
this.isEmailTaken = true;
console.log(this.formstate.$valid);
},
resetState: function() {
this.model = {
foo: '',
foo2: '',
email: '',
name: 'name',
contact: '',
testcomp: '',
contactRequired: false
};
//this.$nextTick(function () {
this.$refs.form.reset();
//});
}
},
mounted () {
setTimeout(()=>{
// this.formstate._submit();
}, 5000);
}
});
</script>
</body>
</html>