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

Commit 0579685

Browse files
committed
bug(timing): fix the initiali timing when use v-model integration
Closes #214
1 parent d06d6be commit 0579685

File tree

3 files changed

+248
-2
lines changed

3 files changed

+248
-2
lines changed

src/validations/base.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export default class BaseValidation {
5858
return
5959
}
6060

61-
this.handleValidate(el, this._initial)
61+
this.handleValidate(el, { noopable: this._initial })
6262
if (this._initial) {
6363
this._initial = null
6464
}

src/validations/select.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export default class SelectValidation extends BaseValidation {
3838
return
3939
}
4040

41-
this.handleValidate(el, this._initial)
41+
this.handleValidate(el, { noopable: this._initial })
4242
if (this._initial) {
4343
this._initial = null
4444
}

test/specs/issues.js

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import assert from 'power-assert'
22
import Vue from 'vue'
3+
import { trigger } from '../../src/util'
34

45

56
describe('github issues', () => {
@@ -122,4 +123,249 @@ describe('github issues', () => {
122123
})
123124
})
124125
})
126+
127+
128+
describe('#214', () => {
129+
describe('text v-model', () => {
130+
beforeEach((done) => {
131+
el.innerHTML = '<validator name="validator1">'
132+
+ '<form novalidate>'
133+
+ '<input type="text" v-model="msg" initial="off" v-validate:field1="{ required: true, minlength: 10 }">'
134+
+ '</form>'
135+
+ '</validator>'
136+
vm = new Vue({
137+
el: el,
138+
data: { msg: 'hello' }
139+
})
140+
vm.$nextTick(done)
141+
})
142+
143+
it('should be validated', (done) => {
144+
let field = el.getElementsByTagName('input')[0]
145+
146+
// default
147+
assert(vm.$validator1.field1.required === false)
148+
assert(vm.$validator1.field1.minlength === false)
149+
assert(vm.$validator1.field1.valid === true)
150+
assert(vm.$validator1.field1.touched === false)
151+
assert(vm.$validator1.field1.modified === false)
152+
assert(vm.$validator1.field1.dirty === false)
153+
assert(field.value === vm.msg)
154+
155+
// modify vm property
156+
vm.msg = 'helloworld!!'
157+
setTimeout(() => {
158+
assert(vm.$validator1.field1.required === false)
159+
assert(vm.$validator1.field1.minlength === false)
160+
assert(vm.$validator1.field1.valid === true)
161+
assert(vm.$validator1.field1.touched === false)
162+
assert(vm.$validator1.field1.modified === true)
163+
assert(vm.$validator1.field1.dirty === true)
164+
assert(field.value === vm.msg)
165+
166+
field.value = 'foo'
167+
trigger(field, 'input')
168+
trigger(field, 'blur')
169+
vm.$nextTick(() => {
170+
assert(vm.$validator1.field1.required === false)
171+
assert(vm.$validator1.field1.minlength === true)
172+
assert(vm.$validator1.field1.valid === false)
173+
assert(vm.$validator1.field1.touched === true)
174+
assert(vm.$validator1.field1.modified === true)
175+
assert(vm.$validator1.field1.dirty === true)
176+
177+
done()
178+
})
179+
}, 10)
180+
})
181+
})
182+
183+
describe('checkbox v-model', () => {
184+
beforeEach((done) => {
185+
el.innerHTML = '<validator name="validator1">'
186+
+ '<form novalidate>'
187+
+ '<input type="checkbox" v-model="checkedNames" initial="off" value="foo" v-validate:field1="{ required: true, minlength: 2 }">'
188+
+ '<input type="checkbox" v-model="checkedNames" initial="off" value="bar" v-validate:field1>'
189+
+ '<input type="checkbox" v-model="checkedNames" initial="off" value="buz" v-validate:field1>'
190+
+ '</form>'
191+
+ '</validator>'
192+
vm = new Vue({
193+
el: el,
194+
data: { checkedNames: [] }
195+
})
196+
vm.$nextTick(done)
197+
})
198+
199+
it('should be validated', (done) => {
200+
let foo = el.getElementsByTagName('input')[0]
201+
let bar = el.getElementsByTagName('input')[1]
202+
203+
// default
204+
assert(vm.$validator1.field1.required === false)
205+
assert(vm.$validator1.field1.minlength === false)
206+
assert(vm.$validator1.field1.valid === true)
207+
assert(vm.$validator1.field1.touched === false)
208+
assert(vm.$validator1.field1.dirty === false)
209+
assert(vm.$validator1.field1.modified === false)
210+
211+
// checked foo
212+
foo.checked = true
213+
trigger(foo, 'change')
214+
trigger(foo, 'click')
215+
trigger(foo, 'blur')
216+
vm.$nextTick(() => {
217+
assert(vm.$validator1.field1.required === false)
218+
assert(vm.$validator1.field1.minlength === true)
219+
assert(vm.$validator1.field1.valid === false)
220+
assert(vm.$validator1.field1.touched === true)
221+
assert(vm.$validator1.field1.dirty === true)
222+
assert(vm.$validator1.field1.modified === true)
223+
assert(vm.checkedNames.sort().toString() === ['foo'].sort().toString())
224+
225+
// checked bar
226+
bar.checked = true
227+
trigger(bar, 'change')
228+
trigger(bar, 'click')
229+
trigger(bar, 'blur')
230+
vm.$nextTick(() => {
231+
assert(vm.$validator1.field1.required === false)
232+
assert(vm.$validator1.field1.minlength === false)
233+
assert(vm.$validator1.field1.valid === true)
234+
assert(vm.$validator1.field1.touched === true)
235+
assert(vm.$validator1.field1.dirty === true)
236+
assert(vm.$validator1.field1.modified === true)
237+
assert(vm.checkedNames.sort().toString() === ['foo', 'bar'].sort().toString())
238+
239+
done()
240+
})
241+
})
242+
})
243+
})
244+
245+
describe('radio v-model', () => {
246+
beforeEach((done) => {
247+
el.innerHTML = '<validator name="validator1">'
248+
+ '<form novalidate>'
249+
+ '<input type="radio" v-model="picked" name="r1" value="foo" initial="off" v-validate:field1="{ required: true }">'
250+
+ '<input type="radio" v-model="picked" name="r1" value="bar" initial="off" v-validate:field1>'
251+
+ '</form>'
252+
+ '</validator>'
253+
vm = new Vue({
254+
el: el,
255+
data: { picked: 'foo' }
256+
})
257+
vm.$nextTick(done)
258+
})
259+
260+
it('should be validated', (done) => {
261+
let foo = el.getElementsByTagName('input')[0]
262+
let bar = el.getElementsByTagName('input')[1]
263+
264+
// default
265+
assert(vm.$validator1.field1.required === false)
266+
assert(vm.$validator1.field1.valid === true)
267+
assert(vm.$validator1.field1.touched === false)
268+
assert(vm.$validator1.field1.dirty === false)
269+
assert(vm.$validator1.field1.modified === false)
270+
assert(vm.$validator1.valid === true)
271+
assert(vm.$validator1.touched === false)
272+
assert(vm.$validator1.dirty === false)
273+
assert(vm.$validator1.modified === false)
274+
275+
// change bar radio
276+
bar.checked = true
277+
trigger(bar, 'change')
278+
trigger(bar, 'blur')
279+
vm.$nextTick(() => {
280+
assert(vm.$validator1.field1.required === false)
281+
assert(vm.$validator1.field1.valid === true)
282+
assert(vm.$validator1.field1.touched === true)
283+
assert(vm.$validator1.field1.dirty === true)
284+
assert(vm.$validator1.field1.modified === true)
285+
assert(vm.$validator1.valid === true)
286+
assert(vm.$validator1.touched === true)
287+
assert(vm.$validator1.dirty === true)
288+
assert(vm.$validator1.modified === true)
289+
assert(vm.picked === 'bar')
290+
291+
// back to foo radio
292+
foo.checked = true
293+
trigger(foo, 'change')
294+
trigger(foo, 'blur')
295+
vm.$nextTick(() => {
296+
assert(vm.$validator1.field1.required === false)
297+
assert(vm.$validator1.field1.valid === true)
298+
assert(vm.$validator1.field1.touched === true)
299+
assert(vm.$validator1.field1.dirty === true)
300+
assert(vm.$validator1.field1.modified === false)
301+
assert(vm.$validator1.valid === true)
302+
assert(vm.$validator1.touched === true)
303+
assert(vm.$validator1.dirty === true)
304+
assert(vm.$validator1.modified === false)
305+
assert(vm.picked === 'foo')
306+
307+
done()
308+
})
309+
})
310+
})
311+
})
312+
313+
describe('select v-model', () => {
314+
beforeEach((done) => {
315+
el.innerHTML = '<validator name="validator1">'
316+
+ '<form novalidate>'
317+
+ '<select v-model="lang" initial="off" v-validate:lang="{ required: true }">'
318+
+ '<option value="en">english</option>'
319+
+ '<option selected value="ja">japanese</option>'
320+
+ '<option value="zh">chinese</option>'
321+
+ '</select>'
322+
+ '</form>'
323+
+ '</validator>'
324+
vm = new Vue({
325+
el: el,
326+
data: { lang: 'ja' }
327+
})
328+
vm.$nextTick(done)
329+
})
330+
331+
it('should be validated', (done) => {
332+
let select = el.getElementsByTagName('select')[0]
333+
let en = el.getElementsByTagName('option')[0]
334+
let zh = el.getElementsByTagName('option')[2]
335+
336+
// default
337+
assert(vm.$validator1.lang.required === false)
338+
assert(vm.$validator1.lang.valid === true)
339+
assert(vm.$validator1.lang.touched === false)
340+
assert(vm.$validator1.lang.dirty === false)
341+
assert(vm.$validator1.lang.modified === false)
342+
assert(vm.lang === 'ja')
343+
344+
en.selected = true
345+
trigger(select, 'change')
346+
vm.$nextTick(() => {
347+
assert(vm.$validator1.lang.required === false)
348+
assert(vm.$validator1.lang.valid === true)
349+
assert(vm.$validator1.lang.touched === false)
350+
assert(vm.$validator1.lang.dirty === true)
351+
assert(vm.$validator1.lang.modified === true)
352+
assert(vm.lang === 'en')
353+
354+
zh.selected = true
355+
trigger(select, 'change')
356+
trigger(select, 'blur')
357+
vm.$nextTick(() => {
358+
assert(vm.$validator1.lang.required === false)
359+
assert(vm.$validator1.lang.valid === true)
360+
assert(vm.$validator1.lang.touched === true)
361+
assert(vm.$validator1.lang.dirty === true)
362+
assert(vm.$validator1.lang.modified === true)
363+
assert(vm.lang === 'zh')
364+
365+
done()
366+
})
367+
})
368+
})
369+
})
370+
})
125371
})

0 commit comments

Comments
 (0)