Skip to content
This repository was archived by the owner on Dec 25, 2017. It is now read-only.

Commit 83f5806

Browse files
committed
feat(errors): add manually validation error message settings
Closes #70
1 parent cc19283 commit 83f5806

File tree

5 files changed

+289
-6
lines changed

5 files changed

+289
-6
lines changed

README.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,109 @@ Vue.validator('url', function (val) {
795795
new Vue({ el: '#app' })
796796
```
797797

798+
## Manually error message settings
799+
800+
Sometimes, you need to manually set the validation error message such as server-side validation error. At that time, you can apply some error messages to validation results with using `$setValidationErrors` meta method.
801+
802+
### vm.$setValidationErrors(erros)
803+
804+
- **Arguments:**
805+
- `Array<Object>` errors
806+
- `{String}` feild
807+
- `{String}` message
808+
- `{String}` validator [optional]
809+
810+
- **Usage:**
811+
812+
Set the `errors` to validation result errors. This is useful when you want to set manually some errors of server-side validation.
813+
814+
- **Example:**
815+
816+
```html
817+
<div id="app">
818+
<validator name="validation">
819+
<div class="username">
820+
<label for="username">username:</label>
821+
<input id="username" type="text" v-model="username" v-validate:username="{
822+
required: { rule: true, message: 'required you name !!' }
823+
}">
824+
</div>
825+
<div class="old">
826+
<label for="old">old password:</label>
827+
<input id="old" type="text" v-model="passowrd.old" v-validate:old="{
828+
required: { rule: true, message: 'required you old password !!' }
829+
}"/>
830+
</div>
831+
<div class="new">
832+
<label for="new">new password:</label>
833+
<input id="new" type="text" v-model="password.new" v-validate:new="{
834+
required: { rule: true, message: 'required you new password !!' },
835+
minlength: { rule: 8, message: 'your new password short too !!' }
836+
}"/>
837+
</div>
838+
<div class="confirm">
839+
<label for="confirm">confirm password:</label>
840+
<input id="confirm" type="text" v-validate:confirm="{
841+
required: { rule: true, message: 'required you confirm password !!' },
842+
confirm: { rule: true, message: 'your confirm password incorrect !!' }
843+
}"/>
844+
</div>
845+
<div class="errors">
846+
<validator-errors :validation="$validation"></validator-errors>
847+
</div>
848+
<button type="button" v-if="$validation.valid" @click.prevent="onSubmit">update</button>
849+
</validator>
850+
</div>
851+
```
852+
```javascript
853+
new Vue({
854+
el: '#app',
855+
data: {
856+
id: 1,
857+
username: '',
858+
password: {
859+
old: '',
860+
new: ''
861+
}
862+
},
863+
validators: {
864+
confirm: function (val) {
865+
return this.password.new === val
866+
}
867+
},
868+
methods: {
869+
onSubmit: function () {
870+
var self = this
871+
var resource = this.$resource('/user/:id')
872+
resource.save({ id: this.id }, {
873+
username: this.username,
874+
passowrd: this.new
875+
}, function (data, stat, req) {
876+
// something handle success ...
877+
// ...
878+
}).error(function (data, stat, req) {
879+
// handle server error
880+
self.$setValidationErrors([
881+
{ field: data.field, message: data.message }
882+
])
883+
})
884+
}
885+
}
886+
})
887+
```
888+
889+
- **Argument: field**
890+
891+
To detect as validation feild error, you need to pass in `field` argument.
892+
893+
- **Argument: message**
894+
895+
To output as validation error messsage, you need to pass in `message` argument.
896+
897+
- **Argument: validator**
898+
899+
In order to detect where the validator error occurred, you pass in `validator` argument.
900+
798901

799902
# Event
800903

example/errors/manually/index.html

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>manually error message example</title>
6+
<script src="../../../node_modules/vue/dist/vue.min.js"></script>
7+
<script src="../../../dist/vue-validator.min.js"></script>
8+
<style>
9+
.errors { color: red; }
10+
</style>
11+
</head>
12+
<body>
13+
<div id="app">
14+
<validator name="validation">
15+
<div class="username">
16+
<label for="username">username:</label>
17+
<input id="username" type="text" v-model="username" v-validate:username="{
18+
required: { rule: true, message: 'required you name !!' }
19+
}">
20+
</div>
21+
<div class="old">
22+
<label for="old">old password:</label>
23+
<input id="old" type="text" v-model="passowrd.old" v-validate:old="{
24+
required: { rule: true, message: 'required you old password !!' }
25+
}"/>
26+
</div>
27+
<div class="new">
28+
<label for="new">new password:</label>
29+
<input id="new" type="text" v-model="password.new" v-validate:new="{
30+
required: { rule: true, message: 'required you new password !!' },
31+
minlength: { rule: 8, message: 'your new password short too !!' }
32+
}"/>
33+
</div>
34+
<div class="confirm">
35+
<label for="confirm">confirm password:</label>
36+
<input id="confirm" type="text" v-validate:confirm="{
37+
required: { rule: true, message: 'required you confirm password !!' },
38+
confirm: { rule: true, message: 'your confirm password incorrect !!' }
39+
}"/>
40+
</div>
41+
<div class="errors">
42+
<validator-errors :validation="$validation"></validator-errors>
43+
</div>
44+
<button type="button" v-if="$validation.valid" @click.prevent="onSubmit">update</button>
45+
</validator>
46+
</div>
47+
<script>
48+
new Vue({
49+
el: '#app',
50+
data: {
51+
id: 1,
52+
username: '',
53+
password: {
54+
old: '',
55+
new: ''
56+
}
57+
},
58+
validators: {
59+
confirm: function (val) {
60+
return this.password.new === val
61+
}
62+
},
63+
methods: {
64+
onSubmit: function () {
65+
var self = this
66+
67+
// simulate server validation errors
68+
setTimeout(function () {
69+
self.$setValidationErrors([
70+
{ field: 'old', message: 'sorry, your account is locked !!' }
71+
])
72+
}, 2000)
73+
}
74+
}
75+
})
76+
</script>
77+
</body>
78+
</html>

src/validator.js

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,17 @@ export default class Validator {
4646
this._dir.vm.$validate = (field) => {
4747
this._validate(field)
4848
}
49+
50+
// define manually the validation errors
51+
this._dir.vm.$setValidationErrors = (errors) => {
52+
this._setValidationErrors(errors)
53+
}
4954
}
5055

5156
disableReactive () {
52-
this._dir.vm.$validate = null
53-
this._dir.vm.$validatorReset = null
57+
this._dir.vm.$setValidationErrors = undefined
58+
this._dir.vm.$validate = undefined
59+
this._dir.vm.$validatorReset = undefined
5460
this._dir.vm._validatorMaps[this.name] = null
5561
this._dir.vm[this.name] = null
5662
}
@@ -116,6 +122,35 @@ export default class Validator {
116122
this.validate()
117123
}
118124

125+
_setValidationErrors (errors) {
126+
const extend = util.Vue.util.extend
127+
128+
// make tempolaly errors
129+
let temp = {}
130+
each(errors, (error, index) => {
131+
if (!temp[error.field]) {
132+
temp[error.field] = []
133+
}
134+
temp[error.field].push(error)
135+
})
136+
137+
// set errors
138+
each(temp, (values, field) => {
139+
let validation = this._scope[field]
140+
let newValidation = {}
141+
each(values, (error) => {
142+
if (error.validator) {
143+
validation[error.validator] = error.message
144+
}
145+
})
146+
validation.valid = false
147+
validation.invalid = true
148+
validation.errors = values
149+
extend(newValidation, validation)
150+
util.Vue.set(this._scope, field, newValidation)
151+
}, this)
152+
}
153+
119154
// TODO: should be improved performance (use cache)
120155
get validations () {
121156
const extend = util.Vue.util.extend

test/specs/messages.js renamed to test/specs/errors.js

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Vue from 'vue'
33
import { each, empty, trigger } from '../../src/util'
44

55

6-
describe('messages', () => {
6+
describe('errors', () => {
77
let el, vm
88

99
let testMatches = (target, validatorErrors) => {
@@ -57,7 +57,8 @@ describe('messages', () => {
5757
vm.$nextTick(done)
5858
})
5959

60-
context('invalid', () => {
60+
61+
describe('invalid', () => {
6162
beforeEach((done) => {
6263
let field3 = el.getElementsByTagName('input')[2]
6364
field3.value = '4'
@@ -123,7 +124,7 @@ describe('messages', () => {
123124
})
124125

125126

126-
context('valid', () => {
127+
describe('valid', () => {
127128
beforeEach((done) => {
128129
let field1 = el.getElementsByTagName('input')[0]
129130
field1.value = 'foo'
@@ -186,4 +187,70 @@ describe('messages', () => {
186187
})
187188
})
188189
})
190+
191+
192+
describe('$setValidationErrors', () => {
193+
beforeEach((done) => {
194+
let field1 = el.getElementsByTagName('input')[0]
195+
field1.value = 'foo'
196+
trigger(field1, 'input')
197+
trigger(field1, 'blur')
198+
vm.$nextTick(() => {
199+
let field2 = el.getElementsByTagName('input')[1]
200+
field2.value = 'hello'
201+
trigger(field2, 'input')
202+
trigger(field2, 'blur')
203+
vm.$nextTick(() => {
204+
let field3 = el.getElementsByTagName('input')[2]
205+
field3.value = '1'
206+
trigger(field3, 'input')
207+
trigger(field3, 'blur')
208+
vm.$nextTick(() => {
209+
let field4 = el.getElementsByTagName('input')[3]
210+
field4.value = 'hi'
211+
trigger(field4, 'input')
212+
trigger(field4, 'blur')
213+
vm.$nextTick(() => {
214+
let field5 = el.getElementsByTagName('input')[4]
215+
field5.value = '10'
216+
trigger(field5, 'input')
217+
trigger(field5, 'blur')
218+
vm.$nextTick(() => {
219+
let field6 = el.getElementsByTagName('input')[5]
220+
field6.value = 'hello'
221+
trigger(field6, 'input')
222+
trigger(field6, 'blur')
223+
done()
224+
})
225+
})
226+
})
227+
})
228+
})
229+
})
230+
231+
it('should be set errors', (done) => {
232+
vm.$setValidationErrors([
233+
{ field: 'field1', validator: 'pattern', message: 'failed field1 server validation error' },
234+
{ field: 'field5', validator: 'min', message: 'failed field5 server validation error' }
235+
])
236+
vm.$nextTick(() => {
237+
assert(vm.$validation.field1.pattern === 'failed field1 server validation error')
238+
assert(vm.$validation.field1.valid === false)
239+
assert(vm.$validation.field1.invalid === true)
240+
assert(vm.$validation.field1.errors[0].validator === 'pattern')
241+
assert(vm.$validation.field1.errors[0].message === 'failed field1 server validation error')
242+
assert(vm.$validation.field5.min === 'failed field5 server validation error')
243+
assert(vm.$validation.field5.valid === false)
244+
assert(vm.$validation.field5.invalid === true)
245+
assert(vm.$validation.field5.errors[0].validator === 'min')
246+
assert(vm.$validation.field5.errors[0].message === 'failed field5 server validation error')
247+
assert(vm.$validation.valid === false)
248+
assert(vm.$validation.invalid === true)
249+
assert(!empty(vm.$validation.errors))
250+
assert(vm.$validation.group1.errors.length === 2)
251+
assert(empty(vm.$validation.group2.errors))
252+
done()
253+
})
254+
})
255+
})
189256
})

test/specs/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ require('./event')
2323
require('./group')
2424
require('./multiple')
2525
require('./components/errors')
26-
require('./messages')
26+
require('./errors')
2727
require('./lazy')
2828
require('./checkbox')
2929
require('./radio')

0 commit comments

Comments
 (0)