Switch multiple toggle buttons on/off based on created() data - html

I have multiple toggle buttons , each which should be selected if that value is present in the obtained response which i get through created().
<li>
<input
v-on:click="toggleCheckbox($event)"
type="checkbox"
v-model="selectedCategories.jfif"
:checked="selectedCategories.jfif === 'active'" />
</li>,
<li>
<input
v-on:click="toggleCheckbox($event)"
type="checkbox"
v-model="selectedCategories.exif"
:checked="selectedCategories.exif === 'active'" />
</li>,
<li>
<input
v-on:click="toggleCheckbox($event)"
type="checkbox"
v-model="selectedCategories.iptc"
:checked="selectedCategories.iptc === 'active'" />
</li>
I have multiple lists wrapped inside a ul.
The script is as shown:
export default {
data() {
return {
selectedCategories: {},
};
},
methods: {
toggleCheckbox(event) {
console.log("Event is,", event, event.value);
},
},
created() {
//this is how i get the response
this.selectedCategories = {"exif":"active","iptc":"active"}
});
The issue is, if i get the data as :{"exif":"active","iptc":"active"} in this case jfif is not present. All the toggle switches are turned off. Even the one having "exif" and "iptc" get turned off. Where is my binding going wrong?

Instead of a dictionary , i used a list to bind and gave a value parameter to each li.
<li>
<input
v-on:click="toggleCheckbox($event)"
type="checkbox"
value="exif"
v-model="checkedCategories"
</li>
<li>
<input
v-on:click="toggleCheckbox($event)"
type="checkbox"
value="jfif"
v-model="checkedCategories"
</li>
<li>
<input
v-on:click="toggleCheckbox($event)"
type="checkbox"
value="iptc"
v-model="checkedCategories"
</li>
Now i get the response in the format of ["exif","iptc"]
data(){
return checkedCategories: []
},
created() {
this.checkedCategories = ["exif","iptc"]
});
}

