I am using vue for data binding. I want to create a widget for access level control so I need allow, deny, and indeterminate states.
This markup is good but there is no indeterminate state:
<div class="row" v-for='a in context.This.Actions'>
<div class="col-96">
<input class="custom-control-input access-checkbox" v-bind:id="'chk_'+a.Name" v-bind:value="a.Id" v-model="context.This.RoleActions" indeterminate="true" type="checkbox" />
<label class="pointer" v-bind:for="'chk_'+a.Name">{{ a.Name }}</label>
</div>
</div>
The variables are :
context.This.Actions = [
{ "Id": "id_1",
"Name": "AAA"
},
{ "Id": "id_2",
"Name": "BBB"
},
{ "Id": "id_3",
"Name": "CCC"
}
]
context.This.RoleActions = [ "id_1", "id_2" ]
I want this change:
context.This.RoleActions = [ {"id_1":true}, {"id_2":false} ]
and I expect the below result:
The first checkbox: checked
The second checkbox: unchecked
The other one: indeterminate
A checkbox cannot be set to indeterminate state by an HTML attribute - it must be set by a JavaScript. This state can be used to force the user to check or uncheck the checkbox.
prop('checked'); which will return true if checkbox is checked or not.
Indeterminate is a DOM property on a checkbox, which means putting it in the markup won't have an effect, it needs to be applied programmatically.
Even after doing that, keep in mind the state of a checkbox is still either checked or not checked. This is important to keep in mind when processing the form. The difference is visual only. (source)
With those caveats in mind, in Vue 2 you can add an indeterminate property to a checkbox like so:
<input type="checkbox" indeterminate.prop="true">
or bind to a dynamic value in your component:
<input type="checkbox" :indeterminate.prop="dataProperty">
I would recommend refactoring with this in mind.
I had a similar issue using props with checkbox to support 2 and 3 states . to handle this I used computed property with getter and setter using Vuetify checkbox
Here is my example
<template>
<v-container class="checkbox-container">
<v-checkbox
type="checkbox"
:indeterminate="indeterminate"
:color="indeterminate ? '#767575' : 'success'"
v-model="internalState"
@click.stop="onCheckbox"
@keyup.space.prevent="onCheckbox"
></v-checkbox>
</v-container>
</template>
<script>
/**
* Responsability: boolean field editor checkbox
* When @threeState is true : following states (check, uncheck, indeterminate) otherwise (check, uncheck)
* @checkboxState is an external state where it contains always the current state of checkbox
**/
export default {
model: {
// v-model prop
prop: 'checkboxState',
},
props: {
threeState: Boolean,
/**
* Init state is the starting state Which the chekbox starts from.
* by defining initstate it will ignore the default input @boolProperty
**/
initState: {
type: String,
default: 'false',
},
// Reperesent the value of checked state in model
config: {
type: Object,
default: () => ({
checked: 'true',
unchecked: 'false',
indeterminate: null,
}),
},
checkboxState: {
type: String,
},
},
data() {
return {
internalState: this.checkboxState,
indeterminate: false,
}
},
computed: {
state: {
get() {
return this.checkboxState
},
set(newState) {
this.changeCheckboxState(newState)
},
},
},
// Change the state of checkbox after DOM is mounted
mounted() {
this.changeCheckboxState(this.initState)
},
methods: {
changeCheckboxState(state) {
this.$vnode.data.model.callback(state)
this.internalState = state === this.config.checked
this.indeterminate = state === this.config.indeterminate
},
onCheckbox() {
if (this.threeState) {
switch (this.state) {
case this.config.unchecked:
this.state = this.config.checked
break
case this.config.checked:
this.state = this.config.indeterminate
break
case this.config.indeterminate:
this.state = this.config.unchecked
break
}
} else {
this.state = (!(this.state === this.config.checked)).toString()
}
},
},
}
</script>
<style lang="scss" scoped>
.checkbox-container {
width: 50px;
}
</style>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With