Commit 96f71eda authored by qingwei.li's avatar qingwei.li

Radio/Checkbox: fix radio-radiogroup checkbox-checkboxgroup nested bug fixed #1152

parent 6cd01c26
...@@ -16,7 +16,12 @@ ...@@ -16,7 +16,12 @@
value(value) { value(value) {
this.$emit('change', value); this.$emit('change', value);
this.dispatch('form-item', 'el.form.change', [value]); this.dispatch('form-item', 'el.form.change', [value]);
this.broadcast('ElCheckbox', 'initData', [value]);
} }
},
mounted() {
this.broadcast('ElCheckbox', 'initData', [this.value]);
} }
}; };
</script> </script>
......
...@@ -17,11 +17,9 @@ ...@@ -17,11 +17,9 @@
:disabled="disabled" :disabled="disabled"
:true-value="trueLabel" :true-value="trueLabel"
:false-value="falseLabel" :false-value="falseLabel"
v-model="_value" v-model="model"
@focus="focus = true" @focus="focus = true"
@blur="focus = false" @blur="focus = false">
@change="handleChange"
ref="checkbox">
<input <input
v-else v-else
class="el-checkbox__original" class="el-checkbox__original"
...@@ -29,10 +27,9 @@ ...@@ -29,10 +27,9 @@
:disabled="disabled" :disabled="disabled"
:value="label" :value="label"
:name="name" :name="name"
v-model="_value" v-model="model"
@focus="focus = true" @focus="focus = true"
@blur="focus = false" @blur="focus = false">
@change="handleChange">
</span> </span>
<span class="el-checkbox__label" v-if="$slots.default || label"> <span class="el-checkbox__label" v-if="$slots.default || label">
<slot></slot> <slot></slot>
...@@ -48,70 +45,69 @@ ...@@ -48,70 +45,69 @@
mixins: [Emitter], mixins: [Emitter],
props: { componentName: 'ElCheckbox',
value: {},
label: String,
indeterminate: Boolean,
disabled: Boolean,
checked: Boolean,
name: String,
trueLabel: [String, Number],
falseLabel: [String, Number]
},
computed: { computed: {
_value: { model: {
get() { get() {
return !this.wrapInGroup ? this.value : this.$parent.value; return this.isGroup ? this.store : this.value;
}, },
set(newValue) {
if (!this.wrapInGroup) { set(val) {
this.$emit('input', newValue); if (this.isGroup) {
this.dispatch('ElCheckboxGroup', 'input', [val]);
} else { } else {
this.$parent.$emit('input', newValue); this.$emit('input', val);
} }
} }
}, },
isChecked() {
var type = Object.prototype.toString.call(this._value);
if (type === '[object Boolean]') { isChecked() {
return this._value; if ({}.toString.call(this.model) === '[object Boolean]') {
} else if (type === '[object Array]') { return this.model;
return this._value.indexOf(this.label) > -1; } else if (Array.isArray(this.model)) {
} else if (type === '[object String]' || type === '[object Number]') { return this.model.indexOf(this.label) > -1;
return this._value === this.trueLabel; } else if (this.model !== null && this.model !== undefined) {
return this.model === this.trueLabel;
} }
} }
}, },
props: {
value: {},
label: String,
indeterminate: Boolean,
disabled: Boolean,
checked: Boolean,
name: String,
trueLabel: [String, Number],
falseLabel: [String, Number]
},
data() { data() {
return { return {
focus: false, store: [],
wrapInGroup: this.$parent.$options.componentName === 'ElCheckboxGroup' isGroup: false
}; };
}, },
watch: { methods: {
checked: { addToStore() {
immediate: true, if (Array.isArray(this.model)) {
handler(value) { this.model.indexOf(this.label) === -1 && this.model.push(this.label);
if (value) { } else {
let type = Object.prototype.toString.call(this._value); this.model = this.trueLabel || true;
if (type !== '[object Array]') {
this._value = this.trueLabel || true;
} else {
this._value.push(this.label);
}
}
} }
} }
}, },
methods: { created() {
handleChange(ev) { this.checked && this.addToStore();
this.$emit('change', ev); this.$on('initData', data => {
} this.store = data;
this.isGroup = true;
this.checked && this.addToStore();
});
} }
}; };
</script> </script>
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
export default { export default {
name: 'ElRadioGroup', name: 'ElRadioGroup',
componentName: 'radio-group', componentName: 'ElRadioGroup',
mixins: [Emitter], mixins: [Emitter],
...@@ -15,8 +15,12 @@ ...@@ -15,8 +15,12 @@
watch: { watch: {
value(value) { value(value) {
this.$emit('change', value); this.$emit('change', value);
this.broadcast('ElRadio', 'initData', value);
this.dispatch('form-item', 'el.form.change', [this.value]); this.dispatch('form-item', 'el.form.change', [this.value]);
} }
},
mounted() {
this.broadcast('ElRadio', 'initData', this.value);
} }
}; };
</script> </script>
......
...@@ -4,14 +4,14 @@ ...@@ -4,14 +4,14 @@
<span class="el-radio__inner" <span class="el-radio__inner"
:class="{ :class="{
'is-disabled': disabled, 'is-disabled': disabled,
'is-checked': _value === label, 'is-checked': store === label,
'is-focus': focus 'is-focus': focus
}"></span> }"></span>
<input <input
class="el-radio__original" class="el-radio__original"
:value="label" :value="label"
type="radio" type="radio"
v-model="_value" v-model="store"
@focus="focus = true" @focus="focus = true"
@blur="focus = false" @blur="focus = false"
:name="name" :name="name"
...@@ -24,9 +24,15 @@ ...@@ -24,9 +24,15 @@
</label> </label>
</template> </template>
<script> <script>
import Emitter from 'element-ui/src/mixins/emitter';
export default { export default {
name: 'ElRadio', name: 'ElRadio',
mixins: [Emitter],
componentName: 'ElRadio',
props: { props: {
value: [String, Number], value: [String, Number],
label: { label: {
...@@ -36,24 +42,34 @@ ...@@ -36,24 +42,34 @@
disabled: Boolean, disabled: Boolean,
name: String name: String
}, },
data() { data() {
return { return {
focus: false focus: false,
isGroup: false,
store: this.value
}; };
}, },
computed: {
_value: { watch: {
get() { store(store) {
return this.value !== undefined ? this.value : this.$parent.value; if (this.isGroup) {
}, this.dispatch('ElRadioGroup', 'input', store);
set(newValue) { } else {
if (this.value !== undefined) { this.$emit('input', store);
this.$emit('input', newValue);
} else {
this.$parent.$emit('input', newValue);
}
} }
},
value(val) {
this.store = val;
} }
},
created() {
this.$on('initData', data => {
this.store = data;
this.isGroup = true;
});
} }
}; };
</script> </script>
...@@ -5,7 +5,7 @@ function broadcast(componentName, eventName, params) { ...@@ -5,7 +5,7 @@ function broadcast(componentName, eventName, params) {
if (name === componentName) { if (name === componentName) {
child.$emit.apply(child, [eventName].concat(params)); child.$emit.apply(child, [eventName].concat(params));
} else { } else {
broadcast.apply(child, [componentName, eventName].concat(params)); broadcast.apply(child, [componentName, eventName].concat([params]));
} }
}); });
} }
......
...@@ -67,6 +67,33 @@ describe('Checkbox', () => { ...@@ -67,6 +67,33 @@ describe('Checkbox', () => {
done(); done();
}); });
}); });
it('nested group', done => {
vm = createVue({
template: `
<el-checkbox-group v-model="checkList">
<el-row>
<el-checkbox label="a" ref="a"></el-checkbox>
<el-checkbox label="b" ref="b"></el-checkbox>
<el-checkbox label="c" ref="c"></el-checkbox>
<el-checkbox label="d" ref="d"></el-checkbox>
</el-row>
</el-checkbox-group>
`,
data() {
return {
checkList: []
};
}
}, true);
expect(vm.checkList.length === 0).to.be.true;
vm.$refs.a.$el.click();
vm.$nextTick(_ => {
expect(vm.checkList.indexOf('a') !== -1).to.be.true;
done();
});
});
it('true false label', done => { it('true false label', done => {
vm = createVue({ vm = createVue({
template: ` template: `
......
...@@ -65,14 +65,16 @@ describe('Radio', () => { ...@@ -65,14 +65,16 @@ describe('Radio', () => {
}; };
} }
}, true); }, true);
expect(vm.$refs.radio1.$el.querySelector('.is-checked')).to.be.ok; setTimeout(_ => {
let radioElm = vm.$refs.radio2.$el; expect(vm.$refs.radio1.$el.querySelector('.is-checked')).to.be.ok;
radioElm.click(); let radioElm = vm.$refs.radio2.$el;
vm.$nextTick(_ => { radioElm.click();
expect(radioElm.querySelector('.is-checked')).to.be.ok; vm.$nextTick(_ => {
expect(vm.radio === 6).to.be.true; expect(radioElm.querySelector('.is-checked')).to.be.ok;
done(); expect(vm.radio === 6).to.be.true;
}); done();
});
}, 50);
}); });
it('radio button', done => { it('radio button', done => {
vm = createVue({ vm = createVue({
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment