Skip to content

Commit

Permalink
feat(MdCheckBox): True / false value supporting (#1703)
Browse files Browse the repository at this point in the history
* feat(MdCheckBox): True / false value supporting

support true-value and false-value for checkboxes

BREAKING CHANGE: checkbox without setting value is true / false as default

fix #1701

* fix(MdCheckbox): better native value binding
  • Loading branch information
VdustR authored and marcosmoura committed May 13, 2018
1 parent a4e3619 commit 7cdcb66
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 20 deletions.
2 changes: 2 additions & 0 deletions docs/app/pages/Components/Checkbox/Checkbox.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<example src="./examples/RegularCheckboxes.vue" />
<example src="./examples/CheckboxHueColors.vue" />
<example src="./examples/TrueFalseValue.vue" />

<template>
<page-container centered :title="$t('pages.checkbox.title')">
Expand All @@ -12,6 +13,7 @@

<code-example title="Checkbox" :component="examples['regular-checkboxes']" />
<code-example title="Hue Colors" :component="examples['checkbox-hue-colors']" />
<code-example title="True / False Value" :component="examples['true-false-value']" />

<api-item title="API - md-checkbox">
<p>The following options can be applied to all checkboxes:</p>
Expand Down
57 changes: 57 additions & 0 deletions docs/app/pages/Components/Checkbox/examples/TrueFalseValue.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<template>
<div>
<div class="block">
<div class="title">Without <code>:true-value</code> / <code>:false-value</code></div>
<div class="input">
<md-checkbox v-model="withoutSetValue">{{withoutSetValue|jsonStringify}}</md-checkbox>
</div>
</div>

<md-divider />

<div class="block">
<div class="title">With <code>:true-value</code> / <code>:false-value</code></div>
<div class="input">
<md-checkbox v-model="withSetValue" true-value="true" false-value="false">{{withSetValue|jsonStringify}}</md-checkbox>
</div>
</div>

<md-divider />

<div class="block">
<div class="title">Native checkbox with <code>:true-value</code> / <code>:false-value</code></div>
<div class="input">
<label><input type="checkbox" v-model="native" true-value="true" false-value="false" value="test" />{{native|jsonStringify}}</label>
</div>
</div>
</div>
</template>

<script>
export default {
name: 'TrueFalseValue',
data () {
return {
withoutSetValue: null,
withSetValue: null,
native: null
}
},
filters: {
jsonStringify (val) {
return JSON.stringify(val)
}
}
}
</script>

<style lang="scss">
.block:not(:first-child) {
margin-top: 32px;
}
.title {
font: 1.2em;
}
</style>
2 changes: 1 addition & 1 deletion src/components/MdCheckbox/MdCheckbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="md-checkbox" :class="[$mdActiveTheme, checkClasses]">
<div class="md-checkbox-container" @click.stop="toggleCheck">
<md-ripple md-centered :md-active.sync="rippleActive" :md-disabled="disabled">
<input type="checkbox" v-bind="{ id, name, disabled, required, value }" :indeterminate.prop="indeterminate">
<input type="checkbox" v-bind="attrs" :indeterminate.prop="indeterminate">
</md-ripple>
</div>

Expand Down
57 changes: 38 additions & 19 deletions src/components/MdCheckbox/MdCheckboxMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ export default {
model: [String, Boolean, Object, Number, Array],
value: {
type: [String, Boolean, Object, Number],
default: 'on'
},
name: [String, Number],
required: Boolean,
disabled: Boolean,
indeterminate: Boolean
indeterminate: Boolean,
trueValue: {
default: true
},
falseValue: {
default: false
}
},
model: {
prop: 'model',
Expand All @@ -23,30 +28,48 @@ export default {
rippleActive: false
}),
computed: {
attrs () {
const attrs = {
id: this.id,
name: this.name,
disabled: this.disabled,
required: this.required,
'true-value': this.trueValue,
'false-value': this.falseValue
}

if (this.$options.propsData.hasOwnProperty('value')) {
if (this.value === null || typeof this.value !== 'object') {
attrs.value = (this.value === null || this.value === undefined) ? '' : String(this.value)
}
}

return attrs
},
isSelected () {
if (this.isModelArray) {
return this.model.includes(this.value)
}

if (this.isModelBoolean && this.value === 'on') {
return this.model
if (this.hasValue) {
return this.model === this.value
}

return this.model === this.value
return this.model === this.trueValue
},
isModelArray () {
return Array.isArray(this.model)
},
isModelBoolean () {
return typeof this.model === 'boolean'
},
checkClasses () {
return {
'md-checked': this.isSelected,
'md-disabled': this.disabled,
'md-required': this.required,
'md-indeterminate': this.indeterminate
}
},
hasValue () {
return this.$options.propsData.hasOwnProperty('value')
}
},
methods: {
Expand All @@ -68,26 +91,22 @@ export default {

this.$emit('change', newModel)
},
handleStringCheckbox () {
if (!this.isSelected) {
this.$emit('change', this.value)
} else {
this.$emit('change', null)
}
handleSingleSelectCheckbox () {
this.$emit('change', this.isSelected ? null : this.value)
},
handleBooleanCheckbox () {
this.$emit('change', !this.model)
handleSimpleCheckbox () {
this.$emit('change', this.isSelected ? this.falseValue : this.trueValue)
},
toggleCheck () {
if (!this.disabled) {
this.rippleActive = true

if (this.isModelArray) {
this.handleArrayCheckbox()
} else if (this.isModelBoolean) {
this.handleBooleanCheckbox()
} else if (this.hasValue) {
this.handleSingleSelectCheckbox()
} else {
this.handleStringCheckbox()
this.handleSimpleCheckbox()
}
}
}
Expand Down

0 comments on commit 7cdcb66

Please sign in to comment.