Getting value of checkbox using angular - javascript

I have a problem with getting values of checkbox in angular. Here is the snippet:
<div class="list-group-item" *ngFor="let ticket of tickets">
<input
type="checkbox"
[name]="ticket.id"
[id]="ticket.id"
[value]="ticket.id"
formControlName="ticketTypes"
/>
<label for="{{ ticket.id }}">{{ ticket.name }}</label>
</div>
I am getting above checkbox's value as true. How to get checkbox value correctly ?
Here is a stackblitz

You can use (change) which fires every time when change detects on the input element and then write a custom logic to get the checked items from list, for example:
HTML:
<div class="list-group-item" *ngFor="let ticket of tickets">
<input type="checkbox" [name]="ticket.id" [id]="ticket.id" [value]="ticket.id" (change)="onCheck(ticket.id)"/>
<label for="{{ ticket.id }}">{{ ticket.name }}</label>
</div>
<pre>{{tickets | json}}</pre>
TS Code:
import { Component } from "#angular/core";
#Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
tickets = [{ id: 1, name: "Test1" }, { id: 2, name: "Test2" }];
checkedTickets = [];
onCheck(evt) {
if (!this.checkedTickets.includes(evt)) {
this.checkedTickets.push(evt);
} else {
var index = this.checkedTickets.indexOf(evt);
if (index > -1) {
this.checkedTickets.splice(index, 1);
}
}
console.log(this.checkedTickets);
}
}
Working Demo

In such scenarios better/recommended to use formArray if you are dealing with the form or you can use simply ngModel two way data binding of Angular.
<form [formGroup]="form" (submit)="submit(form.value)">
<div *ngFor="let s of addOns.controls; let j=index">
<input type="checkbox" [formControl]="s"/> {{user1.addOns[j].name}}
</div>
</form>
Also simply formControlName i.e single control is generally used while dealing with Radio Buttons because in that case user can select always single value but here in case of checkboxes you can select multiple entries as well, which is designed like this, So you might use array in that case like above in my example.
Working Example
Or in case you want to use ngModel you can use it like this -
<ul>
<li *ngFor="let item of list">
<input type="checkbox" [(ngModel)]="item.checked">{{item.title}}
</li>
</ul>
Working Example

Related

How can I associate labels with form fields outside them in Angular?

