简体   繁体   中英

Kendo Angular Grid Filter on UI Value

I'm using Kendo UI for Angular 7 and I have filtering mostly up and working, however there is one thing I can't figure out. I have a few of my fields that go through pipes to make the UI more user friendly. For example I have a code in my objects that designates a software; when this is displayed in the grid it transforms the code into the full name of the software to make it easier for the user.

Filtering on this column is working... but it is filtering based on the underlying code, not the UI displayed value. So the user sees 'Keynote Manager' and tries to put 'Ke' into the filter and it doesn't find anything, because it's looking for 'KM' which is the underlying code.

Is there a way to get it to filter based on the UI displayed/piped value rather than the underlying value before piping?

Edit

Not sure if my specific code is really relevant as it's a more general question but here is my code as requested:

Grid Definition

<kendo-grid [data]="GridData" style="height: 100%" (detailExpand)="GetSessions($event.dataItem)"
                  [reorderable]="true" [resizable]="true"
                  [sortable]="{allowUnsort: true, mode: 'single'}" [sort]="State.sort"
                  [filterable]="true"
                  [filter]="State.filter"
                  (dataStateChange)="dataStateChange($event)"
                  [loading]="IsLoading">
        <ng-template kendoGridNoRecordsTemplate><div class="values" *ngIf="!IsLoading">No Licenses to Display</div></ng-template>
        <kendo-grid-column title="#" field="Seats" width="60" [filterable]="false"
                           [headerStyle]="{'text-align': 'center'}"
                           [style]="{'text-align': 'center'}"></kendo-grid-column>
        <kendo-grid-column title="Software" field="Software">
          <ng-template kendoGridCellTemplate let-license>{{ license.Software | softwareType }}</ng-template>
        </kendo-grid-column>
        <kendo-grid-column title="Portable" field="IsPortable" filter="boolean">
          <ng-template kendoGridCellTemplate let-license>{{ license.IsPortable | titlecase }}</ng-template>
        </kendo-grid-column>
        <kendo-grid-column title="Features" field="Features">
          <ng-template kendoGridCellTemplate let-license>{{ license.Features | features | titlecase }}</ng-template>
        </kendo-grid-column>
        <kendo-grid-column title="Expiry" field="Expiry" filter="date" format="d"></kendo-grid-column>
        <kendo-grid-column title="Key" field="ID">
          <ng-template kendoGridCellTemplate let-license>{{ license.ID }}</ng-template>
        </kendo-grid-column>            
      </kendo-grid>

Component Code

    import {Component, OnInit} from '@angular/core';
import {License} from '../Classes/license';
import {LicenseService} from '../license.service';
import {StandaloneActivation} from '../Classes/StandaloneActivation';
import {LicenseUsageBase} from '../Classes/LicenseUsageBase';
import {UserService} from '../user.service';
import {Session} from '../Classes/Session';
import {State, process} from '@progress/kendo-data-query';
import {DataStateChangeEvent, GridDataResult} from '@progress/kendo-angular-grid';

@Component({
  selector: 'app-licenses',
  templateUrl: './licenses.component.html',
  styleUrls: ['./licenses.component.css']
})
export class LicensesComponent implements OnInit {
  // TODO: Allow release of multiple licenses at a time
  Licenses: License[];

  GridData: GridDataResult;

  State: State = {
    skip: 0,
    sort: [{field: 'Software', dir: 'asc'}],
    filter: {
      logic: 'and',
      filters: []
    }
  };
  IsLoading = true;

  constructor(private licenseService: LicenseService,
              private userService: UserService) {
  }

  ngOnInit() {
    this.GetLicenses();
  }

  GetLicenses(): void {
    this.licenseService.GetLicenses().subscribe(licenses => {
      this.Licenses = licenses;
      this.GridData = process(this.Licenses, this.State);
      this.IsLoading = false;
    });
  }   

  public dataStateChange(state: DataStateChangeEvent): void {
    this.State = state;
    this.GridData = process(this.Licenses, this.State);
  }
}

Edit

Per the suggestion below I ended up changing my base level converter to set a new property on the class and filtered based on that using my original pipe:

private ConvertBaseToLicense(baseObject: any): License {
  const jsonConvert: JsonConvert = new JsonConvert();
  jsonConvert.operationMode = Constants.ConverterMode;

  const license = jsonConvert.deserializeObject<License>(baseObject, License);
  const SwPipe = new SoftwareTypePipe();
  license.UIName = SwPipe.transform(license.Software);
  return license;
}

The filtering is going to be against the grid's datasource, but I think there are a couple of ways to achieve what you are looking for, although neither of them is exactly what you want.

The easiest approach would be to modify GetLicenses() to add an additional column to your data that contains "Keynote Manager" and the other values either at the source or when the data is returned, and then bind to this column.

Another approach would be to add a custom filter to your grid where you could keep your key value pairs of codes (KM) and friendly descriptions (Keynote Manager) and allow the user to select from a dropdown.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM