【问题标题】:Apply custom In Between Filter for PrimeNG: Datatable为 PrimeNG 应用自定义中间过滤器:数据表
【发布时间】:2018-10-12 22:11:59
【问题描述】:

考虑一个场景,我在 p-dataTable 列中显示 START 和 END YEAR。

这里是列代码sn-p:

<p-column field="startYear" header="Active Period" filterPlaceholder="Search" [filter]="true">
  <ng-template let-col let-manual="rowData" pTemplate="body">
    {{record.startYear}} - {{record.endYear}}
  </ng-template>
</p-column>

显示为:

|--------------|
| ActivePeriod |
|--------------|
|2015 - 2017   |
|--------------|
|2012 - 2016   |
|--------------|
|2023 - 2025   |
|--------------|
|2024 - 2030   |
|--------------|
|2011 - 2013   |
|--------------|

我想应用一个自定义过滤器,这样当用户输入 YEAR 时,表格应该只显示该活跃期的记录。

这意味着我必须编写一个逻辑来检查用户搜索的年份是否在每个活跃期之间。

我怎样才能做到这一点?

【问题讨论】:

    标签: angular primeng primeng-datatable


    【解决方案1】:

    首先,您可以添加隐藏助手字段years,其中将包含给定范围内的年份数组,因此对于范围2012 - 2015,我们将获得一个数组:

    [
      2012,
      2013,
      2014,
      2015
    ]
    

    您可以使用map 函数来实现,例如:

    const yearsRange = row.endYear - row.startYear + 1;
    YOUR_DATA_ARRAY.map(row => ({
      ...row,
      years: [...Array(yearsRange).keys()].map(y => y + row.startYear)
    }))
    

    开箱即用的PRIME NG 没有between 过滤器。 Filters available currently 是:

    • 开始于
    • 包含
    • 结束
    • 等于
    • 不等于
    • lt
    • gt

    您可以编写自己的过滤器来扩展它:

    // import Table class
    import { Table } from 'primeng/components/table/table';
    
    .....
    
    // get reference to your table
    @ViewChild('dt') tableRef: Table;
    
    .....
    
    // extend filters
    this.tableRef.filterConstraints.between = (value, filter: any): boolean => {
      if (filter === undefined || filter === null || filter === '') {
        return true;
      }
    
      if (value === undefined || value === null || !value.length) {
        return false;
      }
    
      return value.some(val => +val === +filter);
    };
    

    现在您可以在 HTML 中使用它了:

    <p-table #dt [value]="cars">
    
      .....
    
      <input size="4"
             (input)="dt.filter($event.target.value, 'years', 'between')">
    
      .....
    

    堆栈闪电:https://stackblitz.com/edit/angular-sfoh3j?file=app%2Fapp.component.ts

    更新

    我注意到您使用旧的(已弃用)DataTable, 解决方案应该非常相似,filters 与缺少ltgt 几乎相同。只需更改导入中的名称并在我的示例中键入名称。 HTML 语法也不同。 如果您需要关于旧 DataTable 的帮助,请告诉我

    【讨论】:

    • 嗨@Andriy,我正在使用旧版本的DataTable,我在.filterConstraints 上遇到错误,你能帮帮我吗?我没有时间迁移到较新的版本。提前致谢。
    • 请为您的问题创建一个 STACKBLITZ 重现,说明错误是什么以及您想要实现什么,我会尽力提供帮助
    【解决方案2】:

    Andriy 的回答帮助我解决了我在使用 DataTable 时遇到的一个特定问题。我们需要几个自定义过滤器用于 >= 和

    1 - 构建一个自定义组件来处理来自用户的输入

    打字稿:

    import { Component, Output, EventEmitter  } from '@angular/core';
    import { FormBuilder, FormGroup, AbstractControl, FormControl } from '@angular/forms';
    import { SelectItem } from 'primeng/components/common/selectitem';
    import { ICustomGtLsFilter } from '../../Models/ICustomGtLsFilter';
    
    @Component({
      selector: 'app-custom-filter',
      templateUrl: './custom-filter.component.html',
      styleUrls: ['./custom-filter.component.css']
    })
    export class CustomFilterComponent {
        @Output() onCriteriaSelectedChanged = new EventEmitter<ICustomGtLsFilter>();
    
        _myForm: FormGroup;
        _criteria: SelectItem[] = [{label: 'None', value: 'none'}, { label: '<=', value: 'lte' }, { label: '>=', value: 'gte' }];
    
        private _filterModel: ICustomGtLsFilter = new ICustomGtLsFilter();
    
        constructor(private _fb: FormBuilder) {
            this._myForm = _fb.group({
                _inputField: [null],
                _criteriaSel:[]
            });
        }
    
        fieldChanged(event) {
            // clear the input field
            if (event === "none") {
                this._myForm.controls['_inputField'].setValue('');
            }
    
            this._filterModel.Criteria = event;
            this._filterModel.FilterVal = this._myForm.controls['_inputField'].value;
    
            this.onCriteriaSelectedChanged.emit(this._filterModel);
        }
    }
    

    模板

    <form [formGroup]="_myForm">
        <div class="row">
            <div class="col-sm-12">
                <input type="number" name="_inputField" id="_inputField" [formControl]="_myForm.controls['_inputField']" autocomplete="off" />
                <p-dropdown [options]="_criteria"
                            [autoWidth]="false"
                            id="_criteriaSel"
                            name="_criteriaSel"
                            placeholder="None"
                            formControlName="_criteriaSel"
                            (onChange)="fieldChanged($event.value)">
                </p-dropdown>
            </div>
        </div>
    </form>  
    

    界面:

    export class ICustomGtLsFilter {
        FilterVal: number;
        Criteria: string;
    }
    

    这是定义为我们要应用过滤器的列的 ng-template 的自定义组件:

    <p-column field='TimeRem'
                      header='Time Remaining'
                      [sortable]='true'
                      [filter]='true'>
                <ng-template let-col
                             pTemplate='filter'>
                    <app-custom-filter appendTo="body" 
                             (onCriteriaSelectedChanged)="dt.filter($event.FilterVal,col.field,$event.Criteria)">
                    </app-custom-filter>
                </ng-template>
                <ng-template let-col
                             let-rd='rowData'
                             pTemplate='body'>
                    <span appAlignRightStyle>{{rd[col.field] | format: '0.0'}}</span>
                </ng-template>
            </p-column>
    

    最后是使用 DataTable 的组件中的相关打字稿代码:

    ...

    import { Component, OnInit, OnDestroy, ViewChild, AfterViewInit } from '@angular/core';
    import { CustomFilterComponent } from '../../../../shared/custom-filter/custom-filter.component';
    import { ICustomGtLsFilter } from '../../../../Models/ICustomGtLsFilter';
    
    export class SomeComponent implements OnInit {
        @ViewChild('dt') dt: DataTable;
    
     ngAfterViewInit() { 
            // custom filter implementations
            this.dt.filterConstraints['gte'] = function gte(value: any, filter: any): boolean {
    
                if (filter === undefined || filter === null) {
                    return false;
                }
    
                if (value === undefined || value === null || value.length === 0) {
                    return false;
                }
    
                if (value >= filter) {
                    return true;
                }
    
                return false;
            };
    
            this.dt.filterConstraints['lte'] = function lte(value: any, filter: any): boolean {
    
                if (filter === undefined || filter === null) {
                    return false;
                }
    
                if (value === undefined || value === null || value.length === 0) {
                    return false;
                }
    
                if (value <= filter) {
                    return true;
                }
    
                return false;
            };
    
            this.dt.filterConstraints['none'] = function none(value: any, filter: any): boolean {
    
                return true;
            };
    
        }
    

    【讨论】:

      猜你喜欢
      • 2017-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多