Let's say I'm creating labels and form fields in a *ngFor loop like this:
app.component.ts
export class AppComponent {
items = ['aaa', 'bbbbbb', 'ccccccccc']
}
app.component.html
<div class='form'>
<ng-container *ngFor="let item of items">
<label>{{item|uppercase}}:</label>
<input [value]="item"/>
</ng-container>
</div>
(See it on StackBlitz: https://stackblitz.com/edit/angular-ptwq6t)
Is there a way to cleanly associate these "dynamic" labels and inputs with one another? If I do:
<label for="field" >{{item|uppercase}}:</label>
<input id="field" [value]="item"/>
Angular just repeats the for and id attributes verbatim and all labels point to the first input field.
Is there some way to use Angular's component identity, or am I stuck with something like generating a UUID myself, or otherwise guaranteeing uniqueness of the ID myself?
I can't nest the input inside the label because I have to reuse some already implemented CSS that doesn't expect that structure, but would still like the better usability that comes from having a proper label.
Given that the items are unique, you could surely do this:
<label [for]="item" >{{item|uppercase}}:</label>
<input [id]="item" [value]="item"/>
That way, each id and for would be unique and label would work as required.
Here is the demo.
If you anyway need to generate the unique IDs, take a look at shortid
you can try:
<div class='form'>
<ng-container *ngFor="let item of items">
<label for="{{item}} + 'field'" >{{item|uppercase}}:</label>
<input id="{{item}} + 'field'" [value]="item"/>
</ng-container>
</div>
or use the ngfor index if your items are not unique:
<div class='form'>
<ng-container *ngFor="let item of items; let i = index">
<label for="{{i}} + 'field'" >{{item|uppercase}}:</label>
<input id="{{i}} + 'field'" [value]="item"/>
</ng-container>
</div>
DEMO

Angular Reactive Forms binding a control to multiple inputs doesn't refresh the others

When I am using reactive forms and try to access the same control in multiple Inputs it looks like it's only a one-way-data-binding (input-to-model).
If I edit an input it will update the model correctly but it will not refresh the other input as well.
<input type="text" formControlName="test" id="in1">
<input type="text" formControlName="test" id="in2">
My work-a-round is to add the following line to both inputs:
(change)="form.controls.test.setValue(form.controls.test.value)
But to be honest this looks like a pretty bad solution. Am I doing anything wrong here? What is the correct way to archive this?
https://plnkr.co/edit/yALzCIHgOA463OvGi5rP
I don't sure why you need exactly 2 fields with same formControlName but a solution could be - Create custom angular element.
#Component({
selector: 'custom-element',
templateUrl: `
<input type="text" [(ngModel)]="value">
<input type="text" [(ngModel)]="value">
`,
styleUrls: ['./custom-element.component.css']
})
export class CustomElementComponent implements ControlValueAccessor
#Input() value: any
writeValue(value: any) {
// Some if statements
this.value = value;
}
registerOnChange(fn: Function) {
// your code here
}
registerOnTouched(fn: Function) {
// your code here
}
And in the parent component template
<custom-element formControlName="fieldname"></custom-element>
For more details (and deeper explanation), you can check https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html
You can use ngModel:
<div>
<form [formGroup]="form">
<h2>Test = {{form?.controls.test.value}}</h2>
1. <input type="text" formControlName="test" [(ngModel)]="test">
2. <input type="text" formControlName="test" [(ngModel)]="test">
3.
<button type="button" (click)="form.controls.test.setValue('manual')">change with setValue</button>
</form>
</div>
The two-way binding syntax is really just syntactic sugar for a
property binding and an event binding
For example:
<app-sizer [(size)]="fontSizePx"></app-sizer>
Is equal to:
<app-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></app-sizer>
CODE EXAMPLE

Count how many check boxes checked in Angular 2 typescript?

How to count how many boxes checked in Angular 2/4 using typescript. It should show the count of the check boxes checked, and if unchecked it should decrement to 0.
My example, data coming from server, which I loop through:
I know how to do it using foreach function in Angularjs, but cant understand how to do this in Typescript, generally I have to replace angular foreach method with Typescript foreach method? Need help
app.ts
data = [
{"name":"jason"},
{"name":"james"},
{"name":"josh"},
{"name":"joshua"}
];
calculateChecked = function() {
let count = 0;
angular.forEach(this.data, function(value) { //don't work in typescript
if(value.checked)
count++;
});
return count;
};
};
app.htm
<li class="list-group-item" *ngFor="let user of data">
<input type="checkbox" [ngModel]="user.checked"/>
{{user.name}}
</li>
<p>total checked: {{calculateChecked()}}</p>
should show:
And if unchecked should show 0
<div class="sasha-ui-list" #em *ngFor="let email of emails; let i=index"
(click)="onAddtoMessage(email)"> <div class="row"> <div class="col-lg-1">
<input class="magic-checkbox sasha_checkbox" name="emails" type="checkbox"
id="{{email.id}}" value="email" [checked]="checkboxFlag"> <label for="
{{email.id}}"></label> </div>
You should make it to 0 when clicked as below,
changed(){
this.count = 0;
this.data.forEach(item=>{
console.log(item)
if(item.checked){
this.count= this.count+1
}
} )
}
<ul> <li class="list-group-item" *ngFor="let user of data">
<input type="checkbox" [(ngModel)]="user.checked" (ngModelChange)="changed()"/>
{{user.name}}
</li>
LIVE DEMO
not tested code, but something like this should work, if data is an array
this.data.map((value) => {
if(value.checked)
count++;
});
Use a for..of loop:
this.count: number = 0;
for (let datum of data) {
if(dataum.checked) count++;
}
And the markup to..
<ul> <li class="list-group-item" *ngFor="let user of data">
<input type="checkbox" [(ngModel)]="user.checked" (ngModelChange)="changed()"/>
{{user.name}}
</li>
<p>total checked: {{count}}</p>

