Skip to content

Commit 45f789b

Browse files
committed
added form validation
1 parent 124b571 commit 45f789b

File tree

8 files changed

+742
-62
lines changed

8 files changed

+742
-62
lines changed

dist/vue-formly.js

Lines changed: 609 additions & 20 deletions
Large diffs are not rendered by default.

dist/vue-formly.min.js

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/FormlyField.vue

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<script>
66
const Vue = require('vue');
7-
import Util, {getTypes, addError, removeError} from '../util';
7+
import Util, {getTypes, setError} from '../util';
88
export default {
99
props: ['form', 'key'],
1010
computed: {
@@ -16,23 +16,36 @@
1616
validate:function(){
1717
let field = this.form[this.key];
1818
19-
//just return straight away if nothing is there
20-
if ( !field.required && !field.value ) return;
19+
//first check if we need to create a field
20+
if ( !this.form.$errors[this.key] ) this.$set('form.$errors.'+this.key, {});
2121
22+
//check for required fields. This whole setting,unsetting thing seems kind of wrong though..
23+
//there might be a more 'vue-ey' way to do this...
2224
if ( field.required ){
23-
if ( !field.value ){
24-
addError(this.form, this.key, 'required');
25-
} else {
26-
removeError(this.form, this.key, 'required');
27-
}
25+
if ( !this.form.$errors[this.key].required ) this.$set('form.$errors.'+this.key+'.required', true);
26+
setError(this.form, this.key, 'required', !field.value) ;
2827
}
28+
29+
//if we've got nothing left then return
30+
if ( !field.validators ) return;
31+
32+
Object.keys(field.validators).forEach((validKey) => {
33+
if ( !this.form.$errors[this.key][validKey] ) this.$set('form.$errors.'+this.key+'.'+validKey, false);
34+
if ( !field.required && !field.value ) return;
35+
36+
let validator = field.validators[validKey];
37+
38+
let valid = typeof validator == 'function' ? !validator(field) : !eval(validator);
39+
setError(this.form, this.key, validKey, valid);
40+
41+
});
2942
}
3043
},
3144
components: getTypes(),
3245
created(){
3346
this.validate();
3447
this.$watch('form.'+this.key+'.value', (val) =>{
35-
this.validate();
48+
let valid = this.validate();
3649
});
3750
}
3851
}

src/components/FormlyForm.vue

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,17 @@
1717
this.$set('form.$errors', {});
1818
this.$set('form.$valid', true);
1919
20-
this.$watch('form.$errors', (val) => {
21-
let valid = false;
22-
if ( Object.keys(this.form.$errors).length == 0 ) valid = true;
20+
this.$watch('form.$errors', function(val){
21+
let valid = true;
22+
Object.keys(this.form.$errors).forEach((key)=>{
23+
let errField = this.form.$errors[key];
24+
Object.keys(errField).forEach((errKey) => {
25+
if ( errField[errKey] ) valid = false;
26+
})
27+
});
2328
this.form.$valid = valid;
24-
return valid;
29+
}, {
30+
deep: true
2531
});
2632
}
2733
}

src/util.js

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,13 @@ export function getTypes(){
1919
}
2020

