'Changing status of checkbox on the basis of user action

I am working on angular app. I am using primeng carousel in my app. My code is as follows:

<p-carousel
  [value]="products"
  [numVisible]="3"
  [numScroll]="3"
  [circular]="false"
  [responsiveOptions]="responsiveOptions"
>
  <ng-template pTemplate="header">
    <h5>Basic</h5>
  </ng-template>
  <ng-template let-product let-i="index" pTemplate="item">
    <div class="product-item">
      <div class="product-item-content">
        <div class="p-mb-3"></div>
        <div>
          <p>{{ product.id }}</p>
          <h4 class="p-mb-1">{{ product.name }}</h4>
          <h6 class="p-mt-0 p-mb-3">${{ product.price }}</h6>
          <span
            [class]="
              'product-badge status-' + product.inventoryStatus.toLowerCase()
            "
            >{{ product.inventoryStatus }}</span
          >
          <div class="car-buttons p-mt-5">
            <p-button
              type="button"
              styleClass="p-button p-button-rounded p-mr-2"
              icon="pi pi-search"
            ></p-button>
            <p-button
              type="button"
              styleClass="p-button-success p-button-rounded p-mr-2"
              icon="pi pi-star"
            ></p-button>
            <p-button
              type="button"
              styleClass="p-button-help p-button-rounded"
              icon="pi pi-cog"
            ></p-button>
          </div>
        </div>
      </div>

      <div
        *ngFor="let cityData of myData; let i = index"
        style="position: relative;margin-top: 2rem;border-bottom: 1px solid #4E5668;"
      >
        <div style="display: flex; margin:1em; ">
          <span style="flex:1;">{{ cityData.name }}</span>
          <span style="flex:1;">
            <p-checkbox
              name="product"
              [value]="cityData.id"
              (onChange)="toggleVisibility($event, cityData, product)"
              #checkbox
            ></p-checkbox>
          </span>
        </div>
      </div>
    </div>
  </ng-template>
</p-carousel>

Stackblitz:

https://stackblitz.com/edit/primeng-carousel-demo-fjw4ap?file=src%2Fapp%2Fapp.component.ts

In this carousel I have some checkboxes as shown in stackblitz. My array is as follows -

  myData = [
    {
      myid: 1,
      name: 'paris',
      status: [
        {
          id: 1000,
          active: 1,
        },
        {
          id: 1001,
          active: 1,
        },
      ],
    },
    {
      myid: 2,
      name: 'London',
      status: [
        {
          id: 1003,
          active: 1,
        },
        {
          id: 1004,
          active: 1,
        },
      ],
    },
  ]; 

In this array I have a status array under each city. id is product id. If active value is 1,then I want to mark that checkbox as checked when the page loads. For example in above array, Paris is the city and status with id 1001 and 1002 has active value as 1. So when my page loads, these checkboxes should be checked. In case if user decides to uncheck them then value of active should be set as 0. In case if user decides to check any other product, then a new element with product id and active as 1 will be added to status array. How can I do this?



Solution 1:[1]

In order achieve what you are trying to do, you have understand how prime chechbox detects your selection to toggle the check mark, read more about it here. PrimeNg compares the value with the ngModel it's binded to. You didn't specify any ngModel in the first place. Secondly, the active field is two level deep in your array, myData > city.status > active. So you also need to run the ngFor twice, or flatten the array, so that only one ngFor can run on it. Also, you need to bind with the whole status object, because active field itself is not a unique identified.

I have modified your stackblitz to demo all the changes I mentioned above.

https://stackblitz.com/edit/primeng-carousel-demo-kysr1x?file=src%2Fapp%2Fapp.component.ts

Code Summary:

component.ts:

...
...
selectedValues = []; // ngModel binding
...
...

ngOnInit() {
    // creates intial selection for ngModel binding
    this.populateSelectedData();
...
}

...
...
populateSelectedData() {
    this.myData.forEach(city => {
      city.status.forEach(status => {
        if (status.active ===1) {
          this.selectedValues.push(status);
        }
      })
    })
  }

html:

...
...
<div *ngFor="let status of cityData.status">
          <div style="display: flex; margin:1em; ">
            <span style="flex:1;">{{ cityData.name }}</span>
            <span style="flex:1;">
              <p-checkbox
                name="product"
                [value]="status"
                [(ngModel)]="selectedValues"
                (onChange)="toggleVisibility($event, cityData, product, status)"
                #checkbox
              ></p-checkbox>
            </span>
          </div>
        </div>
    ...
    ...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nehal