Passing parameters on checking and un-checking of a checkbox - html

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>

Related

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

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/

VueJs set active class to the data coming from API, when one li element is clicked in V-for loop

I need to set active class to one of the many options, which is coming from API. Also the first option is active at first, and when user clicks it has to toggle.
Below is my template :
<div #click="showTimezone">
<span>{{defaultCountry}}</span>
</div>
<div id="timezone-menu" class="timezone-menu" v-show="showTimezone">
<ul >
<li class="country-menu-item" v-for="item in Options" :id="item.id" :key="item.abbrevation" #click="selectCountry(item)">
{{ item.optionText }}
</li>
</ul>
</div>
I stored the data from API in Options array.
data() {
return {
defaultCountry: "CST",
Options: [],
}
}
On the drop down, the CST will be by default Bold. On clicking other option, it should lose its style class and added to the other option which user clicked. Please help me out on how to do this. Will provide additional details if required.
Add property called activeId to your data object and update it in the selectCountry method:
data() {
return {
defaultCountry: "CST",
Options: [],
activeId:-1
}
},
methods:{
selectCountry(item){
...
this.activeId=item.id;
}
}
in the template add the class binding :
<li class="country-menu-item" :class="{'active':item.id===activeId}" v-for="item in Options"

How to set formgroup data from angular

I have a formgroup like below:
this.myform = this.fb.group({
mydata: ''
});
I was able to set the data with formgroup setValue but in rendering the values in HTML, the option was not selected.
This is the HTML:
<div *ngFor="let item of (items$ | async); index as i; first as first">
<input type="radio" id="{{item.itemId}}" name="test" value="{{item.itemId}}" [formControl]="myform.controls.mydata"
selected = "(items$ | async).length ===1">
</div>
This doesnot select the first input label in HTML but in typescript the form is valid .
Use the setValue() method to set a new value for an individual control. The setValue() method strictly adheres to the structure of the form group and replaces the entire value for the control.
this.myform.setValue({ mydata: 'yourData' });
use the patchValue to set the value for the whole form
this.myform .patchValue({ mydata: 'yourData' });

Angular 6: How to build a simple multiple checkbox to be checked/unchecked by the user?

I am writing this post after having read several threads concerning this topic but no one of them gives me what I need. This post seems to have the solution but I do not have to read the checked values from the json.
All I need is to:
read countries from an array of objects
build dinamically a list of checkbox representing each country
user should check and uncheck each checkbox
bonus:
get the value of the checked input and send it outside the component
I know It might be really dumb to do but all I have accomplished untile now is to have a list of uncheckable checkboxes and nothing more.
Here is the code:
Template:
<div class="form-group">
<div *ngFor="let country of countries">
<input type="checkbox"
name="countries"
value="{{country.id}}"
[(ngModel)]="country"/>
<label>{{country.name}}</label>
</div>
</div>
And TS:
countries = [
{id: 1, name: 'Italia'},
{id: 2, name: 'Brasile'},
{id: 3, name: 'Florida'},
{id: 4, name: 'Spagna'},
{id: 5, name: 'Santo Domingo'},
]
I tried to use the reactive forms but that gave me more issues then template driven (surely because of bad implementation of mine).
Please, help me, I do not know where to bump my head anymore
Here is a working example, where you can observe that an additional 'checked' value is added to each country, and bound to the value of each checkbox with [(ngModel)].
Stackblitz live example
template:
<p>
Test checkboxes
</p>
<div *ngFor="let country of countries; let i = index;">
<input type="checkbox" name="country{{country.id}}" [(ngModel)]="countries[i].checked">
<label for="country{{country.id}}">{{country.name}}</label>
</div>
<button type="button" (click)="sendCheckedCountries()" *ngIf="countries">Click to send the selected countries (see your javascript console)</button>
<p *ngIf="!countries">loading countries, please wait a second...</p>
<p *ngIf="countries">Debug info : live value of the 'countries' array:</p>
<pre>{{ countries | json }}</pre>
component :
//...
export class AppComponent implements OnInit {
public countries: Country[];
constructor(private countryService: CountryService) {}
public ngOnInit(): void {
// loading of countries, simulate some delay
setTimeout(() => {
this.countries = this.countryService.getCountries();
}, 1000);
}
// this function does the job of sending the selected countried out the component
public sendCheckedCountries(): void {
const selectedCountries = this.countries.filter( (country) => country.checked );
// you could use an EventEmitter and emit the selected values here, or send them to another API with some service
console.log (selectedCountries);
}
}
To use some proper TypeScript, I made an interface Country :
interface Country {
id: number;
name: string;
checked?: boolean;
}
I hope you get the idea now.
Note : the checked value is not "automatically there" at the beginning, but it doesn't matter.
When not there, it is the same as undefined, and this will be treated as false both in the checkbox and in the function that reads which country is checked.
For the "sending value" part :
The button will output the selected value to the browser's console, with some filter similar to what #Eliseo's answer suggests (I just used full country objects instead of ids)
For "real usecase" situation, you could use Angular's EventEmitters and have your component "emit" the value to a parent component, or call some service function that will make a POST request of your values to another API.
Your countries like
{id: 1, name: 'Italia',checked:false},
Your html like
<div *ngFor="let country of countries">
<input type="checkbox" [(ngModel)]="country.checked"/>
<label>{{country.name}}</label>
</div>
You'll get an array like, e.g.
[{id: 1, name: 'Italia',checked:false},{id: 2, name: 'Brasile',checked:tue}..]
you can do
result=this.countries.filter(x=>x.checked).map(x=>x.id)
//result becomes [2,...]
I had an error using [(ngModel)]
In case it serves anyone, I have solved the problem changing
[(ngModel)]
to:
[checked]="countries[i].checked" (change)="countries[i].checked= !countries[i].checked"

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. :)