I'm having trouble binding radiobuttons to boolean values in model.
In this example: https://jsfiddle.net/krillko/npv1snzv/2/
On load, the radio radio button is not checked, and when I try to change them, the 'primary' value in model is becomes empty.
I've tried:
:checked="variation.primary == true"
but with no effect.
To bind radio buttons to boolean values instead of string values in Vue, use v-bind on the value attribute:
<input type="radio" v-model="my-model" v-bind:value="true">
<input type="radio" v-model="my-model" v-bind:value="false">
I'll leave it to you to figure out how to match these values with your backend data.
Checkboxes are not so good for this scenario; the user could leave them both blank, and you don't get your answer. If you are asking a yes/no or true/false question where you want only one answer, then you should be using radio buttons instead of checkboxes.
What you are looking for is a checkbox. Here is an updated jsfiddle.
Your use case is not how radio buttons are supposed to work.
Look at this example.
new Vue({
el: '#app',
data: {
picked: 'One',
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.js"></script>
<div id="app">
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<br><br>
<span>Picked: {{ picked }}</span>
</div>
I ran into this myself too, the thing to remember is that the value attribute actually shouldn't change for the radio button, what changes (and what you need to bind to) is the checked attribute.
And then you need to handle the change event to set the correct item's value in your data.
Based on your jsFiddle, I think this is what you're looking for:
<div id="l-main">
<div v-for="(variation, key) in variations">
<label>
{{ variation.name }}
<input
type="radio"
name="Test"
:value="key"
:checked="variation.primary"
#change="onChange"
/>
</label>
</div>
<br>Output:<br>
<div v-for="(variation, key) in variations">
{{ variation.name }} {{ variation.primary }}
</div>
</div>
var vm = new Vue({
el: '#l-main',
data: {
variations: {
'41783' : {
'name': 'test1',
'primary': false
},
'41785' : {
'name': 'test2',
'primary': true
}
}
},
methods: {
onChange($event) {
// the primary variation is the one whose key
// matches the value of the radio button that got checked
for (const key in this.variations) {
this.variations[key].primary = key === $event.target.value;
}
}
}
});
Related
I have this checkbox
<div class="form-check form-check-inline col-lg-2">
<input v-model="propertyData.fitness_centre" type="checkbox" class="form-check-input" id="dc_li_u" />
<label class="form-check-label" for="dc_li_u">Fitness Centre</label>
</div>
and i am saving the state in a database so when editing the state is restored and displays whether the checkbox was checked or not.
However, i need the checkbox to have a string value that is saved to the database when the checkbox is clicked such that when a checkbox has a string value, its checked and when the string value is empty the checkbox is not checked.
I have many checkboxes and so, i wanted the entire logic to be contained inside the checkbox. How can i modify the checkbox to do this?
You can use true-value and false-value attributes, to assign specific values when checking/unchecking.
new Vue({
el: "#app",
data: {
fitness_centre: "true value"
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="form-check form-check-inline col-lg-2">
<input v-model="fitness_centre" true-value="true value" false-value="" type="checkbox" class="form-check-input" id="dc_li_u" />
<label class="form-check-label" for="dc_li_u">Fitness Centre</label>
<div>Value: {{ fitness_centre }}</div>
</div>
</div>
You could use a change-event handler to set propertyData.fitness_centre to the desired value based on the checked state. Also bind <input>.checked to propertyData.fitness_centre so that the checked state is bound to the model's truthiness (empty string is false, otherwise true).
<template>
<input type="checkbox"
#change="onChange"
:checked="propertyData.fitness_centre"
value="fitness_centre">
</template>
<script>
export default {
data() {
return {
propertyData: { fitness_centre: '' }
}
},
methods: {
onChange(e) {
this.propertyData.fitness_centre = e.target.checked ? e.target.value : ''
}
}
}
</script>
demo
I have a two page form so I am trying to mix submitting data to the server as well as making use of vuex. So on page one, I have a simple form which contains a group of checkboxes (removed layout and styling to reduce code)
<b-form #submit.stop.prevent="onSubmit">
<b-form-group>
<input v-model="$v.form.checkboxGroup.$model" type="checkbox" name="checkbox1" value="1">
<input v-model="$v.form.checkboxGroup.$model" type="checkbox" name="checkbox2" value="2">
<input v-model="$v.form.checkboxGroup.$model" type="checkbox" name="checkbox3" value="3">
</b-form-group>
<button class="btn try-btn" type="submit">Submit</button>
</b-form>
Essentially, when submitted, I send the form data to my repository so it can be saved on the backend. If this is successful, I call the following method
handleSubmitSuccess (response) {
if (response.data.action === 'next_step') {
this.$store.dispatch('createCheckboxData', this.$v.form.$model)
return
}
}
This method sets the checkbox data in my store and routes the user to the next page (removed this part). So all of this is fine, seems to work well.
So when on page two, I have a button that can take you back to page one. My idea is that if this happens, I use the previously checked data in the store to auto check the previously selected checkbox. As such, on page one I added a computed method
computed: {
checkboxData () {
return this.$store.getters.checkboxData
}
}
Now if I output checkboxData to the console, it seems to be an Observer object
[{…}, __ob__: Observer]
0:
checkboxData: Array(2)
0: "1"
1: "3"
length: 2
So the above shows that previously, the first and second checkboxes were checked.
My question is how can I now use this data to auto-check my checkboxes. I have seen some examples online, but they do not seem to work.
Thanks
The way you use Vue is a little different to me so you might have to change this but, basically, you can set your v-model to whatever array is set in the Vuex store and it will set those checkboxes to true:
new Vue({
el: "#app",
data: {
checkbox: [],
vuexData: ['1', '3']
},
mounted() {
this.checkbox = this.vuexData;
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input v-model="checkbox" type="checkbox" name="checkbox1" value="1">
<input v-model="checkbox" type="checkbox" name="checkbox2" value="2">
<input v-model="checkbox" type="checkbox" name="checkbox3" value="3">
{{ checkbox }}
</div>
I want to make multiple 'in-place' editable date fields in table rows.
An example for a single field below works.
I show the currentdate (oldDate) as a label. User clicks on 'Change', an input field appears, after editing the user can Accept or Cancel.
https://jsfiddle.net/asrajan55/qv6crg84/
<div id="root">
<label>Test Date:</label>
<span v-show="!makeEditable"> {{ oldDate }} </span>
<span v-show = "makeEditable">
<input type="date" v-model="newDate" required=""/>
<button #click="acceptClicked">Accept</button>
<button name="cancel" #click="makeEditable=false">Cancel</button>
</span>
<button v-show="!makeEditable" #click="makeEditable=true" >Change</button>
</div>
new Vue({
el: "#root",
data: {
oldDate: '2019-02-04',
newDate: '2019-02-04',
makeEditable: false,
},
methods: {
acceptClicked(){
if (this.newDate!='') {
this.oldDate=this.newDate;
this.makeEditable=false;
}
}
}
});
However if I try multiple(2) fields the click event fires (sometimes) but nothing seems to happen. No errors in console. Also the Vue debugger in the browser does not immediately update the changed fields. Please help. I am desperate and pulling my hair out!
https://jsfiddle.net/asrajan55/9uhkr4w0/3/
<div id="root">
<div v-for="(item,index) in oldDates">
<label for="">Test Date:</label>
<span v-show="!editables[index]">{{item}}</span>
<input v-show="editables[index]" type="date" v-model="oldDates[index]"/>
<button v-show="editables[index]">Accept</button>
<button v-show="editables[index]" #click="editables[index]=false">Cancel</button>
<button v-show="!editables[index]" #click="makeEditable(index)">Change</button>
<hr />
</div>
</div>
new Vue({
el: "#root",
data: {
oldDates: ['2019-01-04', '2019-02-04'],
newDates: ['2019-01-04', '2019-02-04'],
editables: [false, false]
},
methods: {
makeEditable(index) {
alert(index);
this.editables[index] = true;
}
}
});
The problem was that you were mutating the array in place,
creating a new array reference and passing it would solve the issue
fixed here : https://jsfiddle.net/e3L2zcna/
makeEditable(index) {
this.editables = this.editables.map((val,i) => i===index || val);
}
Try using this.$set(this.editables, index, true);
Vue can't detect changes to arrays if you directly access an element using []. Read about it here:
https://vuejs.org/2016/02/06/common-gotchas/#Why-isn%E2%80%99t-the-DOM-updating
When the page loads, the radio buttton status should be checked status need, after that on change radio button, bellow div should be hide and show. I wrote the bellow code but it is not working:
html
----
<div id="demo">
<input type="radio" value="male" v-model="male" v-bind:checked="checked" />
<input type="radio" value="male" v-model="male" v-bind:checked="unchecked" />
</div>
javascript
---------
new Vue({
el: '#demo',
data: {
checked: true
},
methods:{
onChange:function(){
checked=false;
}
}
})
Apparently, Vue will check input if bound value is the same with input value:
Check out this fiddle: https://jsfiddle.net/v7zj4c13/188/
<input type="radio" name="gender" value="female" v-model="gender"/>
<input type="radio" name="gender" value="male" v-model="gender"/>
new Vue({
el: '#demo',
data: {
gender: "female"
}
})
Code above will checked the female input, not the male one
Now we have to choose between 2 conditions. So we should use input radio group.
<b-form-radio-group v-model="gender">
<input type="radio" value="female"/>
<input type="radio" value="male"/>
</b-form-radio-group>
And you can set "female" or "male" as variable "gender" initial value.
data() {
return {
...
gender: 'female',
...
}
}
If you use radio button as individual element, not as group element.
Its v-model variable has to be unique, also we can set as default checked option like this.
<input type="radio" value="female" v-model="gender"/>
<input type="radio" value="1" v-model="isOnline"/>
data() {
return {
...
gender: 'female',
isOnline: 0,
...
}
}
In the context of what you provided in the html input value as male appearing twice makes no sense because vue.js model entirely depends on the input value to determine the v-model value in the data method under the script section, it's rather you can add female in one of the input fields if your intention is to switch between male and female, you also don't need v-bind:checked="checked" as vue.js determines the default selected radio item from the v-model(gender) you will specify in data function that will be returned, the below is the change you can make in the input radio fields,
<div id="demo">
<input type="radio" value="male" v-model="gender"/>
<input type="radio" value="female" v-model="gender" />
</div>
Lastly, you can add the below in the data function in the script section,
new Vue({
el: '#demo',
data: function(){
return {
gender: "female"
}
}
})
and above functional data option is the best practice other than
new Vue({
el: '#demo',`enter code here`
data: {
gender: "female"
}
})
, for component re usability reason
I am trying to make a radio button checked using vuejs v-for only if my if-statement is true. Is there a way to use vuejs' v-if/v-else for this type of problem?
in php and html I can achieve this by doing the following:
<input type="radio" <? if(portal.id == currentPortalId) ? 'checked="checked"' : ''?>>
Below is what I have so far using vuejs:
<div v-for="portal in portals">
<input type="radio" id="{{portal.id}}" name="portalSelect"
v-bind:value="{id: portal.id, name: portal.name}"
v-model="newPortalSelect"
v-on:change="showSellers"
v-if="{{portal.id == currentPortalId}}"
checked="checked">
<label for="{{portal.id}}">{{portal.name}}</label>
</div>
I know the v-if statement here is for checking whether to show or hide the input.
Any help would be very much appreciated.
You could bind the checked attribute like this:
<div v-for="portal in portals">
<input type="radio"
id="{{portal.id}}"
name="portalSelect"
v-bind:value="{id: portal.id, name: portal.name}"
v-model="newPortalSelect"
v-on:change="showSellers"
:checked="portal.id == currentPortalId">
<label for="{{portal.id}}">{{portal.name}}</label>
</div>
Simple example: https://jsfiddle.net/b4k6tpj9/
Maybe someone finds this approach helpful:
In template I assign each radio button a value:
<input type="radio" value="1" v-model.number="someProperty">
<input type="radio" value="2" v-model.number="someProperty">
Then in the component I set the value, i.e:
data: function () {
return {
someProperty: 2
}
}
And in this case vue will select the second radio button.
You can follow below option if you can adjust with your logic:
<div class="combination-quantity">
<input type="radio" value="Lost"
v-model="missing_status">
<label for="lost">Lost</label>
<br>
<input type="radio" value="Return Supplier" v-model="missing_status">
<label for="return_supplier">Return Supplier</label>
</div>
Value for missing_status could be "Lost" or "Return Supplier" and based on the value radio option will be get selected automatically.
Below is an example of keeping track of the selected radiobutton, by
applying a value binding to the object (:value="portal") and
applying a v-model binding to the currently selected object (v-model="currentPortal").
The radiobutton will be checked automatically by Vue, when the two match (no :checked binding necessary!).
Vue 3 with composition API
Vue.createApp({
setup() {
const portals = [{
id: 1,
name: "Portal 1"
}, {
id: 2,
name: "Portal 2"
}];
const currentPortal = portals[1];
return {
portals,
currentPortal
}
}
}).mount("#app");
<script src="https://unpkg.com/vue#next"></script>
<div id="app">
<template v-for="portal in portals">
<input
type="radio"
:id="portal.id"
name="portalSelect"
:value="portal"
v-model="currentPortal">
<label :for="portal.id">{{portal.name}}</label>
</template>
</div>
I would like to point out a few options when dealing with radios and vue.js. In general if you need to dynamically bind an attribute value you can use the shorthand binding syntax to bind to and calculate that value. You can bind to data, a computed value or a method and a combination of all three.
new Vue({
el: '#demo',
data() {
return {
checkedData: false,
checkedGroupVModel: "radioVModel3", //some defaul
toggleChecked: false,
recalculateComputed: null
};
},
computed: {
amIChecked() {
let isEven = false;
if (this.recalculateComputed) {
let timeMills = new Date().getMilliseconds();
isEven = timeMills % 2 === 0;
}
return isEven;
}
},
methods: {
onToggle() {
this.toggleChecked = !this.toggleChecked;
return this.toggleChecked;
},
mutateComputedDependentData() {
this.recalculateComputed = {};
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="demo">
<div>
<div>
<span>Simple Radio Group - Only one checked at a time. Bound to data.checkedData</span><br>
<label>Radio 1 - inverse of checkedData = {{!checkedData}}
<input type="radio" name="group1" value="radio1" :checked="!checkedData">
</label><br>
<label>Radio 2 - checkedData = {{checkedData}}
<input type="radio" name="group1" value="radio2" :checked="checkedData">
</label><br>
<span>Understanding checked attribute: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-checked</span>
</div>
<br>
<div>
<span>Simple Radio - Checked bouned to semi-random computed object</span><br>
<label>Radio 1: {{amIChecked}}
<input type="radio" :checked="amIChecked">
</label>
<label>Recalculate Computed Value
<button type="button" #click="mutateComputedDependentData">Click Me Several Times</button>
</label>
</div>
<br>
<div>
<span>Simple Radio Group - v-model bound value = {{checkedGroupVModel}}</span><br>
<label>Simple Radio 1:
<input type="radio" name="vModelGroup" value="radioVModel1" v-model="checkedGroupVModel">
</label><br>
<label>Simple Radio 2:
<input type="radio" name="vModelGroup" value="radioVModel2" v-model="checkedGroupVModel">
</label><br>
<label>Simple Radio 3:
<input type="radio" name="vModelGroup" value="radioVModel3" v-model="checkedGroupVModel">
</label>
</div>
<br>
<div>
<span>Simpe Radio - click handler to toggle data bound to :checked to toggle selection</span><br>
<label>Toggle Radio = {{toggleChecked}}
<input type="radio" :checked="toggleChecked" #click='onToggle()'>
</label>
</div>
</div>
</div>