UNPKG

vue-form

Version:

Form validation for Vue.js

248 lines (222 loc) 7.42 kB
<!DOCTYPE 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> .required-field>label::after { content: '*'; color: red; margin-left: 0.25rem; } </style> <script src="https://cdn.tinymce.com/4/tinymce.min.js"></script> </head> <body> <div id="app" class="container py-5"> <p>Example showing vue-form usage with Bootstrap styles, validation messages are shown on field touch or form submission</p> <vue-form :state="formstate" v-model="formstate" @submit.prevent="onSubmit"> <!-- <validate auto-label class="form-group required-field" :class="fieldClassName(formstate.name)"> <label>Comments</label> <tinymce type="text" name="comments" class="form-control" required v-model="model.comments" v-input></tinymce> <field-messages name="comments" show="$touched || $submitted" class="form-control-feedback"> <div>Success!</div> <div slot="required">Comments is a required field</div> </field-messages> </validate> --> <validate auto-label class="form-group required-field" :class="fieldClassName(formstate.number)"> <label>Custom number</label> <custom-number name="number" min="2" class="form-control" v-model="model.number"></custom-number> <field-messages name="number" class="form-control-feedback"> <div>Success!</div> <div slot="max">Number is too large</div> <div slot="min">Number is too small</div> <div slot="required">required</div> </field-messages> </validate> <validate auto-label class="form-group required-field" :class="fieldClassName(formstate.name)"> <label>Name</label> <input type="text" name="name" class="form-control" v-model="model.name" required /> <field-messages name="name" class="form-control-feedback"> <div>Success!</div> <div slot="required">required</div> </field-messages> </validate> <!-- <validate auto-label class="form-group required-field" :class="fieldClassName(formstate.name)"> <label>Custom number</label> <input type="number" :min="min" max="11" name="number2" class="form-control" required v-model="model.number" /> <field-messages name="number2" class="form-control-feedback"> <div>Success!</div> <div slot="required">Comments is a required field</div> </field-messages> </validate> <validate auto-label class="form-group required-field" :class="fieldClassName(formstate.name)"> <label>Name</label> <input type="text" name="name" class="form-control" required v-model.lazy="model.name"> <field-messages name="name" show="$touched || $submitted" class="form-control-feedback"> <div>Success!</div> <div slot="required">Name is a required field</div> </field-messages> </validate> --> <div class="py-2 text-center"> <button type="button" @click="changeStuff">changeStuff()</button> <button class="btn btn-primary" type="submit">Submit</button> </div> </vue-form> <pre>{{formstate}}</pre> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script src="../dist/vue-form.js"></script> <script> console.log(Vue.version); var options = { inputClasses: { valid: 'form-control-success', invalid: 'form-control-danger' } } var input = { name: 'input', bind: function(el) { console.log('here'); } }; var generatedIds = 0; var tinymce = { template: ` <div :class="{'pre-loader': isLoading}"> <div class="rich-textarea-toolbar"><div :id="elementId + '-toolbar'"></div></div> <div :class="[className, {'invert-theme': invertTheme }]" class="input-richtext" :placeholder="placeholder" :id="elementId"></div> </div>`, data() { generatedIds++; return { elementId: 'tinymce-inline-editor-' + generatedIds, isLoading: true }; }, props: { value: String, preset: { type: String, default: 'inline' }, placeholder: String, forceEmpty: Boolean, disabled: Boolean, forcedRootBlock: null, invertTheme: Boolean }, computed: { className() { if (this.preset === 'textarea') { return 'input-textarea'; } else if (this.preset === 'inline' || this.preset === 'el') { return 'inline-editor'; } } }, }; var customNumber = { template: '<input type="number" :min="min" :max="max" v-model="input" />', props: { min: { type: null, default: 2 }, value: null //type: String }, data: () => ({ num: 5, input: null }), watch: { input (v) { this.$emit('input', v) } }, computed: { max () { return this.num; }, validationData () { return { type: 'number', //min: this.min, required: true, max: this.max } } }, created() { this.input = this.value; }, mounted() { // this.$emit('vf:mounted', { // type: 'number', // min: this.min, // max: this.max // }); this.$emit('vf:watch', 'validationData'); setInterval(()=>{ this.num = this.num + 1; //console.log(this.num) }, 2000); }, updated() { // this.$emit('vf:updated', { // type: 'number', // min: this.min, // max: this.max // }); } }; var vm = new Vue({ el: '#app', mixins: [new VueForm(options)], components: { tinymce: tinymce, customNumber: customNumber }, directives: { input: input }, data: { formstate: {}, model: { name: '', email: '', phone: '', department: null, comments: '', notValidated: '', number: 7, number2: 10 }, min: 6 }, methods: { changeStuff () { this.min = this.min + 1; }, fieldClassName: function(field) { if (!field) { return ''; } if ((field.$touched || field.$submitted) && field.$valid) { return 'has-success'; } if ((field.$touched || field.$submitted) && field.$invalid) { return 'has-danger'; } }, onSubmit: function() { console.log(this.formstate.$valid); } } }); </script> </body> </html>