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

Commit

Permalink
feat(event): add touched, dirty and modified event for element level
Browse files Browse the repository at this point in the history
  • Loading branch information
kazupon committed Jan 26, 2016
1 parent dd4e03b commit 675bb30
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 4 deletions.
10 changes: 9 additions & 1 deletion src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,19 @@ export function attr (el, name) {
*
* @param {Element} el
* @param {String} event
* @param {Object} [args]
*/

export function trigger (el, event) {
export function trigger (el, event, args) {
let e = document.createEvent('HTMLEvents')
e.initEvent(event, true, false)

if (args) {
for (let prop in args) {
e[prop] = args[prop]
}
}

// Due to Firefox bug, events fired on disabled
// non-attached form controls can throw errors
try { el.dispatchEvent(e) } catch (e) {}
Expand Down
13 changes: 10 additions & 3 deletions src/validations/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default class BaseValidation {
this.dirty = false
this.modified = false

this._modifiedOrg = false
this._model = model
this._validator = validator
this._vm = vm
Expand Down Expand Up @@ -68,13 +69,19 @@ export default class BaseValidation {
handleValidate (el, type) {
if (type && type === 'blur') {
this.touched = true
this._fireEvent(el, 'touched')
}

if (!this.dirty && this._checkModified(el)) {
this.dirty = true
this._fireEvent(el, 'dirty')
}

this.modified = this._checkModified(el)
if (this.modifiedOrg !== this.modified) {
this._fireEvent(el, 'modified', { modified: this.modified })
this.modifiedOrg = this.modified
}

this._validator.validate()
}
Expand Down Expand Up @@ -120,7 +127,7 @@ export default class BaseValidation {
}
}, this)

this._fireEvent(this._el, valid)
this._fireEvent(this._el, valid ? 'valid' : 'invalid')

let props = {
valid: valid,
Expand Down Expand Up @@ -162,8 +169,8 @@ export default class BaseValidation {
return this._init !== this._getValue(target)
}

_fireEvent (el, valid) {
trigger(el, valid ? 'valid' : 'invalid')
_fireEvent (el, type, args) {
trigger(el, type, args)
}

_resolveValidator (name) {
Expand Down
82 changes: 82 additions & 0 deletions test/specs/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('event', () => {
})
})


describe('invalid', () => {
it('should be occured event', (done) => {
el.innerHTML =
Expand All @@ -56,4 +57,85 @@ describe('event', () => {
})
})
})


describe('touched', () => {
it('should be occured event', (done) => {
el.innerHTML =
'<validator name="validator1">' +
'<input type="text" value="hello" @touched="onTouched" v-validate:field1="{ required: true }">' +
'</validator>'
vm = new Vue({
el: el,
methods: {
onTouched () {
assert(true)
done()
}
}
})
vm.$nextTick(() => {
let input = el.getElementsByTagName('input')[0]
trigger(input, 'input')
trigger(input, 'blur')
})
})
})


describe('dirty', () => {
it('should be occured event', (done) => {
el.innerHTML =
'<validator name="validator1">' +
'<input type="text" value="hello" @dirty="onDirty" v-validate:field1="{ required: true }">' +
'</validator>'
vm = new Vue({
el: el,
methods: {
onDirty () {
assert(true)
done()
}
}
})
vm.$nextTick(() => {
let input = el.getElementsByTagName('input')[0]
input.value = ''
trigger(input, 'input')
})
})
})


describe('modified', () => {
it('should be occured event', (done) => {
let results = []
el.innerHTML =
'<validator name="validator1">' +
'<input type="text" value="hello" @modified="onModified" v-validate:field1="{ required: true }">' +
'</validator>'
vm = new Vue({
el: el,
methods: {
onModified (e) {
results.push(e.modified)
if (results.length === 2) {
assert(results[0] === true) // first event
assert(results[1] === false) // second event
done()
}
}
}
})
vm.$nextTick(() => {
let input = el.getElementsByTagName('input')[0]
input.value = ''
trigger(input, 'input')
vm.$nextTick(() => {
input.value = 'hello'
trigger(input, 'input')
})
})
})
})
})

0 comments on commit 675bb30

Please sign in to comment.