Skip to content

Commit e54c304

Browse files
committed
added global validation messages
1 parent b3015b2 commit e54c304

File tree

5 files changed

+139
-24
lines changed

5 files changed

+139
-24
lines changed

src/components/FormlyField.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<script>
66
const Vue = require('vue');
7-
import Util, {getTypes, setError} from '../util';
7+
import Util, {getTypes, setError, parseValidationString} from '../util';
88
export default {
99
props: ['form', 'model', 'field', 'to'],
1010
computed: {
@@ -49,6 +49,9 @@
4949
}
5050
}
5151
52+
let label = ( 'templateOptions' in this.field ) && ( 'label' in this.field.templateOptions ) ? this.field.templateOptions.label : '';
53+
validatorMessage = parseValidationString( validKey, validatorMessage, label, model[ this.field.key ] );
54+
5255
let valid = typeof validator == 'function' ? !validator(field, model) : !eval(validator);
5356
setError(this.form, this.field.key, validKey, valid, validatorMessage);
5457

src/index.js

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
import Components from './components/index';
22
import Filters from './filters/index';
3-
import Util,{getTypes, addType} from './util';
3+
import Util,{getTypes, addType, addValidationMessage} from './util';
44

55

66
let Formly = {
7-
getTypes,
8-
addType,
9-
install(Vue, options){
10-
11-
//install our components
12-
Components(Vue);
13-
Filters(Vue);
7+
getTypes,
8+
addType,
9+
addValidationMessage,
10+
install(Vue, options){
11+
12+
//install our components
13+
Components(Vue);
14+
Filters(Vue);
1415

15-
Vue.$formly = {getTypes, addType};
16-
}
16+
Vue.$formly = {getTypes, addType, addValidationMessage};
17+
}
1718
};
1819

1920
//auto install
2021
if (typeof window !== 'undefined' && window.Vue) {
21-
window.Vue.use(Formly);
22-
//expose formly functions if auto installed
23-
window.Vue.$formly = {getTypes, addType};
22+
window.Vue.use(Formly);
23+
//expose formly functions if auto installed
24+
window.Vue.$formly = {getTypes, addType, addValidationMessage};
2425
}
2526
export default Formly;

src/util.js

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const exports = {
2-
formlyFields: {}
2+
formlyFields: {},
3+
validationMessages: {}
34
};
45
export default exports;
56

@@ -11,11 +12,11 @@ export default exports;
1112
* @param {Object} options
1213
*/
1314
export function addType(id, options){
14-
exports.formlyFields['formly_'+id] = options;
15+
exports.formlyFields['formly_'+id] = options;
1516
}
1617

1718
export function getTypes(){
18-
return exports.formlyFields;
19+
return exports.formlyFields;
1920
}
2021

2122
/**
@@ -26,6 +27,36 @@ export function getTypes(){
2627
* @param {Bool} isError
2728
*/
2829
export function setError(form, key, err, isError, message = false){
29-
if ( !form.$errors[key] ) form.$errors[key] = {};
30-
form.$errors[key][err] = message || isError;
30+
if ( !form.$errors[key] ) form.$errors[key] = {};
31+
form.$errors[key][err] = message || isError;
32+
}
33+
34+
/**
35+
* Adds a validation string to Vue Formly to be used later on by validations
36+
* @param {string} key
37+
* @param {string} message
38+
*/
39+
export function addValidationMessage(key, message){
40+
exports.validationMessages[ key ] = message;
41+
}
42+
43+
/**
44+
* Given a message key or message it parses in the label and the value
45+
* @param {string/bool} key
46+
* @param {string} message
47+
* @param {string} label
48+
* @param {string} value
49+
*/
50+
export function parseValidationString(key, message, label, value){
51+
52+
// if a key has been passed and there's no validation message and no message has been passed then return
53+
if ( key && !(key in exports.validationMessages ) && !message ) return false;
54+
55+
// first check if a validation message with this key exists
56+
if ( key in exports.validationMessages ){
57+
message = exports.validationMessages[key];
58+
}
59+
60+
let output = message.replace(/\%l/g, label).replace(/\%v/g, value);
61+
return output;
3162
}

test/unit/specs/FormlyField.spec.js

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import chai from 'chai';
22
const expect = chai.expect;
33
import Vue from 'vue';
44
import FormlyField from 'src/components/FormlyField.vue';
5+
import Utils from 'src/util';
56

