Validation not working for checkbox in angular - html

Validation not working for checkbox.
When checkbox is not selected, form is getting submitted. Also not showing error.
HTML Code
<form [formGroup]="feedbackFormWithArray" (ngSubmit)="submitData()">
<label class="form-control-label"><span class="text-danger">*</span>Recommendation:</label>
<div class="recommendation-div">
<div class="rec-div" *ngFor="let recommendation of recommendations">
<label class="container">{{recommendation.listTypeValueName}}
<input formControlName="recommendation" type="checkbox" value="{{recommendation.listTypeValueId}}"
[checked]="recommendation.selected" (change)="isAllSelected(recommendation)" />
<span class="mark"></span>
</label>
<div *ngIf="(submitted && recommendation.invalid)">
<small *ngIf="recommendation.errors?.required" class="text-danger">Please select recommendation</small>
</div>
</div>
</div>
</form>
TS Code
import { Validators } from '#angular/forms';
submitted : boolean = false;
this.feedbackFormWithArray= this.fb.group({
recommendation: ['', [Validators.required]]
});
submitData() {
this.submitted = true;
}
get recommendation()
{
return this.feedbackFormWithArray.get('recommendation');
}
How to solve this?
Thank you!

I think replace feedbackForm with feedbackFormWithArray in 3 rd line of ts code

import { Validators } from '#angular/forms';
submitted : boolean = false;
//in reactive form you should take care the form controller's name.
this.feedbackFormWithArray= this.fb.group({
recommendation: ['', [Validators.required]]
});
submitData() {
this.submitted = true;
}
get recommendation()
{
return this.feedbackFormWithArray.get('recommendation');
}

There is a static property in class Validators called "requiredTrue".
this.feedbackFormWithArray= this.fb.group({
recommendation: ['', [Validators.requiredTrue]]
});
#description
Validator that requires the control's value be true. This validator is commonly used for required checkboxes.
You can check more about it here https://angular.io/api/forms/Validators

Related

How to do checked checkbox from formarray in angular 8 on specific condition

I am sharing my code as I am trying to show list of items in form of checkboxes and on dropdown selection it check for certain condition if it matched then, checkbox should be checked dynamically. I have tried number of options but unable to succeed.
HTML code : here showing list of items in form of checkboxes. On dropdown selection it should show list of privileges given to all roles in common and show checkboxes checked for privileges given to the selected role
<nz-card>
<div class="row">
<div>
<label><h5>Role List</h5></label>
</div>
<div>
<nz-select
nzPlaceHolder="Select Role"
[nzShowArrow]="true"
[(ngModel)]="chosenRole"
(ngModelChange)="onselectRole($event)"
name="selectRole" style="max-width: 500px;">
<nz-option *ngFor="let s of roleList" [nzValue]="s.roleid" [nzLabel]="s.name"></nz-option>
</nz-select>
</div>
</div>
<br/><br/>
<div class="row" *ngIf="showPrivleges">
<form [formGroup]="privilegeform" (ngSubmit)="updatePrivleges()">
<div class="col-md-2" >
<label><h5>Privilege List</h5></label>
</div>
<div formArrayName="privileges" *ngFor="let privilege of getformArray().controls; let i = index" >
<div>
<label>
<input type="checkbox"
[formControlName]="i" />
{{privilegeList[i].name}}
</label></div>
</div>
<br/>
</div>
<button nz-button nzType="primary" nzBlock>Update</button>
</form>
</div>
</nz-card>
typescript code : here fetching data from api and checking for condition on selected option from dropdown menu , If condition matched it should do checked on particular checkbox with index in formarray
constructor(private fb : FormBuilder,private roleprisrv: AuthenticationRoleService, private modalService: NzModalService, private message: NzMessageService)
{
this.privilegeform = this.fb.group({
privileges: []
});
}
ngOnInit() : void {
//Load Role List
this.roleprisrv.getRoleList().subscribe(data =>{
this.roleList = data;
});
//Load Privilege List
this.roleprisrv.getPrivilegeList().subscribe(data =>{
this.privilegeList = data;
this.privilegeform = this.fb.group({
privileges: new FormArray([])
});
this.addCheckboxes();
});
}
private addCheckboxes() {
this.privilegeList.forEach(() => this.getformArray().push(new FormControl(false)));
}
getformArray() : FormArray {
return this.privilegeform.controls.privileges as FormArray;
}
onselectRole(id:String)
{
this.chosenRole=id;
this.roleprisrv.getRolePrivlegeList(id).subscribe(rolePrivList =>{
var rolePrivListTemp : any= rolePrivList;
var privMap = this.privilegeform.value.privileges.map;
var privIndex = 0;
this.privilegeList.forEach(privelement => {
var status : boolean = false;
var privId = this.privilegeList[privIndex].privilegeid;
var privExist = false;
rolePrivListTemp.forEach(function(childObj: any){
if(privelement.privilegeid===childObj.privilegeid ){
privExist=true;
}
})
if(privExist){
this.privilegeform.value.privileges[privIndex] = true;
this.privilegeform.controls.privileges.value[privIndex];
}
privIndex++;
});
this.showPrivleges=true; //: TODO implement in front end
});
}
My problem is that I am unable to checked checkbox. I am doing but it is right way to do this
if(privExist)
{
this.privilegeform.value.privileges[privIndex] = true;
this.privilegeform.controls.privileges.value[privIndex];
}
I got solution for this issue I added this.getformArray().controls[privIndex].setValue(privExist); It bind to form array control. I added in this block rolePrivListTemp.forEach(function(childObj: any){ if(privelement.privilegeid===childObj.privilegeid ){ privExist=true; } }) this.getformArray().controls[privIndex].setValue(privExist);

