Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1e15840

Browse filesBrowse files
committed
Merge pull request vuejs#1129 from fergaldoyle/v-model-enhancments
v-model radio and checkbox expressions
2 parents 199a55f + b73e77c commit 1e15840
Copy full SHA for 1e15840

File tree

3 files changed

+93
-7
lines changed
Filter options

3 files changed

+93
-7
lines changed

‎src/directives/model/checkbox.js

Copy file name to clipboardExpand all lines: src/directives/model/checkbox.js
+27-3Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,41 @@ module.exports = {
55
bind: function () {
66
var self = this
77
var el = this.el
8+
var trueExp = this._checkParam('true-exp')
9+
var falseExp = this._checkParam('false-exp')
10+
11+
function getValue () {
12+
var val = el.checked
13+
if (val && trueExp !== null) {
14+
val = self.vm.$eval(trueExp)
15+
}
16+
if (!val && falseExp !== null) {
17+
val = self.vm.$eval(falseExp)
18+
}
19+
return val
20+
}
21+
this._getValue = getValue
22+
23+
function matchValue (value) {
24+
var trueValue = true
25+
if (trueExp !== null) {
26+
trueValue = self.vm.$eval(trueExp)
27+
}
28+
return trueValue === value
29+
}
30+
this._matchValue = matchValue
31+
832
this.listener = function () {
9-
self.set(el.checked)
33+
self.set(getValue())
1034
}
1135
_.on(el, 'change', this.listener)
1236
if (el.checked) {
13-
this._initValue = el.checked
37+
this._initValue = getValue()
1438
}
1539
},
1640

1741
update: function (value) {
18-
this.el.checked = !!value
42+
this.el.checked = this._matchValue(value)
1943
},
2044

2145
unbind: function () {

‎src/directives/model/radio.js

Copy file name to clipboardExpand all lines: src/directives/model/radio.js
+10-4Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@ module.exports = {
66
var self = this
77
var el = this.el
88
var number = this._checkParam('number') != null
9+
var expression = this._checkParam('exp')
910
function getValue () {
10-
return number
11-
? _.toNumber(el.value)
12-
: el.value
11+
var val = el.value
12+
if (number) {
13+
val = _.toNumber(val)
14+
} else if (expression !== null) {
15+
val = self.vm.$eval(expression)
16+
}
17+
return val
1318
}
19+
this._getValue = getValue
1420
this.listener = function () {
1521
self.set(getValue())
1622
}
@@ -22,7 +28,7 @@ module.exports = {
2228

2329
update: function (value) {
2430
/* eslint-disable eqeqeq */
25-
this.el.checked = value == this.el.value
31+
this.el.checked = value == this._getValue()
2632
/* eslint-enable eqeqeq */
2733
},
2834

‎test/unit/specs/directives/model_spec.js

Copy file name to clipboardExpand all lines: test/unit/specs/directives/model_spec.js
+56Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,34 @@ if (_.inBrowser) {
8080
expect(vm.test).toBe('a')
8181
})
8282

83+
it('radio expression', function (done) {
84+
var vm = new Vue({
85+
el: el,
86+
data: {
87+
test: false,
88+
test2: 'string1',
89+
expression1: 'string1',
90+
expression2: 'string2'
91+
},
92+
template:
93+
'<input type="radio" value="1" v-model="test" name="test" exp="true">' +
94+
'<input type="radio" value="0" v-model="test" name="test" exp="false">' +
95+
'<input type="radio" value="1" v-model="test2" name="test2" exp="expression1">' +
96+
'<input type="radio" value="0" v-model="test2" name="test2" exp="expression2">'
97+
})
98+
expect(el.childNodes[0].checked).toBe(false)
99+
expect(el.childNodes[1].checked).toBe(true)
100+
expect(el.childNodes[2].checked).toBe(true)
101+
expect(el.childNodes[3].checked).toBe(false)
102+
_.nextTick(function () {
103+
el.childNodes[0].click()
104+
expect(vm.test).toBe(true)
105+
el.childNodes[3].click()
106+
expect(vm.test2).toBe('string2')
107+
done()
108+
})
109+
})
110+
83111
it('checkbox', function (done) {
84112
var vm = new Vue({
85113
el: el,
@@ -113,6 +141,34 @@ if (_.inBrowser) {
113141
expect(vm.test).toBe(true)
114142
})
115143

144+
it('checkbox expression', function (done) {
145+
var vm = new Vue({
146+
el: el,
147+
data: {
148+
test: '',
149+
expression1: 'aTrueValue',
150+
expression2: 'aFalseValue'
151+
},
152+
template: '<input type="checkbox" v-model="test" true-exp="expression1" false-exp="expression2">'
153+
})
154+
expect(vm.test).toBe('')
155+
el.firstChild.click()
156+
expect(vm.test).toBe('aTrueValue')
157+
expect(el.firstChild.checked).toBe(true)
158+
el.firstChild.click()
159+
expect(vm.test).toBe('aFalseValue')
160+
expect(el.firstChild.checked).toBe(false)
161+
vm.test = 'aTrueValue'
162+
_.nextTick(function () {
163+
// the updated value of 'test' is not being passed
164+
// into the 'update' method of v-model in this environment
165+
// works fine in manual test
166+
// expect(el.firstChild.checked).toBe(true)
167+
done()
168+
})
169+
170+
})
171+
116172
it('select', function (done) {
117173
var vm = new Vue({
118174
el: el,

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.