2121
/**
22-
* Allows a field to add errors to the form
22+
* Allows a field to add/remove errors to the form
2323
* @param {Object} form
2424
* @param {String} key
2525
* @param {String} err
26+
* @param {Bool} isError
2627
*/
27-
export function addError(form, key, err){
28+
export function setError(form, key, err, isError){
2829
if ( !form.$errors[key] ) form.$errors[key] = {};
29-
form.$errors[key][err] = true;
30-
}
31-
32-
/**
33-
* Allows a field to remove an error from the form
34-
* @param {Object} form
35-
* @param {String} key
36-
* @param {String} err
37-
*/
38-
export function removeError(form, key, err){
39-
delete form.$errors[key][err];
40-
if (Object.keys(form.$errors[key]).length == 0 ) delete form.$errors[key];
30+
form.$errors[key][err] = isError;
4131
}

test/unit/specs/FormlyField.spec.js

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ describe('FormlyField', () => {
3030

3131
let data = {
3232
form:{
33+
$errors: {},
34+
$valid: {},
3335
test: {
3436
type: 'test'
3537
}
@@ -53,6 +55,8 @@ describe('FormlyField', () => {
5355

5456
let data = {
5557
form: {
58+
$errors: {},
59+
$valid: {},
5660
search: {
5761
type: 'test',
5862
value: 'foo'
@@ -108,22 +112,87 @@ describe('FormlyField', () => {
108112

109113
vm.$set('form.search.value','testing');
110114
setTimeout(()=>{
111-
expect(vm.form.$errors.search).to.equal(undefined);
115+
expect(vm.form.$errors.search.required).to.be.false;
112116
done();
113117
},0);
114118

115119
});
116120

117-
it('should take an expression', () => {
121+
it('should take an expression', (done) => {
118122
let data = {
119123
form: {
120124
$valid: true,
121125
$errors: {},
122126
search: {
123-
127+
type: 'test',
128+
value: 'testing',
129+
validators: {
130+
expression: 'field.value == "test"'
131+
}
132+
}
133+
}
134+
};
135+
136+
createValidField(data);
137+
expect(vm.form.$errors.search.expression).to.be.true;
138+
139+
vm.$set('form.search.value', 'test');
140+
setTimeout(()=>{
141+
expect(vm.form.$errors.search.expression).to.be.false;
142+
done();
143+
},0);
144+
});
145+
146+
it('should not require non-required values', (done) => {
147+
let data = {
148+
form: {
149+
$valid: true,
150+
$errors: {},
151+
search: {
152+
type: 'test',
153+
value: '',
154+
validators: {
155+
expression: 'field.value == "test"'
156+
}
157+
}
158+
}
159+
};
160+
161+
createValidField(data);
162+
expect(vm.form.$errors.search.expression).to.be.false;
163+
164+
vm.$set('form.search.value', 'testing');
165+
setTimeout(()=>{
166+
expect(vm.form.$errors.search.expression).to.be.true;
167+
done();
168+
},0);
169+
});
170+
171+
it('should take a function', (done) => {
172+
let data = {
173+
form: {
174+
$valid: true,
175+
$errors: {},
176+
search: {
177+
type: 'test',
178+
value: 'testing',
179+
validators: {
180+
expression: function(field){
181+
return field.value == 'test';
182+
}
183+
}
124184
}
125185
}
126186
};
187+
188+
createValidField(data);
189+
expect(vm.form.$errors.search.expression).to.be.true;
190+
191+
vm.$set('form.search.value', 'test');
192+
setTimeout(()=>{
193+
expect(vm.form.$errors.search.expression).to.be.false;
194+
done();
195+
},0);
127196
});
128197

129198
});

test/unit/specs/FormlyForm.spec.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,26 @@ describe('FormlyForm', () => {
111111
createForm('<formly-form :form="form"></formly-form>', data);
112112
expect(vm.form.$errors).to.deep.equal({});
113113
expect(vm.form.$valid).to.be.true;
114-
vm.$set('form.$errors.test', 'testing');
114+
vm.$set('form.$errors.test', {foo: true});
115115

116116
setTimeout(()=>{
117117
expect(vm.form.$valid).to.be.false;
118118
done();
119119
},0);
120120
});
121+
122+
it('should skip empty errors', (done)=>{
123+
let data = {
124+
form: {
125+
126+
}
127+
};
128+
createForm('<formly-form :form="form"></formly-form>', data);
129+
vm.$set('form.$errors.test', {foo: false});
130+
setTimeout(() => {
131+
expect(vm.form.$valid).to.be.true;
132+
done();
133+
});
134+
});
121135

122136
});

test/unit/specs/index.spec.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {expect} from 'chai';
22

33
import VueFormly from 'src/index';
4-
import Util, {addType, getTypes, addError, removeError} from 'src/util';
4+
import Util, {addType, getTypes, setError} from 'src/util';
55

66

77
describe('module', () => {
@@ -13,8 +13,7 @@ describe('module', () => {
1313
expect(VueFormly.getTypes).to.be.a('function');
1414
expect(addType).to.be.a('function');
1515
expect(getTypes).to.be.a('function');
16-
expect(addError).to.be.a('function');
17-
expect(removeError).to.be.a('function');
16+
expect(setError).to.be.a('function');
1817
expect(Util.formlyFields).to.be.a('object');
1918
});
2019

@@ -36,13 +35,13 @@ describe('module', () => {
3635

3736
it('should handle errors',()=>{
3837
let form = {
39-
'$errors': {}
38+
$errors: {}
4039
};
41-
addError(form, 'fname', 'required');
40+
setError(form, 'fname', 'required', true);
4241
expect(form.$errors.fname.required).to.be.true;
4342

44-
removeError(form, 'fname', 'required');
45-
expect(typeof form.$errors.fname).to.equal('undefined');
43+
setError(form, 'fname', 'required', false);
44+
expect(form.$errors.fname.required).to.be.false;
4645
});
4746

4847
});

0 commit comments

Comments
 (0)