Input fields as lists in Angular

I want to take inputs from the user and append them to a list I have in my typescript. Here's what I have tried so far.
Here's the code:
<input type="text" id="course" name="course" class="form-control"[(ngModel)]="institutes.course">
institutes={course:''}
Use a function to add a new course and trigger it using a button.
app.component.html :
<!-- Input field -->
<input type="text" id="course" name="course" class="form-control" [(ngModel)]="newCourse">
<!-- Add button -->
<button (click)="addCourse()">Add</button>
app.component.ts :
newCourse : string = '';
allCourses : string[] = [];
// Function to add course
addCourse(){
this.allCourses.push(this.newCourse);
//Reset input
this.newCourse = '';
}
Demo : https://stackblitz.com/edit/angular-hzh42b
Write the following method in your component -
constructor(private url: string, private http: HttpClient) {}
posts: any;
createPost(input: HTMLInputElement) {
const post = { title: input.value };
this.posts.splice(0, 0, post);
input.value = "";
this.service.create(post).subscribe(
newPost => {
post.id = newPost;
},
(error: AppError) => {
this.posts.splice(0, 1);
if (error instanceof BadInput) {
// this.form.setErrors(error.originalError);
} else {
throw error;
}
}
);
}
Include this method in your service -
constructor(private url: string, private http: HttpClient) {}
create(resource) {
return this.http.post(this.url, JSON.stringify(resource)).pipe(
map(response => response),
catchError(this.handleError)
);
}
write the following code in your HTML -
<input
(keyup.enter)="createPost(title)"
#title
type="text"
class="form-control"
/>
You are good to go now!
The following code will help you to add a course into a list, which will be displayed in the web page.
.ts
courseList contains a list of all the added courses
course is the current course that you are adding.
addCourse is a method which will add a course into the list, and clear the course string.
public courseList = [];
public course;
addCourse() {
this.courseList.push(this.course);
console.log(this.courseList);
this.course = '';
}
.html
There is an input field which will take in course name.
And an add course button which will add the entered course name into the list and display the course list in the web page.
<ul>
<li *ngFor="let course of courseList">
{{course}}
</li>
</ul>
<input type="text" id="course" name="course" class="form-control" [(ngModel)]="course">
<button (click)="addCourse()">Add Course</button>

Reactive form with dynamic data change from component

