Zahid Hussain
Zahid Hussain

Reputation: 1121

How to handle multiple checkboxes with angular reactive forms

I am having data related to cars coming from an API call which I am displaying in angular ag-grid. I have some default and some customized options which user can select of his own choice. I also need to provide user an option to select the customized option. I am giving user an edit option inside the ag-grid if he clicks on edit one mat-dialog will open up with all customized options with checkbox user can select the option by clicking on the checkbox. if user next time try to edit the customized option the previously selected option checkbox should be checked so that user can know what options he has already selected.

I am facing issue in showing the already selected option as checked, Could anyone please tell me how can I achieve this. I have replicated the same scenario under this link

https://stackblitz.com/edit/ag-grid-with-edit-funcion?file=src%2Fapp%2Fapp.component.ts

I am using below data to display in ag-grid row if a user selects edit of first row the engine and seat-covers checkbox should be automatically selected .

{
  no: 1,
  make: "Toyota",
  model: "Celica",
  price: 35000,
  fields: ["engine", "seat-covers"]
},
{
  no: 2,
  make: "Ford",
  model: "Mondeo",
  price: 32000,
  fields: ["engine", "body-material", "seat-covers"]
},
{
  no: 3,
  make: "Porsche",
  model: "Boxter",
  price: 72000,
  fields: ["engine", "body-material", "seat-covers"]
}

Upvotes: 1

Views: 1153

Answers (1)

Eliseo
Eliseo

Reputation: 57929

you need, when create the formArray use the value of this.data.selectedRow.fields

  buildTaskFields() {
    const arr = this.allColumns.map(element => {
      return this.fb.control(this.data.selectedRow.fields.indexOf(element)>=0);
    });
    return this.fb.array(arr);
  }

See that the formArray gets the values, e.g. [true,false,false,true]

In submitButton we form an array using the value of the formArray

  onSave() {
    const value=this.businessConfigForm.value.taskFieldsArray
    this.data.selectedRow.fields=this.allColumns.filter((x,index)=>value[index])
    this.dialogRef.close(null);
  }

See that, as we pass as data the object itself of the row, we can change in the dialog component and that we needn't mannage "change event" of the checks

Your forked stackblitz

NOTE: you can see another aproach to mannage a list of checkbox in this SO, in this case you needn't create a formArray, just use a variable array=[...this.data.selectedRow.fields] (you need make a copy)

Update if we want to add a new feature,

The first is that allColumns belong to the main component, so we need pass this array in data, so to edit

 this.dialog.open(AddConfigComponent, {
        const selectedRow = evt.data;
        data: {
          data: selectedRow,
          features:allColumns
        }

And in constructor

   if (data) {
      this.data = data.data;
      this.allColumns=data.features;
    }

Well, now to add a new characteristic again, as we pass the array itself, we can use in save

   this.data.push("another characteristic")
   this.dialogRef.close(null);

Updae 2 if ours characteristics are object type {name:...} and not only string, we need change a few the save and the buildEditTaskFields

  buildEditTaskFields() {
    const arr = this.allColumns.map(element => {
      //value becomes true if exist and object with name equal to the element
      //see how we use find
      const value=this.data.fields.find(f=>f.name==element)!=null;

      return this.fb.control(value);
    });
    return this.fb.array(arr);
  }

In save, after filter the array AllColumns, we "map" the array of string to an array of object, some like

  onSave() {
    const value = this.businessConfigForm.value.taskFieldsArray;
    //the filter makes, e.g. the result is ["engine", "body-material"]
    this.data.fields = this.allColumns.filter(
      (x, index) => value[index]
      //the map becomes to [{name:"engine"},{name:"body-material"}]
    ).map(x=>({name:x}));
    this.dialogRef.close(null);
  }

Upvotes: 1

Related Questions