Home > Mobile >  Push only checked and not duplicated checkbox values to an array in Angular?
Push only checked and not duplicated checkbox values to an array in Angular?

Time:02-18

I have three checkboxes and I want to create an array which should have the values of the checked checkboxes values and should avoid pushing duplicating values.

This is what I have tried but values are pushing even though it is checked or not.

Can someone let me know what is the issue here?

.ts

public dataSource: any[] = [];

compsForm: FormGroup = new FormGroup({

  dataSource: new FormControl('', Validators.required),
  name: new FormControl('',Validators.required),
});
    dataSourceChange(event:any){
    
        var name = event.target.name;
        var isChecked = event.target.checked;
        const index = this.dataSource.findIndex((el) => el.id === name);
    
        if (index > -1) {
          this.dataSource[index].isChecked = isChecked;
        } else {
          this.dataSource.push(name);
        }
        this.dataSource = [...this.dataSource];
        console.log(this.dataSource);
      }

.html

<form [formGroup]="compsForm">
     <input type="checkbox" name="om" (change)="dataSourceChange($event)" formControlName = "dataSource"> <span> OM</span>
     <input type="checkbox" name="fe" (change)="dataSourceChange($event)" formControlName = "dataSource"> <span> FE</span>
     <input type="checkbox" name="be" (change)="dataSourceChange($event)" formControlName = "dataSource"> <span> BE </span>
</form>

CodePudding user response:

the idea is from this SO (the part of the simple e.g. with a variable). You simply change the variable "answer" by the formControl.

<div *ngFor="let option of options">
  <input
    #check
    type="checkbox"
    [checked]="compsForm.get('dataSource').value &&
               compsForm.get('dataSource').value.indexOf(option) >= 0"
    (change)="onChange(option, check.checked)"
  />

  {{ option }}
</div>

  options=["check 1","check 2","check3"]
  compsForm: FormGroup = new FormGroup({

    dataSource: new FormControl('', Validators.required),
    name: new FormControl('',Validators.required),
  });
  onChange(option:string,checked:boolean)
  {
     let answer=this.compsForm.get('dataSource').value;
     if (checked && answer.indexOf(option)<0)
     {
         answer=[...answer,option]
         .sort((a,b)=>this.options.indexOf(a)>this.options.indexOf(b)?1:-1)
         //we can also not sort the array
         //answer=[...answer,option]
     }

    if (!checked)
          answer=answer.filter(x=>x!=option)

    this.compsForm.get('dataSource').setValue(answer.length?answer:null)
  }

the stackblitz

NOTE: If you want simply the code you can use a getter

get dataSourceValue(){
   return this.compsForm.get('dataSource').value
}

CodePudding user response:

Some things to consider:

The formGroup in your ts should match the "shape" of the form in the html. If the html form has 3 inputs then so should the formGroup. The html should have different names on each input.

You were only pushing elements in your array and not removing them when unchecked so the array will just keep getting bigger.

When you're worried about duplicate entries it is often better to work with a "Set" and the convert the set to an array when you have done all your work.

CHeck out this SO answer: HashSet Explanation

.html

    <form [formGroup]="compsForm">
  <input
    type="checkbox"
    name="om"
    (change)="dataSourceChange($event)"
    formControlName="dataSource1"
  />
  <span> OM</span>
  <input
    type="checkbox"
    name="fe"
    (change)="dataSourceChange($event)"
    formControlName="dataSource2"
  />
  <span> FE</span>
  <input
    type="checkbox"
    name="be"
    (change)="dataSourceChange($event)"
    formControlName="dataSource3"
  />
  <span> BE </span>
</form>

.ts

     // private _dataSource: any[] = [];
  private _dataSet: Set<string> = new Set<string>();
  private _dataArray = [];

  compsForm: FormGroup = new FormGroup({
    dataSource1: new FormControl(''),
    dataSource2: new FormControl(''),
    dataSource3: new FormControl(''),
  });

  dataSourceChange(event: any) {
    console.log(event.target.name);

    const name = event.target.name;
    const isChecked = event.target.checked;

    if (isChecked) this._dataSet.add(name);
    else this._dataSet.delete(name);

    this._dataArray = Array.from(this._dataSet);
    console.log(this._dataArray);
  }
  • Related