Angular 2 - Add Value of Checked Radio Button to Array

I am trying to get the checked radio button and add the value to an Array. Currently, i cannot remove the previously checked radio buttons, so basically it keeps adding to the array every time i select a radio button.
item.component.ts
displaySelectedConditions(event) {
if(event.target.checked) {
this.selectedConditionsArr.push(event.target.value);
}
}
item.component.html
<ul class="dropdown-menu">
<li *ngFor="let item of filteredItems | funder "> //generates 4 items
<a><input type="radio" (change) = "displaySelectedConditions($event);"
name="funder" id="{{item}}" value="{{item}}">
<label for="{{item}}" >{{item}}</label></a>
</li>
</ul><!-- Dropdown Menu -->
I would suggest if you want to have the values neatly stored somewhere, then make use of a form. Simple template driven form works well here, then you would have all your values stored in an object, here's a sample:
<form #radioGroup="ngForm">
<div *ngFor="let str of strings">
<input type="radio" [value]="str" name="str" ngModel />{{str}}
</div>
<hr>
<div *ngFor="let num of numbers">
<input type="radio" [value]="num" name="num" ngModel />{{num}}
</div>
</form>
This would create an object like:
{
str: "value here",
num: "value here"
}
And if you declare the form like the following, you can easily access the object values:
#ViewChild('radioGroup') radioGroup: NgForm;
Somewhere in component:
console.log(this.radioGroup.value);
Plunker

How to check all checkboxs with angular

I have a checkbox that should check all checkboxes. The checkbox works as it should by checking all the checkbox's, however angular doesnt think they have been checked? The only way angular knows if they are checked is if i manually check each one. (The brackets and for loop are blade php from laravel)
<label class="checkbox-inline">
<input type="checkbox" ng-model="everyoneCheck"/> Everyone
</label>
#foreach($company->users as $tagIndex => $user)
<label class="checkbox-inline">
<input type="checkbox" ng-checked="everyoneCheck" ng-model="newDiscussion.notify_partners[{{$tagIndex}}]" ng-true-value="{{$user->id}}" /> {{ $user->first_name }} {{ $user->last_name }}
</label>
#endforeach
upon click of the submit button i proceed to $http.post to my server, i just pass in an object to the post function, this is the object.
var discussionData = {
'title': $scope.newDiscussion.title,
'discussion': $scope.newDiscussion.summary,
'company_id': company_id,
'notify_partners': $scope.newDiscussion.notify_partners
};
for some reason when i use the check all approach, nothing gets put into notify_partners, however when i manually click each checkbox, they will get entered and submitted properly.
Any help? I feel like its some sort of binding issue, where i just need to tell angular, hey its updated!
Here's a way to do it:
<p><input type="checkbox" ng-model="globalCheck" ng-click="toggleCheckAll()" /> Check All</p>
<ul>
<li ng-repeat="i in init">
<input type="checkbox" ng-model="checkbox[$index]" /> Checkbox {{ $index + 1 }} {{ checkbox[$index] }}
</li>
</ul>
Then in your controller:
function myControl($scope) {
$scope.globalCheck = false;
$scope.checkbox = {};
$scope.init = [0,1,2,3,4,5,6,7,8,9];
$scope.toggleCheckAll = function() {
var k, val = !$scope.globalCheck;
console.log(val);
for(k in $scope.init) {
$scope.checkbox[k] = val;
}
}
}
See JSfiddle for working example
ng-checked does not update the value bound in ng-model. It only affects the presence of the checked attribute on the element itself.
Your best bet is to use ng-change to execute some function and update all your models accordingly.
<input type="checkbox"
ng-model="everyoneCheck"
ng-change="toggleCheckAll()"/>
And in your controller, you can have toggleCheckAll() loop over your models and set them based on the value of everyoneCheck

Categories

Resources