Using v-model together with checked doesn't make much sense since v-model sets checked itself. Read the Vue documentation on checkboxes: https://v2.vuejs.org/v2/guide/forms.html#Checkbox-1
Instead of checked you need to use the true-value and false-value attributes, so in your case true-value="active" and depending what you want to use, for example, false-value="" for an empty string, or :false-value="null" for null (notice the : or you'll get a string "null" instead).
Here is an working example: https://jsfiddle.net/kgewf04d/1/

Related

Iterate over array of objects and display key and value for each object in ngFor in Angular 12

In an Angular 12 app the data returned from an API is
data = {
"options":[
{
"Yes": 1
},
{
"No": 0
}
]
}
My requirement is to iterate over this array and display radio buttons dynamically in the html as shown below.
<div *ngFor="let option of data.options;">
<input type="radio" class="form-control" name="rdgroup" value="{{option.key}}">
<label>{{option.value}}</label>
</div>
I want display labels for radio buttons to be 'Yes' and 'No' and their values should be 1 and 0 respectively. Currently nothing is displayed. How do I fix it?
You will need to modify you data in order to render radio buttons.
Check this stackblitz: https://stackblitz.com/edit/angular-material-with-angular-sidenav-spz9oq?file=app/app.component.html
Use the below method on your component:
options = this.data.options.map( (op) => {
const key = Object.keys(op)[0];
return {
"value" : Object.keys(op)[0],
"key": op[key]
}
});
and in template
<div *ngFor="let option of options;">
<input type="radio" class="form-control" name="rdgroup" value="{{option.key}}">
<label>{{option.value}}</label>
</div>
You can try in this way, It may help you to get expected output!
edit your component.ts file, and add below defined method.
getEntrires(object: any) {
return Object.entries(object);
}
this method will return you Object entry with it's KEY & VALUE in Array
For Example:
let output = getEntrires({"Yes": 1});
console.log(output) // [Array[2]] => it will be two dimensional array
Now in your html you can consume this in this way
<div *ngFor="let option of data.options;">
<input type="radio" class="form-control" name="rdgroup" value="{{getEntrires(option)[0][1]}}">
<label>{{getEntrires(option)[0][0]}}</label>
</div>

How to make radio buttons with same value reusable?

I am a beginner to Vue, and learning something by doing. I was able to make a checkbox reusable, but getting some weird result for radio buttons.
I have the data in an array format in ProgramDesign.vue:
data() {
return {
strategies: [
"Not Important",
"Slightly Important",
"Moderately Important",
"Very Important",
"Extremely Important",
],
};
},
These are the options that get repeated on every question.
I made a separate component for the radio like this:
<template>
<div>
<span v-for="strategy in groups" :key="strategy">
<input :id="strategy" class="radio-style" name="strategy" type="radio" />
<label :for="strategy" class="radio-style-3-label">{{strategy}}</label>
</span>
</div>
</template>
<script>
export default {
props: {
groups: Array,
},
};
</script>
This is how it's used in ProgramDesign.vue:
<p>first question goes here ?</p>
<RadioButton :groups="strategies" />
<div class="line"></div>
<p>second question goes here ?</p>
<RadioButton :groups="strategies" />
I was able to get the reusable output, but when I click on the radio button for the second question, the buttons for the first question get selected. How can I fix this?
The problem is the input IDs and names are not unique between component instances, as can be seen in the rendering of your two RadioButton components (simplified for brevity):
<!-- RadioButton 1 -->
<div>
<span>
<input id="Not Important" name="strategy" type="radio">
<label for="Not Important">Not Important</label>
</span>
</div>
<!-- RadioButton 2 -->
<div>
<span>
<input id="Not Important"❌ name="strategy"❌ type="radio">
<label for="Not Important">Not Important</label>
</span>
</div>
Each label is linked to an input by matching the for and id attributes, such that clicking the label causes the linked radio input to change values. When there are multiple inputs with the same identifier, the browser links the label to the first matching input, causing the behavior you observed.
The name must also be unique between groups (RadioButton instances), since the browser creates radio groups of inputs that have matching names.
Solution
Alternatively, a label and input can be linked by putting the input inside the label, resolving the id/for duplication (and improving readability):
<label>
<input name="strategy" type="radio">
Not Important
</label>
And one way to resolve the duplicate names is to base the name on a counter incremented per instance:
<template>
<div>
<label v-for="strategy in groups" :key="strategy">
<input :name="'strategy' + groupId" type="radio">
{{strategy}}
</label>
</div>
</template>
<script>
let groupId = 0
export default {
props: {
groups: Array
},
data() {
return {
groupId: groupId++
}
}
}
</script>

Passing parameters on checking and un-checking of a checkbox

I am new to Angular and typescript. I need help from someone in the following requirement.I have a web page where I have a list of check boxes as given here:
I have defined a isChecked boolean variable in component.ts file and has a data binding with the template using ngModel. A function onChange() is called when the checkbox is checked or un-checked. I want to pass two parameters to the function. One is check/uncheck value i.e like true/false and another is the string value containing the label of the checkbox clicked. For example if st1 is checked then onChange(check, 'st1') will be invoked. The logic inside component class will add 'st1' to an array if it is unchecked.
In the template I have written like this:
<ul>
<li [(ngModel)]="student" *ngFor="let student of studentsToLOad" [value]="student">
<b>{{student.name}}</b>
<input type="checkbox" id="present" name="present" [(ngModel)]="isChecked"
(change)="onChange(isChecked, student)"/>
</li>
</ul>
But when I am clicking on st1, all the other check boxes are also getting checked. Please help.
The ngModel value is set to a single variable isChecked. This variable is passed to all checkboxes. All the checkboxes will reflect their state based on isChecked. You could use some thing like student.checked. You could set the value in the onChange fucntion.
onChange(isChecked, student) {
student.isChecked = isChecked;
}
<ul>
<li [(ngModel)]="student" *ngFor="let student of studentsToLOad" [value]="student">
<b>{{student.name}}</b>
<input type="checkbox" id="present" name="present" [(ngModel)]="student.isChecked" (change)="onChange(isChecked, student)" />
</li>
</ul>
The error occurs because all the checkboxes are bound to a single global boolean flag isChecked.
You could remove the ngModel and value from the li element and bind the ngModel in input element to student specific booleans instead of a global boolean flag. Try the following
Controller
export class AppComponent {
studentsToLOad = [
{ name: 'st1', status: false },
{ name: 'st2', status: false },
{ name: 'st3', status: false },
{ name: 'st4', status: false },
];
onChange(status, name) {
console.log(name, status);
}
}
Template
<ul>
<li *ngFor="let student of studentsToLOad">
<b>{{student.name}}</b>
<input type="checkbox" id="present" name="present" [(ngModel)]="student.status"
(change)="onChange(student.status, student.name)"/>
</li>
</ul>

Multiple Checkbox value in angular2

I have one user model and one role model. I want to send value of role into db using checkbox in angular2 in http put request. I have one table user_role and I want to send role_id into that table. For the I am fetching all roles and showing it in html like this:
<a *ngFor="let role of roles">
<input type="checkbox" [value]="role.name" [(ngModel)]="user.role_id" [ngModelOptions]="{standalone: true}"/> <b>{{role.name}}</b>
</a>
Now I want, if I will check multiple checkboxes the multiple values should go into database. I am new in angular2. Could anyone please help me in getting this?
I have created a sample demo where you can understand how multiple checkbox value can be sent to server
here is my .ts file code
roles: Array<String> = [
{
"name":"qa",
"isSelected": false
},
{
"name":"developer",
"isSelected": false
},
{
"name":"manager",
"isSelected": false
},
{
"name":"BA",
"isSelected": false
},];
sendDataToServer() {
alert(JSON.stringify(this.roles)); }
I have a json roles and a function sendDataToServer that displays the final json that is to be sent on server
here is my .html code
<a *ngFor="let role of roles">
<input type="checkbox" [value]="role.name" [(ngModel)]="role.isSelected" [ngModelOptions]="{standalone: true}"/> <b>{{role.name}}</b>
</a>
<br><br>
<input type="button" value="Send Data On Server " (click)="sendDataToServer()"/>
So I have 4 checkbox and I have bind these checkbox with isSelcted property of json. As soon as user click on checkbox the value changes false to true.
when user click on sendDataToServer button then we have the updated isSelected values.
Hope this will help you. :)

