I have two API, one that returns the list of all permissions and second that returns the list of selected permissions(contains permission Object) now I want to show the list of permissions in checkboxes but if the permission is already selected then show checkmark with it.
component.ts
getUserPermissions() {
this.permissionService.getUsersPermission().subscribe(permission => {
this.permission = permission;
})
}
getAssignedPermissions(uuid: any) {
this.permissionService.getAssignedPermissions(uuid, true).subscribe(res
=>{
this.userPermission = res;
})
}
component.html
<form id="permission" #form="ngForm" (ngSubmit)="onSubmit()" class="form-group">
<div *ngFor="let permission of permission" >
<label>
<input type="checkbox"
value="{{permission.code}}"
[(ngModel)]="permission.Checked"
[ngModelOptions]="{standalone: true}"
/>
{{permission.code}}
</label>
</div>
<button type="submit" class="btn theme-btn btn-secondary">SAVE</button>
You can simplify this by using async-await and iterate through permissions to check whether user permission is existing.
async getAllPermissions() {
this.userpermission = await this.permissionService.getUsersPermission().toPromise();
this.permission = await this.permissionService.getAssignedPermissions(uuid, true).toPromise();
this.permission.forEach(permission => {
if (this.userPermission.find(uPermission => uPermission === permission)) {
permission.Checked = true;
}
})
}
You can use a method that check if the permission is already assigned
<form id="permission" #form="ngForm" (ngSubmit)="onSubmit()" class="form-group">
<div *ngFor="let permission of permission" >
<label>
<input type="checkbox"
value="{{permission.code}}"
[ngModel]="permission.Checked || isassigned(permission)"
(ngModelChange)="permission.Checked = $event"
[ngModelOptions]="{standalone: true}"
/>
{{permission.code}}
</label>
</div>
isassigned(permission) {
const p = this.userPermission.find(p => p.code === permission.code)
return this.userPermission.find(p => p.code === permission.code) ? true: false
}
live code
You should just use [] for ngModel
<form id="permission" #form="ngForm" (ngSubmit)="onSubmit()" class="form-group">
<div *ngFor="let permission of permission" >
<label>
<input type="checkbox"
value="{{permission.code}}"
[ngModel]="permission.Checked"
[ngModelOptions]="{standalone: true}"
/>
{{permission.code}}
</label>
</div>
<button type="submit" class="btn theme-btn btn-secondary">SAVE</button>
Related
I am using template driven form.
Currently i am getting the true or false value. but i need the actual value of checkbox
<form #f = "ngForm" (ngSubmit) = "onClickSubmit(f.value)">
<h2 class="no-top-space">
{{Questions?.Question}}
</h2>
<div *ngFor="let op of options">
<input type="checkbox" name="check" [value]="option.Value" ngModel>{{op.Value}}
</div>
<button type="submit" role="button" class="btn btn-primary blue">Submit</button>
</form>
onClickSubmit(data){
console.log("dataaa",data)
}
Try this:
In html:
<input type="checkbox" name="check" [value]="op.Value" ngModel (change)="handleChange($event)">{{op.Value}}
In ts:
declare an array variable which will have a blank array initially. like
selectedOptions:string[]=[]
Then build the handleChange method as:
handleChange(event:any)
{
if(this.selectedOptions.length>0)
{
let existedOption = this.selectedHobby.findIndex((x) => x === e.target.value); //to check if it is already present in the array or not
if (existedOption != -1)
{
this.selectedOptions.splice(existedOption, 1);
}
else
{
this.selectedOptions.push(e.target.value);
}
}
else
{
this.selectedOptions.push(e.target.value);
}
console.log(this.selectedOptions);
}
I have an edit form as below which contains data in the input fields.
<ng-form #infoForm="ngForm" novalidate>
<div>
<label for="firstName">First Name :</label>
<input type="text"
class="form-control"
id="firstName"
name="firstName"
[(ngModel)]="in.firstName">
</div>
<div>
<label for="lastName">Last Name :</label>
<input type="text"
autocomplete="on"
class="form-control"
id="lastName"
name="lastName"
[(ngModel)]="in.lastName">
</div>
<button type="button" class="btn btn-primary" (click)="updateInfo(infoForm.value)">Update
</button>
</ng-form>
And I have the function in the component as below:
updateInfo(info: any) {
console.log(info);
}
This form return all the values (to the console) in the form when the Update button clicked, but I want to submit only the edited values instead of whole form. How could I implement it?
For this you can pass the form instead of its value to 'updateInfo' function and process it there. If user change the control value its state becomes 'dirty' from 'touched/pristine' and we can filter controls based on that.
Change in html:
<button type="button" class="btn btn-primary" (click)="updateInfo(infoForm)">Update
</button>
Change in *.ts file:
updateInfo(info: NgForm) {
const changedValues = Object.keys(info.controls)
.filter(key => info.controls[key].dirty === true)
.map(key => {
return { control: key, value: info.controls[key].value }
});
console.log(changedValues);
}
Im fairly new to working with angular and was wondering if there is a simple way to first check if the checkbox is selected. If it is selected, I want to pass it to the saveOptions function. If more than one is selected, I would like to pass them all and save them to an array of options. Can someone help me out?
import { Component } from '#angular/core';
import { forEach } from '#angular/router/src/utils/collection';
import { Options } from 'selenium-webdriver/ie';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
options: any = []
saveOptions(x:any[]){
x.forEach(element => {
this.options.push(element);
});
}
}
<ul class="option-row">
<div class="option-group">
<li><input type="checkbox" id="option-1" value="1" required> <label for="option-1">Option 1</label></li>
<li><input type="checkbox" id="option-2" value="2" required> <label for="option-2">Option 2</label></li>
<li><input type="checkbox" id="option-3" value="3" required> <label for="option-3">Option 3</label></li>
</div>
<!--Want to know how to check if the checkbox is selected and pass the selected options to the method-->
<button type="button" (click)="saveOptions();">Submit</button>
</ul>
One way is subscribing to valueChanges of the form, like this:
export class AppComponent implements OnInit {
options: any = []
model = { optionOne: false, optionTwo: false, optionThree: false }
formChangesSubscription;
#ViewChild('form') ngForm: NgForm;
ngOnInit() {
this.formChangesSubscription = this.ngForm.form.valueChanges.subscribe(x => {
console.log(x);
})
}
saveOptions(x: any[]) {
x.forEach(element => {
this.options.push(element);
});
}
}
<form #form="ngForm">
<ul class="option-row">
<div class="option-group">
<li><input type="checkbox" [(ngModel)]="model.optionOne" name="optionOne" id="option-1" value="1" required> <label for="option-1">Option 1</label></li>
<li><input type="checkbox" [(ngModel)]="model.optionTwo" name="optionTwo" id="option-2" value="2" required> <label for="option-2">Option 2</label></li>
<li><input type="checkbox" [(ngModel)]="model.optionThree" name="optionThree" id="option-3" value="3" required> <label for="option-3">Option 3</label></li>
</div>
<!--Want to know how to check if the checkbox is selected and pass the selected options to the method-->
<button type="button" (click)="saveOptions();">Submit</button>
</ul>
</form>
https://stackblitz.com/edit/angular-j5idkn?file=src%2Fapp%2Fapp.component.ts
I am just gonna extend ganesh's answer here!
Component.html
<form #form="ngForm">
<ul class="option-row">
<div *ngFor="let li of listedValue; index as i" class="option-group">
<li><input type="checkbox" id="option-{{li}}" [value]="l" required (click)="setCheckbox(li, i)"> <label for="option-{{li}}">Option {{ i }}</label></li>
</div>
button type="button" (click)="saveOptions();">Submit</button>
</ul>
</form>
component.ts
name = 'Angular 5';
listedValue: any = [0, 1, 2];
options: any = []
ngOnInit(){}
setCheckbox(event: any, index: number) {
if(!this.options.includes(event)){
this.options = [...this.options, event];
}else {
this.options = this.options.filter((item) => item !== event);
}
}
saveOptions() {
console.log(this.options);
}
StackBlitz
you can this in dynamic way with the help of ngFor and [value] of the div element.
use an array for your li elements, modify your template and component some thing like below.
Component.html
<ul class="option-row">
<div *ngFor="let li of listedValue" class="option-group">
<li><input type="checkbox" id="option-{{li}}" [value]="l" required (click)="setCheckbox($event,li)"> <label for="option-{{li}}">Option 1</label></li>
</div>
<!--Want to know how to check if the checkbox is selected and pass the selected options to the method-->
<button type="button" (click)="saveOptions();">Submit</button>
</ul>
Component.ts
name = 'Angular 5';
listedValue: any = [1, 2, 3];
options: any = []
setCheckbox(event: any,value: any) {
if (event.target.checked)
this.options.push(value)
else
this.options= this.options.filter(val => val != value);
}
saveOptions() {
console.log(this.options);
}
I have created a stackblitz for your case check it once. I hope this will solve your issue :)
i think you can use form control reactive form it will help you
I am trying to compare values coming from database to the value I am entering on my angular 2 model driven form. I want to display a div when the values are not equal. I am trying the logic below but I am unable to make it work. Help will be appreciated.
View
<form [formGroup]="reguserform" #f="ngForm" (ngSubmit)="register()">
<fieldset>
<div class="form-group">
<label for="Username">Username</label>
<input class="form-control"
[(ngModel)]="user.Username"
type="text" id="Username"
formControlName="Username" />
</div>
<div class="alert alert-danger"
*ngIf="reguserform.controls.Username.touched && reguserform.controls.Username.errors">
<div *ngIf="reguserform.controls.Username.errors.required"
class="alert alert-danger">
Please enter a valid Username...
</div>
<div *ngFor="let r of rusers">
<div *ngIf="r.Username == user.Username" class="alert alert-danger">Username is taken</div>
</div>
</div>
</fieldset>
Component
getUsers() {
this.authenticationService.getRegUser().subscribe(
res => this.rusers = res
);
}
Everything is fine from the db end the object is being logged in console too but at the time of comparison no div is shown.
Your idea works in general, but that *ngIf="reguserform.controls.Username.touched && reguserform.controls.Username.errors" isn't true!
#Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<form [formGroup]="reguserform" #f="ngForm" (ngSubmit)="register()">
<fieldset>
<div class="form-group">
<label for="Username">Username</label>
<input class="form-control"
[(ngModel)]="user.Username"
type="text" id="Username"
formControlName="Username" />
</div>
<div class="alert alert-danger">
<div *ngFor="let r of rusers">
<div *ngIf="r.Username == user.Username" class="alert alert-danger">Username is taken</div>
</div>
</div>
</fieldset>
</form>
</div>
`,
})
export class App {
public reguserform: FormGroup; // our model driven form
user = {};
rusers = [
{ Username: 'mxii' },
{ Username: 'test' },
{ Username: 'peter' }
];
constructor(private _fb: FormBuilder) {
this.name = 'Angular2'
}
ngOnInit() {
this.reguserform = this._fb.group({
Username: ['', [<any>Validators.required, <any>Validators.minLength(1)]]
});
}
}
See my live-demo: https://plnkr.co/edit/SnHfoAL2dnuwKkrFYGzE?p=preview
When you write res => this.rusers = res I guess you put the http response in your variable. It's not an iterable object. Maybe you need to write this :
getUsers() {
this.rusers = this.authenticationService.getRegUser().map(
res => res.json()
);
}
The following form shows a list of data on submit. I am trying to show no results found when there is no data on submit. I tried like shown below,it shows and hides the div. But when there is no options selected on form and click submit button it shows the no result div.How to show the no results div only when form validation succeeds and there is no data to display.
HTML
<div class="form-group" >
<label class="radio-inline">
<input name="sampleinlineradio" value="3" type="radio" ng-model="radioption"
ng-required="!radioption"> MAIN 1</label>
<label class="radio-inline">
<input name="sampleinlineradio" value="1" type="radio" ng-model="radioption" >
Main 2</label>
<div ng-show="!radioption && buttonClicked">Please select one.</div>
</div>
<div class="form-group">
<label ng-repeat="branch in branches">
<input type="checkbox" name="selectedBranches[]" value="{{branch.value}}"
ng-model="branch.selected" ng-required="isOptionsRequired()" >
{{branch.name}}</label>
<div ng-show="isOptionsRequired() && buttonClicked">Please select one.</div>
</div>
<input type="button" ng-click="fetchresults()" value="submit" >
<div ng-show="buttonClicked">
<table> <thead>.....</thead>
<tbody>
<tr ng-show="results.length!=0" ng-repeat="r in results">
<td></td></tbody></table>
</div>
<div ng-show="buttonClicked">
<span ng-show="results.length==0 ">No results.</span>
</div>
Minimal Controller Code
$scope.fetchresults = function(){
$scope.results = Result.query({main: $scope.radioption, branch: $scope.selection[0], });
$scope.buttonClicked = true;
}
EDIT:
I used model to validate and $valid is also working, as suggested below.But Got a couple of glitches. If i click the button it does not show div. but after validation is over it shows automatically "no results" from the click before. How to stop this.And while it lists data when its available it shows "no results" for a second or so
Give your form a name
<form name="formName">
Then you can do
ng-show="results.length==0 && formName.$valid"
Some more information on angularJS form validation
You can check the below snippet, I have changed most of them in angular way with $invalid, $pristine, $submitted and $valid.
You can check the angular documentation to read about them.
Link 1, Link 2
Note: You can use a submit button and get rid of ng-click event and use ng-submit instead which can't be used in this snippet as form submit is not allowed. Comment the line form.$submitted = true; when you use a submit button.
var app = angular.module('app', []);
app.controller('TestController', function($scope){
$scope.isFieldInvalid = function(field) {
var form = $scope.testForm;
return form[field].$invalid && (!form[field].$pristine || form.$submitted);
};
$scope.fetchResults = function(){
var form = $scope.testForm;
form.$submitted = true; // comment this line if button type="submit"
if(form.$valid){
$scope.searching = true;
$scope.results = [];
var rnd = Math.random();
if(rnd >= 0.5) {
$scope.results = [{id: 1}, {id: 2}];
}
//$scope.results = Result.query({main: $scope.radioption, branch: $scope.selection[0], });
$scope.buttonClicked = true;
$scope.searching = false;
}
};
});
angular.bootstrap(document, ['app']);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form name="testForm" ng-controller="TestController" ng-submit="fetchResults()" role="form" novalidate="">
<div class="form-group" ng-controller="TestController">
<label class="radio-inline">
<input name="sampleinlineradio" value="3" type="radio" ng-model="radioption" ng-required="true"> MAIN 1</label>
<label class="radio-inline">
<input name="sampleinlineradio" value="1" type="radio" ng-model="radioption" ng-required="true" >
Main 2</label>
<div ng-show="isFieldInvalid('sampleinlineradio')">Please select one.</div>
</div>
<div class="form-group">
<label ng-repeat="branch in branches">
<input type="checkbox" name="selectedBranches[]" value="{{branch.value}}"
ng-model="branch.selected" ng-required="isOptionsRequired()" >
{{branch.name}}</label>
<div ng-show="isOptionsRequired() && buttonClicked">Please select one.</div>
</div>
<input type="button" value="submit" ng-click="fetchResults()" >
<div ng-show="buttonClicked && !searching">
<table> <thead></thead>
<tbody>
<tr ng-show="results.length!=0" ng-repeat="r in results">
<td>{{r.id}}</td></tbody></table>
</div>
<div ng-show="buttonClicked && !searching">
<span ng-show="results.length==0 ">No results.</span>
</div>
</form>