VueJs Checked Radio Button group - vue.js

I am using vueJs and have a radio button group. When the radio is checked how can I bind a css border attribute to a class :class="selected"?
The :checked attribute does not work as I have bound it to the v-model.
So if the radio is checked bind a class (selected) to the div.
<div class="sau-select lg center" :class="selected">
<label for="windows">
<input type="radio" id="windows" value="windows" v-model="selectedOs" :checked="checked">
<span></span>
<img src="/img/windows.gif" alt="Windows">Windows
</label>
</div>

The :class="selected" you use hasn't much effect.
To conditionally apply a class to the div, you will have to use as :class condition if the selectedOs equals the value attribute of each <input>, such as :class="{redborder: selectedOs === 'windows'}". More details in the demo below:
new Vue({
el: '#app',
data: {
selectedOs: 'windows'
}
})
.redborder { border: 1px solid red; }
<script src="https://unpkg.com/vue"></script>
<div id="app">
<label :class="{redborder: selectedOs === 'windows'}">
<input type="radio" value="windows" v-model="selectedOs"> Windows
</label>
<label :class="{redborder: selectedOs === 'linux'}">
<input type="radio" value="linux" v-model="selectedOs"> Linux
</label>
</div>
Notice that value="linux" means that that radio box will assign the string "linux" to the v-model variable (in this case selectedOs). value="linux" is equivalent to :value="'linux'", for instance.

Related

Modify checkbox behavior in vue js

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

Vue-JS v-show Percitence in radio

v-show appears not be percitent when whit radio (v-model)
Please find example: https://jsfiddle.net/Lngocxrj/1/
<div id="helloWorldApp">
<input type="radio" v-model="visible" value="true" name="optradio">hide
<input type="radio" v-model="visible" value="false" name="optradio">show
<div v-show="visible">
Hello World
</div>
<p>
{{visible}}
</p>
</div>
new Vue({
el: "#helloWorldApp",
data: {
visible: true
},
methods: {
show: function() {
this.visible = !this.visible;
}
}
});
It works, if you use a method to toggle the data.
HTML:
<div id="helloWorldApp">
<label>hide<input type="radio" value="false" #click="inputClick(false)" name="optradio" /></label>
<label>show<input type="radio" value="true" #click="inputClick(true)" name="optradio" /></label>
<div v-show="visible">
Hello World
</div>
<p>
{{visible}}
</p>
</div>
JavaScript:
new Vue({
el: "#helloWorldApp",
data: {
visible: false
},
methods: {
inputClick(val) {
this.visible = val;
}
}
});
Added a new property to differentiate input changes and show/hide div
<div id="helloWorldApp">
<input type="radio" v-model="visible" value="true" name="optradio">hide
<input type="radio" v-model="visible" value="false" name="optradio">show
<div v-if="showDiv">
Hello Worlds
</div>
<p>
{{visible}}
</p>
</div>
new Vue({
el: "#helloWorldApp",
data: {
visible: false,
showDiv: true
},
watch: {
visible(val) {
this.showDiv = val;
}
}
});
As per my comment: the reason why your element is showing regardless of the v-show directive is because the values from the checkboxes are being stored as strings and not booleans. And since "false" is actually truthy because it is a string of non-zero length, your div will always be visible.
Quick solution: Perform string comparison
If you want to keep your code as-is, and understanding that you are looking at string values instead of boolean stored in visible, updating your template to use v-show="visible === 'true'" will work.
Note: I do not encourage this method though, because this is a code smell (see further below for a better solution).
new Vue({
el: "#helloWorldApp",
data: {
visible: 'true'
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="helloWorldApp">
<input type="radio" v-model="visible" value="true" name="optradio">hide
<input type="radio" v-model="visible" value="false" name="optradio">show
<div v-show="visible === 'true'">
Hello World
</div>
<p>
{{visible}}
</p>
</div>
A better solution: use checkbox for binary state toggling
This brings us to another issue: since you are toggling a property, a radio button is not the best UI to do that. A checkbox is more appropriate: in this case, you don't need to do dirty strict comparisons:
new Vue({
el: "#helloWorldApp",
data: {
visible: true
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="helloWorldApp">
<input type="checkbox" v-model="visible" checked>visible
<div v-show="visible">
Hello World
</div>
<p>
{{visible}}
</p>
</div>

Form with radio buttons not submitted

I have a form with two radio buttons which is enabled only when a checkbox is checked.
My problem is when I check the checkbox and click the submit button, the radio value is not getting posted. But after I click on the checkbox and then click on one of the radio buttons then the value is posted.
How to fix this issue?
This is the code I have tried:
HTML
<form [formGroup]="filterProductTargetForm" (ngSubmit)="onSubmitFilterDataList(filterProductTargetForm.value)">
<div class="row">
<div class="col-md-10">
<input type="checkbox" [ngModel]="isProductTypeChecked" formControlName="checkProductType" (change)="onProductTypeChange($event)" />
<label>Select A or B</label>
</div>
</div>
<div class="row">
<label class="col-md-2 uni-label"></label>
<div class="col-md-10 prduct-type-radio">
<fieldset [disabled]="!isProductTypeChecked">
<input type="radio" [checked]="isProductTypeChecked == true" value="A" formControlName="productTypeSelected" [(ngModel)]="productTypeSelected">
<span>B</span>
<br>
<input type="radio" value="B" formControlName="productTypeSelected" [(ngModel)]="productTypeSelected">
<span>B</span>
</fieldset>
</div>
</div>
<button class="uni-button def" [disabled]="!filterProductTargetForm.valid">OK</button>
</form>
TS
ngOnInit() {
this.filterProductTargetForm = this.formBuilder.group({
'checkProductType': '',
'productTypeSelected': ''
});
}
public filterProductTargetForm: FormGroup;
public isProductTypeChecked = false;
onProductTypeChange(event: any) {
this.isProductTypeChecked = !this.isProductTypeChecked;
if(!this.isProductTypeChecked)
this.filterProductTargetForm.controls['productTypeSelected'].reset();
}
First remove all ngModel from your template when using reactive forms.
When the checkbox value changes, in your onProductTypeChange function set the productTypeSelected value
this.filterProductTargetForm.controls['productTypeSelected'].setValue('A');
Working StackBlitz DEMO

VueJS - how to show different div on radio button select

How to show different component on radio button select.
<input type="radio" name="book" value="One" checked="checked">
<input type="radio" name="book" value="Round">
<div> // this should show show default, One is selected
<p>Value One</p>
</div>
<div> // this should show show on radio change to Round selected
<p>Value Round</p>
</div>
How about something like this?
new Vue({
el: '#app',
data: {
x: 'one',
},
});
<script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>
<div id="app">
<input type="radio" v-model="x" value="one">
<input type="radio" v-model="x" value="two">
<div v-show="x === 'one'">One</div>
<div v-show="x === 'two'">Two</div>
</div>
i have done it with javascript .onclick it calls each function which hides & show element vice versa
function rdone(){
document.getElementById('one').style.display ='block';
document.getElementById('round').style.display ='none';
}
function rdround(){
document.getElementById('round').style.display = 'block';
document.getElementById('one').style.display ='none';
}
#round{
display:none;
}
<input type="radio" name="book" value="One" checked="checked" onclick="rdone();">
<input type="radio" onclick="rdround();" name="book" value="Round">
<div id=one> // this should show show default, One is selected
<p>Value One</p>
</div>
<div id=round> // this should show show on radio change to Round selected
<p>Value Round</p>
</div>

vuejs set a radio button checked if statement is true

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>