Vue can't check the recently unchecked, checkbox even its binding - javascript

I have a list of checkboxes, I want when I click on input 4th all previous boxes being checked and the rest unchecked.
I almost did it, but there is an issue that when I back to the those checked boxes and uncheck one of them, its still okay and the next being unchecked, but when again going forward and check another one from those unchecked the recently unchecked item being still unchecked and not changed.
here is the demo, and I think the GIF will describe my issue better.
Demo https://jsfiddle.net/j5dpkut8/1/
<script src="https://unpkg.com/vue"></script>
<div id="app">
<input type="checkbox" v-model="checked[0]" value="0" #change="printState(0)"> checked 0 <br>
<input type="checkbox" v-model="checked[1]" value="1" #change="printState(1)"> checked 1 <br>
<input type="checkbox" v-model="checked[2]" value="2" #change="printState(2)"> checked 2 <br>
<input type="checkbox" v-model="checked[3]" value="3" #change="printState(3)"> checked 3 <br>
<input type="checkbox" v-model="checked[4]" value="4" #change="printState(4)"> checked 4 <br>
<input type="checkbox" v-model="checked[5]" value="5" #change="printState(5)"> checked 5 <br>
<input type="checkbox" v-model="checked[6]" value="6" #change="printState(6)"> checked 6 <br>
<input type="checkbox" v-model="checked[7]" value="7" #change="printState(7)"> checked 7 <br>
</div>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!',
checked: [
false,false,false,false,false,false,false,false,
],
},
methods: {
printState(x) {
this.checked = [
false,
false,
false,
false,
false,
false,
false,
false,
],
for (let i = 1; i < this.checked.length; i++) {
if (i <= x) {
this.checked[i] = true;
}
}
console.log(this.checked);
},
}
})

