0

need your help

I have an array of checkbox values

colors = ['Black', 'Red', 'White', 'Blue', 'Yellow', 'Grey'];

Implemented them in HTML

<div *ngFor="let color of colors; let i = index" class="checkbox">
        <label>
          <input type="checkbox" class="colors" [value]="color" (change)="addCheckboxData($event)" />
          {{ color }}
        </label>
      </div>

So it looks like this: enter image description here

I have an array of values that should be checked when I load the page

  checkedValues = ['Black', 'White', 'Grey'];

I added them to formarray

color: this._formBuilder.array(this.checkedValues),

It works and color formarray have values like in checkedValues array: enter image description here

But checkboxes are not checked so I want this values to be displayed as checked. How can I do this? Thank You

1 Answer 1

1

you need pass an array of booleans

color: this._formBuilder.array(
              this.colors.map(x=>this.checkedValues.indexOf(x)>=0)),

And manage the form like

<form [formGroup]="form">
    <input formControlName="name">
    <div formArrayName="color">
        <div *ngFor="let control of colorFormArray.controls;let i=index">
            <input type="checkbox" [formControlName]="i">{{colors[i]}}
      </div>
        </div>
</form>
<pre>
{{form?.value|json}}
</pre>

Well, you see that "color" get as value an array of booleans, e.g. [true,false,true,false,false,true]

And you want that color get an array with the colors, so the idea is has a formControl not a formArray and use [ngModel] and (ngModelChange). As we are using [ngModel] inside a FormGroup, we need use [ngModel]="{standalone:true}"

See the form and the .html

this.form2=this._formBuilder.group({
  name:[],
  color:[this.checkedValues] //<--see that is a simple FormControl
})

<form [formGroup]="form2">
        <div *ngFor="let col of colors;let i=index">
            <input type="checkbox" 
           [ngModel]="form2.get('color').value && form2.get('color').value.indexOf(col)>=0" 
           (ngModelChange)="colorChange($event,i)"
           [ngModelOptions]="{standalone:true}"
                 
      >{{colors[i]}}
        </div>
</form>

The [ngModel] is true or false according form2.get('color').value.indexOf

The function colorChange received the value of the checkbox and an index

  colorChange(checked:boolean,index:number)
  {
    const checkedColors=this.form2.get('color').value || [] //the actual value of the formControl
                                                            //if is null an empty array
    const color=this.colors[index];  //the color selected

    ///if is checked and is not in the array
    if (checked && checkedColors.indexOf(color)<0)
    {
      //concatenate to the value the new color
      //and sort the result array 

      const orderColors=[...checkedColors,color]
                  .sort((a,b)=>this.colors.indexOf(a)-this.colors.indexOf(b))

      //make a setValue
      this.form2.get('color').setValue(orderColors)
    }

    //if not checked

    if (!checked)
      this.form2.get('color').setValue(checkedColors.filter(x=>x!=color))

  }

In the stackblitz you has the two aproach

NOTE: In this secod aproach we can make that if there are no color select, the value of the control becomes null. This allow us use a Validators.required, e.g. The only is change the function colorChange

  colorChange(checked:boolean,index:number)
  {
        ...

    if (!checked)
    {
      const result=checkedColors.filter(x=>x!=color)
      this.form2.get('color').setValue(result.length>0?result:null)
    }

  }
Sign up to request clarification or add additional context in comments.

Comments

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.