I am setting up a reactive form in angular 6, where I have 2 input boxes(one input is an optional entry) and a submit button. If I enter a value to one input box and press submit, I need to fill the other input box by setting corresponding value from component side. If I enter values to both input boxes, then another function is called. If so how is two-way data bindin possible in form controls? I tried using ngModel, which is not working as expected and from stackoverflow answers, came to know that using ngmodel with form controls is soon to be deprecated. How Can I achieve the same if so? Below is the code snippet I am using:
Component.ts:
export class myComponent implements OnInit {
converterForm: FormGroup;
model: myModel = new MyModel();
constructor(private formBuilder: FormBuilder, ) {
this.myForm = this.formBuilder.group({
vOne: [this.model.vOne],
vTwo: [this.model.vTwo],
});
}
onSubmit(searchInputs) {
this.model.vTwo= "new"; //I need to edit the form value and reflect it in html.. two-waybinding
this.converterForm.value.vOne = "edited";
console.log("Submit called");
}
}
html file:
<div>
<div>
<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm.value)">
<div>
<div>
<mat-form-field>
<input id="vOne" matInput formControlName="vOne" [(ngModel)]="model.vOne">
</mat-form-field>
</div>
<div>
<mat-form-field>
<input id="vTwo" matInput formControlName="vTwo" [(ngModel)]="model.vTwo">
</mat-form-field>
</div>
</div>
<div>
<button mat-raised-button color="primary" type="submit" (click)="search()">
<mat-icon aria-label="Search icon">search </mat-icon>
Search
</button>
</div>
</form>
</div>
thanks in advance.
Using valueChanges for access to live changes, and using setValue func for setting value per input.
in ts file try:
export class myComponent implements OnInit {
myForm: FormGroup;
constructor(private formBuilder: FormBuilder) {
this.myForm = this.formBuilder.group({
vOne: [null],
vTwo: [null],
});
searchHandler();
}
searchHandler() {
const searchInputs = {
vOne: '',
vTwo: '',
};
for (const propertyName in searchInputs) {
const property = this.form.get(propertyName);
property.valueChanges
.subscribe((searchText) => {
// this.form.controls.vOne.setValue('whatever');
// this.form.controls.vTwo.setValue('whatever');
// searchText is what keypress in input tag
});
}
}
onSubmit() {
// this.form.controls.vOne.setValue('whatever');
// this.form.controls.vTwo.setValue('whatever');
}
}
in html file try:
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<div>
<mat-form-field>
<input matInput formControlName="vOne">
</mat-form-field>
</div>
<div>
<mat-form-field>
<input matInput formControlName="vTwo">
</mat-form-field>
</div>
</form>

How to force validation for disabled property?

I have a form element as follows:
<input type="text" id="country" formControlName="Country" />
I have form group as follows:
this.myForm = this.formbuilder.group({
'Country': [{ value: this.user.Country, disabled: this.SomeProperty===true}, [Validators.required]],
});
When it is disabled when this.SomeProperty is true, required validator does not work at all and Save button is enabled.
<button type="submit" [disabled]="!myForm.valid">Save</button>
Is there anyway to force validation for disabled attribute?
The reason the required property can be null is because of some data issue or data got migrated from different source without the required values which is beyond my control.
Hmmm.. Generally, Angular Reactive Forms will not trigger validators for disabled form fields.
I can suggest two ways for you to get around this situation:
1) Writing a custom validator on your FormGroup to manually check the values for each individual Form Control.
this.myForm = this.formbuilder.group({
'Country': [{ value: this.user.Country, disabled: this.SomeProperty===true}, [Validators.required]],
// other FormControls
}, { validator: GroupValidator.checkEveryField() });
Then, create a new Validator class that checks for an empty Country FormControl. If it is empty, it will return the validation error.
import { AbstractControl } from '#angular/forms';
export class GroupValidator {
static checkEveryField(control: AbstractControl) {
const { Country } = control.value;
if (!Country) {
return { 'invalidCountry': true };
} else {
return null;
}
}
}
2) Writing a method that checks the values of the incoming data before you patch the values to your FormGroup.
this.someService.getData().subscribe(response => {
if (!response.user.Country) {
// trigger invalid validation response
} else {
this.myForm.patchVaue(response.user);
}
});

Angular Radio Buttons form with unknown number of elements

I am new to Angular and I have an issue with the radio buttons.
I have an array of strings which I want to use to create a form with radio buttons. I do not know the length or the content of the array - the values are taken from an external service.
How can I do this using a form builder in my Angular Component and in html file? Can it be something like this?
question-dto.ts
export class QuestionDto {
questionText: string;
questionOptions: string[];
}
quiz.component.ts
question: QuestionDto = new QuestionDto();
questionOptionsForm: any;
constructor(private quizService: QuizService,
private formBuilder: FormBuilder) { }
ngOnInit() {
this.initForm();
}
initForm() {
this.questionOptionsForm = this.formBuilder.group({
//INIT RADIO BUTTONS HERE
})
}
quiz.component.html
<div>
<p>
Answers
</p>
<form *ngIf="questionOptionsForm">
<div *ngFor="let option of question.questionOptions">
<label>
<input type="radio" class="form-control">
{{option}}
</label>
</div>
</form>
</div>
You should try FormArray https://alligator.io/angular/reactive-forms-formarray-dynamic-fields/
code would look like:
initForm() {
this.questionOptionsForm = this.formBuilder.group({
options: this.formBuilder.array([this.createOption()])
});
}
createOption():FormGroup {
return this.formBuilder.group({
name: '',
description: ''
});
}