In your code change change handler into click handler and all will be okey.
Or.
new Vue({
el: '#app',
data: {
checked: [
{ state: false },
{ state: false },
{ state: false },
{ state: false },
{ state: false },
{ state: false },
{ state: false },
{ state: false },
],
},
methods: {
printState(x) {
for (let i = 0; i < this.checked.length; i++) {
this.checked[i].state = i <= x ? true : false;
}
},
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<div v-for="(n, index) in checked" :key="index">
<input
type="checkbox"
v-model="n.state"
#click="printState(index)"
>
<span>checked {{ index }} {{ n.state }}</span>
</div>
</div>

As #TigranAbrahamyan mentioned, #click will fix it. But here is a solution in very few lines that also uses v-model and value as intended and lets you easily adjust the number of boxes.
new Vue({
el: "#app",
data: () => ({ num: 10, values: [] }),
methods: {
mark(index) {
this.values = [...Array(index).keys()];
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="index in num" :key="index-1">
<input type="checkbox" v-model="values" :value="index-1" #click="mark(index-1)" />
</div>
</div>

Related

Vue Unchecking isn't removing data from array?

I have a function that pushes the networkAudience to the array when the checkbox is checked but when I unchecked it the same network Audience get pushed into the array again. Clicking the networkAudience should be removed when I uncheck the box.
How should I change my function so that a networkAudience is removed if it's unchecked?
new Vue({
el: '#app',
data: {
networkAudience: {}
selected:[]
},
methods: {
netToggle(networkAudience)
{
if(!this.selected.includes(networkAudience))
this.selected.push(networkAudience);
else
this.selected.splice(this.selected.indexOf(networkAudience), 1);
}
}
});
<div v-for="(networkAudience, index) in networkAudiences" : key="index">
<tr>
<input
class="form-check-input"
type="checkbox"
:checked="selected.includes(networkAudience)"
#click="netToggle(networkAudience)"
>
</tr>
</div>
This should only show one object because I unchecked a box but I end up with two objects. The unchecked box duplicates.
If I understood you correctly , try like following snippet:
new Vue({
el: '#app',
data() {
return {
networkAudiences: [{id:1, name:'aaa'}, {id:2, name: 'bbb'}, {id:3, name: 'ccc'}],
networkAudience: {},
selected: []
}
},
methods: {
netToggle(networkAudience) {
if(!this.selected.includes(networkAudience)) {
this.selected.push(networkAudience);
} else {
this.selected.splice(this.selected.indexOf(networkAudience), 1);
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="(networkAudience, index) in networkAudiences" :key="index">
<div>
<label :for="networkAudience.id">{{ networkAudience.name }}</label>
<input
class="form-check-input"
type="checkbox"
:id="networkAudience.id"
:value="networkAudiences[index]"
#input="netToggle(networkAudience)"
/>
</div>
</div>
{{selected}}
</div>

Delete updated v-model checkbox property in vuejs

I have a input checkbox tag which I'm trying to delete after it has been updated in my v-model please how can I go about this.
This is my input tag:
<input
v-model="checked"
type="checkbox"
id=""
value="jackets"
>
I get the v-model value property by doing this
{{checked}}
Please how can I add a delete function to my v-model property in which if I click on the delete function the checkbox would be unchecked.
If I understood you correctly try like following snippet (just set your checked property to false):
new Vue({
el: '#demo',
data() {
return {
checked: true,
filters: [{name: 'XXL', state: false}, {name: 'Grey', state: false}]
}
},
methods: {
del() {
this.filters.forEach(f => f.state = false)
},
rem(i) {
this.filters[i].state = false
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div v-for="(filter, i) in filters" :key="i">
{{ filter.name }}
<input
v-model="filter.state"
type="checkbox"
id=""
:value="filter.name"
/>
<button #click="rem(i)">X</button>
</div>
Remove All
<input
type="checkbox"
id=""
#input="del"
/>
</div>

Vue Checkboxes - Keep selected unless another checkbox is checked

I am using checkboxes to behave like radio buttons but the one behavior that I want to fix is the ability to keep the checkbox checked until the second one is checked (which will then uncheck the first one). I don't want the ability to deselect the checkbox by clicking on it again, just to hit the "none" checkbox to deselect the one below.
Referring to the image above, the label selects the checkbox as well. Once the checkbox is selected and is tapped on again, it goes back to the none checkbox on the left. Maybe radio buttons would be better, but I like checkboxes more. Here's the code:
<label :for="'none-'+product.id"
class="none addon_label"
:class="{'addon_selected': !selected}"
>
<input class=""
type="checkbox"
:id="'none-'+product.id"
:true-value="false"
:false-value="true"
:value="false"
v-model="selected"
checked
/>
<span class="checkmark addon_checkbox"></span>
<div class="v-center">None</div>
</label>
<label :for="'product-'+product.id"
class="is_flex addon_label"
:class="{'addon_selected': selected}"
:data-product-id="product.id"
>
<div class="checkbox-container">
<input class=""
type="checkbox"
:true-value="true"
:false-value="false"
:id="'product-'+product.id"
v-model="selected"/>
<span class="checkmark addon_checkbox"></span>
To do this, you just need to have two v-models, one for each button, and to create a function that when one of the two buttons changes, each of the values takes its opposite value.
Then, in order to avoid deselection by clicking on its own button, you use :disabled= with the reference of your button
Vue.js 3 with Composition
<script setup lang="ts">
import { ref } from "vue";
let selectedNone = ref(true);
let selectedChoice = ref(false);
function selectOption() {
selectedNone.value = !selectedNone;
selectedChoice.value = !selectedChoice;
}
</script>
<template>
<label>
<input
type="checkbox"
:value="false"
v-model="selectedNone"
:disabled="selectedNone"
#click="selectOption"
/>
<span>None</span>
</label>
<label >
<input
type="checkbox"
v-model="selectedChoice"
:disabled="selectedChoice"
#click="selectOption"
/>
<span>Choice</span>
</label>
</template>
You can use watch to check if the value of the checkbox has changed, and then either select all or deselect all, based on that.
Here's a quick demo
Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: () => {
return {
options: {
check1: null,
check2: null,
check3: null,
},
check1: null,
check2: null,
check3: null,
deselect: null,
};
},
watch: {
deselect(isDeselected) {
if (isDeselected) {
this.options.check1 = false;
this.options.check2 = false;
this.options.check3 = false;
}
},
options() {
console.log("Change");
},
...["options.check1", "options.check2", "options.check3"].reduce(function (
acc,
currentKey
) {
acc[currentKey] = function (newValue) {
if (newValue) this.deselect = false;
};
return acc;
},
{}),
},
})
<script src="https://unpkg.com/vue#2.x/dist/vue.js"></script>
<div id="app">
<label for="check1">Check 1</label>
<input type="checkbox" v-model="options.check1" id="check1" />
<br />
<label for="check2">Check 2</label>
<input type="checkbox" v-model="options.check2" id="check2" />
<br />
<label for="check3">Check 3</label>
<input type="checkbox" v-model="options.check3" id="check3" />
<br />
<label for="deselect-check">Deselect All</label>
<input type="checkbox" v-model="deselect" id="deselect-check" />
</div>

make the checkbox single choice

I want to apply this code on vuejs
I replaced onclick by #click but it doesn't work!
ps: I'm beginner on vuejs
function onlyOne(checkbox) {
var checkboxes = document.getElementsByName('check')
checkboxes.forEach((item) => {
if (item !== checkbox) item.checked = false
})
}
<input type="checkbox" name="check" onclick="onlyOne(this)">
<input type="checkbox" name="check" onclick="onlyOne(this)">
<input type="checkbox" name="check" onclick="onlyOne(this)">
<input type="checkbox" name="check" onclick="onlyOne(this)">
A basic approach to the question you stated:
new Vue({
el: "#app",
data() {
return {
checkboxes: [{
checked: false
},
{
checked: false
},
{
checked: false
},
{
checked: false
},
]
}
},
methods: {
onChange(cb) {
this.checkboxes = this.checkboxes.map(checkbox => ({ checked: cb == checkbox }))
},
},
template: `
<div>
<div
v-for="(checkbox, i) in checkboxes"
:key="i"
>
<input
type="checkbox"
:checked="checkbox.checked"
#change="() => onChange(checkbox)"
/>
{{ checkbox.checked }}
</div>
</div>
`
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>

Check-all stops working when I add v-model attribute to the checkboxes

Check-all feature stops working when I try to get value of each checkbox in an array using v-model. I read lot of questions on different portals including stackoverflow, people are saying that v-model doesn't work with :checked attribute which I understand but could not find a solution / alternate code to make it work.
The 1st code that I tried was to select all checkboxes using the 1st checkbox. This works well. Code below:
new Vue({
el: "#app",
data: {
selectAll:false
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<label>
<input type="checkbox" v-model="selectAll">
Select all
</label>
<br>
<label>
<input type="checkbox" :checked="selectAll" value="Item 1">
Item 1
</label>
<br>
<label>
<input type="checkbox" :checked="selectAll" value="Item 2">
Item 2
</label>
<br>
<label>
<input type="checkbox" :checked="selectAll" value="Item 3">
Item 3
</label>
</div>
The 2nd code that I tried was to get value of each checkbox in an array but in this case 'select all' automatically stops working. Code below:
new Vue({
el: "#app",
data: {
selectAll:false,
eachCheckbox: [],
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<label>
<input type="checkbox" v-model="selectAll">
Select all
</label>
<br>
<label>
<input type="checkbox" :checked="selectAll" value="Item 1" v-model="eachCheckbox">
Item 1
</label>
<br>
<label>
<input type="checkbox" :checked="selectAll" value="Item 2" v-model="eachCheckbox">
Item 2
</label>
<br>
<label>
<input type="checkbox" :checked="selectAll" value="Item 3" v-model="eachCheckbox">
Item 3
</label>
<br>
Selected checkbox values: {{eachCheckbox}}
</div>
I don't know how to make this work. Can someone help please?
Use Vue.set to create objects in the checkbox array once an API call completes.
This shows a simulated async api call which takes 2.5 seconds to complete.
new Vue({
el: '#app',
data () {
return {
loading: false,
checkall: false,
checkboxes: []
}
},
methods: {
toggleAll () {
this.checkall = !this.checkall
this.checkboxes.forEach(c => {
c.checked = this.checkall
})
}
},
watch: {
checkboxes: {
deep: true,
handler: function () {
this.checkall = this.checkboxes.every(c => c.checked)
}
}
},
mounted () {
// simulate an async api call which takes 2.5 seconds to complete
this.loading = true
setTimeout(() => {
Array.from(Array(3), (c, i) => ({ checked: false, text: `Option ${i + 1}` })).forEach((c, i) => {
Vue.set(this.checkboxes, i, c)
})
this.loading = false
}, 2500)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input type="checkbox" #click="toggleAll" v-model="checkall"/> Check All<br/>
<div v-for="(c, i) in checkboxes" :key="i">
<input type="checkbox" v-model="c.checked"/>{{ c.text }}<br/>
</div>
<p v-if="!loading">Checked: {{ checkboxes.filter(c => c.checked).map(c => c.text).join(',') }}</p>
<p v-else>Fetching data...</p>
</div>
i had faced the same problem before and i didn't find a good solution, but i had tried something like the following :
new Vue({
el: "#app",
data: {
selectAll: false,
eachCheckbox: [],
},
methods: {
selectAllItems() {
this.selectAll ? this.eachCheckbox = ["Item 1", "Item 2", "Item 3"] : this.eachCheckbox = [];
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<label>
<input type="checkbox" v-model="selectAll" #change="selectAllItems">
Select all
</label>
<br>
<label>
<input type="checkbox" :checked="selectAll" value="Item 1" v-model="eachCheckbox">
Item 1
</label>
<br>
<label>
<input type="checkbox" :checked="selectAll" value="Item 2" v-model="eachCheckbox">
Item 2
</label>
<br>
<label>
<input type="checkbox" :checked="selectAll" value="Item 3" v-model="eachCheckbox">
Item 3
</label>
<br> Selected checkbox values: {{eachCheckbox}}
</div>

Categories