2

I have a edit profile form. for has dynamic checkbox. if user updated the check box once then it should checked default.

Here is my ts file...

import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { ApplicantsService } from '@app/services/applicants.service';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {

  myForm: FormGroup;
  submitted = false;
 
  userid: any;
  
  skills: any;
  experience: any;
  applicant_skills: any;
  profile: any;
  states: any;
  cities: any;
  profilePicture: any;

  constructor(
    private formBuilder: FormBuilder,
    private applicantsService: ApplicantsService,
  ) { }

  ngOnInit(): void {
    
    this.userid = JSON.parse(localStorage.getItem('currentUser')).user_id;

    this.myForm = this.formBuilder.group({
      userid: [''],
      first_name: new FormControl({value: null, disabled: true}, Validators.required),
      last_name: new FormControl({value: null, disabled: true}, Validators.required),
      email: new FormControl({value: null, disabled: true}, Validators.required),
      mobile: ['', Validators.required],
      state: ['', Validators.required],
      city: ['', Validators.required],
      skills: this.formBuilder.array([], [Validators.required]),
    });
    
    this.applicantsService.getProfile(this.userid).subscribe( res => {
      this.profile = res.data[0];
      this.myForm.patchValue(this.profile); 
    })

    this.applicantsService.getApplicantskills(this.userid).subscribe( res => 
    {
      if(res && res.data)
      {
        this.applicant_skills = res.data;
        
        
      }
    })


  }


  // convenience getter for easy access to form fields
  get f() { return this.myForm.controls; }

 


  onCheckboxChange(e) {
    const checkArray: FormArray = this.myForm.get('skills') as FormArray;

    if (e.target.checked) {
      checkArray.push(new FormControl(e.target.value));
    } else {
      let i: number = 0;
      checkArray.controls.forEach((item: FormControl) => {
        if (item.value == e.target.value) {
          checkArray.removeAt(i);
          return;
        }
        i++;
      });
    }
  }

  onSubmit()
  {
      this.submitted = true;

      // stop here if form is invalid
      if (this.myForm.invalid) {
        console.log(this.myForm)
        return;
      }

      console.log("this.myForm.value", this.myForm.value);
      
  }

}

Here is my html page.

<!-- Spinner -->
<ngx-spinner></ngx-spinner>

<section id="profile-form" class="bg-grey">
    <div class="container">
      <div class="row justify-content-center">
        <div class="col-lg-10 col-md-12">
          
          <h1 class="text-center">Update your profile</h1>

          <div class="form p-md-6">

              
              <form  [formGroup]="myForm" (ngSubmit)="onSubmit()">

                <div class="form-row">
                    <div class="form-group d-none">
                        <input type="text"  formControlName="userid" value={{userid}}>
                    </div>
                    <div class="form-group col-md-6">
                        <label for="linkedin">First Name</label>
                        <input type="text" class="form-control" formControlName="first_name" placeholder="First Name">
                    </div>
                    <div class="form-group col-md-6">
                        <label for="lastname">Last Name</label>
                        <input type="text" class="form-control" formControlName="last_name" placeholder="Last Name">
                    </div>
                </div>

                <div class="form-row">
                    <div class="form-group col-md-6">
                        <label for="linkedin">Email ID</label>
                        <input type="email" class="form-control" formControlName="email" placeholder="Email ID">
                    </div>
                    <div class="form-group col-md-6">
                        <label for="lastname">Cellphone Number</label>
                        <input type="text" class="form-control" formControlName="mobile" placeholder="Cellphone Number" [ngClass]="{ 'is-invalid': submitted && f.mobile.errors }" required>
                        <div *ngIf="submitted && f.mobile.errors" class="invalid-feedback">
                            <div *ngIf="f.mobile.errors.required">This field is required</div>
                        </div>
                    </div>
                </div>

                

                  
                  <div class="form-row">
                      <div class="button-group-pills text-center col-md-12" data-toggle="buttons">

                        <label class="btn btn-default" *ngFor="let skill of skills">
                            <input type="checkbox" formArrayName="skills" (change)="onCheckboxChange($event)" value={{skill.id}} [ngClass]="{ 'is-invalid': submitted && f.skills.errors }" required>
                            <div>{{skill.skill}}</div>
                        </label>
                        <div *ngIf="submitted && f.skills.errors" class="error">
                            <div *ngIf="f.skills.errors.required">This field is required</div>
                        </div>
                      </div>
                      
                  </div>



                  <div class="form-row justify-content-center text-center pt-4 pb-2">
                      <div class="col-md-8">
                          <button type="submit" class="btn btn-apply px-4">save profile</button>
                      </div>
                  </div>
              </form>
          </div>
              
        </div>

      </div>
    </div>
  </section>