67
let el, vm;
78

@@ -291,8 +292,6 @@ describe('FormlyField', () => {
291292

292293
//--- define messages ---
293294
//vf.addValidationString('validatorKey', 'message');
294-
//vf.addValidationPattern('validatorKey', '%l is required');
295-
//vf.addValidationPattern('validatorKey', '%v is too small');
296295

297296
//add specific messages
298297
/*
@@ -331,6 +330,67 @@ describe('FormlyField', () => {
331330
createValidField(data);
332331
expect(vm.form.$errors.search.validatorMessage).to.equal('Must equal test');
333332
});
333+
334+
it('Inline messages with values parsed', () => {
335+
let data = {
336+
form: {
337+
$valid: true,
338+
$errors: {}
339+
},
340+
model: {
341+
search: 'testing'
342+
},
343+
fields: [
344+
{
345+
key: 'search',
346+
type: 'test',
347+
templateOptions: {
348+
label: 'test'
349+
},
350+
validators: {
351+
validatorMessage:
352+
{
353+
expression: 'model.search == "test"',
354+
message: '%l and %v'
355+
}
356+
}
357+
}
358+
]
359+
};
360+
361+
createValidField(data);
362+
expect(vm.form.$errors.search.validatorMessage).to.equal('test and testing');
363+
});
364+
365+
it('Global messages with values parsed', () => {
366+
let data = {
367+
form: {
368+
$valid: true,
369+
$errors: {}
370+
},
371+
model: {
372+
search: 'testing'
373+
},
374+
fields: [
375+
{
376+
key: 'search',
377+
type: 'test',
378+
templateOptions: {
379+
label: 'test'
380+
},
381+
validators: {
382+
validatorMessage: 'model.search == "test"',
383+
}
384+
}
385+
]
386+
};
387+
388+
//just mock the other vue functions
389+
Utils.validationMessages.validatorMessage = '%l and %v';
390+
391+
createValidField(data);
392+
expect(vm.form.$errors.search.validatorMessage).to.equal('test and testing');
393+
});
334394

335395
});
336396

test/unit/specs/index.spec.js

Lines changed: 23 additions & 3 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, setError} from 'src/util';
4+
import Util, {addType, getTypes, setError, addValidationMessage, parseValidationString} from 'src/util';
55

66

77
describe('module', () => {
@@ -11,13 +11,14 @@ describe('module', () => {
1111
expect(VueFormly.install).to.be.a('function');
1212
expect(VueFormly.addType).to.be.a('function');
1313
expect(VueFormly.getTypes).to.be.a('function');
14+
expect(VueFormly.addValidationMessage).to.be.a('function');
1415
expect(addType).to.be.a('function');
1516
expect(getTypes).to.be.a('function');
1617
expect(setError).to.be.a('function');
1718
expect(Util.formlyFields).to.be.a('object');
1819
});
1920

20-
it('should add fields to Vue', () => {
21+
it('addType()', () => {
2122

2223
//mock vue
2324
window.Vue = {
@@ -33,7 +34,7 @@ describe('module', () => {
3334
expect(getTypes().formly_test).to.deep.equal(newField);
3435
});
3536

36-
it('should handle errors',()=>{
37+
it('setError()',()=>{
3738
let form = {
3839
$errors: {}
3940
};
@@ -46,5 +47,24 @@ describe('module', () => {
4647
setError(form, 'fname', 'required', true, 'Hey there');
4748
expect(form.$errors.fname.required).to.equal('Hey there');
4849
});
50+
51+
it('addValidationMessage()', () => {
52+
addValidationMessage('test', 'testing');
53+
expect(Util.validationMessages.test).to.equal('testing');
54+
});
55+
56+
it('parseValidationString()', () => {
57+
addValidationMessage('parseTest', '%l just %v testing');
58+
let message = '%l just %v testing';
59+
let expected = 'label just value testing';
60+
let output = parseValidationString('parseTest', false, 'label', 'value');
61+
expect(output).to.equal(expected);
62+
63+
output = parseValidationString(false, message, 'label', 'value');
64+
expect(output).to.equal(expected);
65+
66+
output = parseValidationString('blahblahblah', false, '', '');
67+
expect(output).to.be.false;
68+
});
4969

5070
});

0 commit comments

Comments
 (0)