Having trouble determining if a radio button was checked

I'm using radio buttons in a ui-kit switcher component:
<ul data-uk-switcher="{connect:'#availabilityButtons', animation:'fade'}">
<button class="uk-button uk-button-primary" type="radio" name="perHourButton" id="perHourButton" value="{{this.spaceId}}" data-uk-tooltip title="Rent hourly">Per Hour</button>
<button class="uk-button uk-button-primary" type="radio" name="'perDayButton" id="perDayButton" namedata-uk-tooltip title="Rent for full days">Per Day</button>
<button class="uk-button uk-button-primary" type="radio" data-uk-tooltip id="perMonthButton" title="Rent for full months">Per Month</button>
</ul>
I want to check which radio button is checked upon form submission, so I am doing the following on the front end:
if (document.getElementById('perHourButton').checked) {
console.log("perHour Button is checked!!");
}
else{
console.log("not checked!!");
}
But I continue getting "not checked". I don't know what I'm doing wrong.
I'm afraid the "radio" value is not valid for the type attribute on a button. That Might be the reason the .checked method does not return true. Try restructuring your html using input with type="checkbox" like so:
<ul data-uk-switcher="{connect:'#availabilityButtons', animation:'fade'}">
<li>
<input class="uk-button uk-button-primary" type="checkbox" name="perHourButton" id="perHourButton" value="{{this.spaceId}}" data-uk-tooltip title="Rent hourly" value="Per Hour"/>
</li>
</ul>
Also added an li tag around the checkbox for valid html.
If the html is generated automatically by the ui-kit (I don't know this framework), you might want to check out if you can use the javascript methods in the documentation to check which button has been clicked (using jQuery) :
$('[data-uk-switcher]').on('show.uk.switcher', function(event, area){
if(area == 1){ /* do something if we clicked button with index 1 */ };});
Try this:
if (document.getElementById('perHourButton').checked == true) {
console.log("perHour Button is checked!!");
}
else{
console.log("not checked!!");
}