Please help .........................................................................................................................................................................................................................................................................

2 Answers 2

2

You toggle [checked] value by checking if the current value is in the checkArray array

Include this in your input field

[checked]="checkArray.includes(skill.id)"

So your input becomes

    <input type="checkbox" formArrayName="skills" (change)="onCheckboxChange($event)" [checked]="checkArray.includes(skill.id)
 value={{skill.id}} [ngClass]="{ 'is-invalid': submitted && f.skills.errors }" required>

UPDATE

The above would work if you're pushing only the id of the skill into the array. But since you are pushing the entire skill object you can check for the object instead.

[checked]="checkArray.includes(skill)"

   <input type="checkbox" formArrayName="skills" (change)="onCheckboxChange($event)" [checked]="checkArray.includes(skill)
 value={{skill.id}} [ngClass]="{ 'is-invalid': submitted && f.skills.errors }" required>
Sign up to request clarification or add additional context in comments.

4 Comments

not working... My checkArray structure is look like this, ` CheckedArray = [ 0: { id: 1, skill: "item1" }, 1: { id: 2, skill: "item2" }, ] `
I have updated the answer to suit your condition. Let me if that works, if it doesn't I can show you a solution using pipe instead. Cheers
it's showing ERROR TypeError: Cannot read property 'includes' of undefined
Oh I see that your array variable is static and is cleared every time you the check box changes. You can declare checkArray before the constructor like so checkArray: any = [] and then in your onCheckboxChange(e) func then call this.checkArray instead of declaring a const checkArray. Let me know if this is clear
1

Sadique, I suppose you want that your "skills" was an array of values. I don't find the SO where I used ngModel inside a ReactiveForms to mannage a list of checkBox. The most closer is this another SO

The idea is that you has NOT a FormArray, just a FormControl, and you use [(ngModel)] to give value to the formControl. yes a FormControl can store an Array, and yes a FormControl exist even you has no input in .html

    <label class="btn btn-default" *ngFor="let skill of skills">
       <input type="checkbox" 
          [ngModelOptions]="{standalone:true}"
          <!--see that "is checked" if in the array you has the value-->
          [ngModel]="(myForm.get('skills').value || []).indexOf(skill.id)>=0" 
          <!--when change, we call to the function-->
          (ngModelChange)="onChange($event,skill.id)" >
           <div>{{skill.skill}}</div>
    </label>

And

  onChange(checked: boolean, id: number) {
    
    const control = this.myForm.get("skills"); //get the control
    let value = control.value || [];       //get the value, if null an empty array
    if (checked && value.indexOf(id) < 0)  //if we checked and it's not in the array
      value = [...value, id].sort((a, b) =>    //concatenate the value and sort
        this.skills.findIndex(f => f.id == a) >
        this.skills.findIndex(f => f.id == b)? 1: -1
      );
    if (!checked) value = value.filter(x => x != id);  //if not checked remove it

    control.setValue(value.length ? value : null);  //finally set value
                          //see that is nothing selected, give value null
                          //this make that we can use Validators.required
  }

See the stackblitz

2 Comments

Thanks for your answer... My actual issue is, I have to make my checkboxes as checked dynamically... If anyone selected 2 items and saved, then it should checked all time... I expecting you got issue.. Thanks
when you create the Control you can give value, e.g. myForm.get('skills').setValue([1,3]), or when you create the form control:myForm=new FormGroup({skill:new FormControl([1],Validators.required}). If in your "profile" the value of "skills" is an array, should work your this.myForm.patchValue(this.profile); what's the value or your "profile"?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.