Search code examples
angulartypescriptprimengprimeng-datatable

p-dataView Getting values of selected rows


Using primeNG p-dataview, I have a checkbox and a dropdown for every row. My goal is If I check the checkobox I want to get the value of the dropdon for the selected row (if selectd) same the other way around, If a user select a value from the dropdown I want to see if the checkbox was already checked for this raw. How can I accomplish this ?

HTML

<p-dataView [value]="iErsaDefaultApps" [paginator]="true" [rows]="20" [sortField]="sortField" [sortOrder]="sortOrder" paginatorPosition="both">
    <ng-template let-apps let-rowIndexValue="rowIndex" pTemplate="listItem">
    <div>
        <input type="checkbox" (click)="toggleSelectedApp($event)" id="defaultAppID" name="defaultApps" style="margin-right:5px;margin-bottom:10px;margin-left:5px; margin-top:10px" [value]='apps.app_id'> {{apps.app_name}}
    </div>
    <div>
        <select name="role" class="dropdown" style="width:60%" (ngModelChange)="selectedDefaultAppRole($event,rowIndex)" [(ngModel)]="selectedRole[rowIndex]" >
            <option class="dropdown-item" value="" selected>Select</option>
            <option class="dropdown-item" *ngFor='let role of apps.roles' [ngValue]="role.app_role_id">
                {{role.app_role_name}}
            </option>
        </select>
    </div>
    </ng-template>
</p-dataView>

TS

    selectedRole: any[] = []

    toggleSelectedApp(event: any)
    {
       //need to check the values of the drpown?
       console.log('checkbox' + event.srcElement.checked);
    }
}

selectedDefaultAppRole(event: any, index:any) {
    //also need to check th value of the checkbox
    console.log('selected defult dropdown ' + event);
    console.log('selected index ' + event);
  }

***********************************************************Update********************************************** 1) selectedDefaultAppRole will not know i the checkbox is checked or not 2) toggleSelectedApp will not know what drpdown value is selected HTML

<p-dataView [value]="iErsaDefaultApps" [paginator]="true" [rows]="20">
    <ng-template let-apps let-rowIndexValue="rowIndex" pTemplate="listItem">
        <div>
            <input type="checkbox" (click)="toggleSelectedApp($event, rowIndexValue)" id="defaultAppID" name="defaultApps"
                style="margin-right:5px;margin-bottom:10px;margin-left:5px; margin-top:10px" [value]='apps.app_id'> {{apps.app_name}}
        </div>
        <div>
            <select name="role" class="dropdown" style="width:60%" (ngModelChange)="selectedDefaultAppRole($event, rowIndexValue,apps.app_id)"
                [(ngModel)]="selectedRole[rowIndexValue]" >
                <option class="dropdown-item" value="" selected>Select</option>
                <option class="dropdown-item" *ngFor='let role of apps.roles' [ngValue]="role.app_role_id">
                    {{role.app_role_name}}
                </option>
            </select>
        </div>
    </ng-template>
</p-dataView>

TS 2 issues with

   toggleSelectedApp(event: any, rowIndexValue: any)
    {

                this.selectedObject = this.iErsaAppList
               .find(x => x.app_id == event.srcElement.value);

           const index: number = this.iErsaDefaultApps.indexOf(this.selectedObject);

                    const cApp = this.iErsaDefaultApps.filter(a => a.app_id === index);
               console.log('currentApp', cApp);

    }

   selectedDefaultAppRole(event: any, index: number,app_id:number) {
        console.log('selected app_id ' + app_id);

        const cApp = this.iErsaDefaultApps.filter(a => a.app_id == app_id);
            console.log('currentAppRole', cApp);
            console.log('currentAppRole', event);

    }

interface

export interface IErsaApps {

        app_id: number;
        app_type_id: number;
        app_name: string;
        app_roles: string;
        app_sort_id?: number;
       roles: Array<IErsaAppRoles>
}

export interface IErsaAppRoles {

    app_role_id: number;
    app_role_app_id: number;
    app_role_name: string;
    app_role_sort_id?: number;

}

Solution

  • Think about making these updates to your template:

    <p-dataView [value]="iErsaDefaultApps" [paginator]="true" [rows]="20">
      <ng-template let-apps let-rowIndexValue="rowIndex" pTemplate="listItem">
      <div>
          <input type="checkbox" (click)="toggleSelectedApp($event, rowIndexValue)" id="defaultAppID" name="defaultApps"
            style="margin-right:5px;margin-bottom:10px;margin-left:5px; margin-top:10px"
                [value]='apps.app_id'> {{apps.app_name}}
      </div>
      <div>
          <select name="role" class="dropdown" style="width:60%"
            (change)="selectedDefaultAppRole($event, rowIndexValue)" [(ngModel)]="apps.app_role">
              <option class="dropdown-item" value="" selected>Select</option>
              <option class="dropdown-item" *ngFor='let role of apps.roles' [value]="role.app_role_id">
                  {{role.app_role_name}}
              </option>
          </select>
      </div>
      </ng-template>
    </p-dataView>
    

    This is similar to what you have now, with the addition of passing the rowIndexValue value into the toggleSelectedApp and selectedDefaultAppRole functions. The rowIndexValue is made available in the template because you used let-rowIndexValue="rowIndex". This means the index from the data coming from iErsaDefaultApps will be available for use.

    UPDATE: I changed what you were binding to with ngModel to set the chosen value on the apps.app_role directly. Change [value]="role.app_role_id" to [value]="role.app_role_name" if you would rather have the role name stored.

    Then you can access the information in the TS code like this:

    export class MyComponent {
      iErsaDefaultApps = [{
        app_id: 1,
        app_name: 'App One',
        app_role: '',
        roles: [{
          app_role_id: 0,
          app_role_name: 'App Role One'
        },
        {
          app_role_id: 1,
          app_role_name: 'App Role Two'
        }]
      },
      {
        app_id: 3,
        app_name: 'App Two',
        app_role: '',
        roles: [{
          app_role_id: 0,
          app_role_name: 'App Role One'
        },
        {
          app_role_id: 1,
          app_role_name: 'App Role Two'
        }]
      }];
    
      selectedApps: Set<IErsaApps> = new Set<IErsaApps>();
    
      toggleSelectedApp(event: any, rowIndexValue: number) {
        // This adds or remove items from the selectedApps set
        const cApp = this.iErsaDefaultApps[rowIndexValue];
        console.log('Selected App', cApp);
        if (event.srcElement.checked) {
          this.selectedApps.add(cApp);
        } else {
          this.selectedApps.delete(cApp);
        }
        console.log('Selected Apps', this.selectedApps);
      }
    
      selectedDefaultAppRole(event: any, index: any) {
        // Now you can find out of the current app is selected
        const cApp = this.iErsaDefaultApps[index];
        console.log('Selected App', cApp);
        const isAppSelected = this.selectedApps.has(cApp);
        console.log('Is App Selected', isAppSelected);
        console.log('Selected Apps', this.selectedApps);
      }
    }
    
    
    export interface IErsaApps {
      app_id: number;
      app_name: string;
      app_role: string;
      roles: Array<IErsaAppRoles>;
    }
    
    export interface IErsaAppRoles {
      app_role_id: number;
      app_role_name: string;
    }
    

    This adds a simple lookup based on the index passed in from the template. Then, it tries to see if the selectedApps set has the app in it.

    Do whatever else you need to when a function is called.