簡體   English   中英

角2的Kendo網格-按鍵上的濾鏡輸入失去焦點

[英]kendo grid for angular 2 - focus lost from filter input on keypress

我創建了一個kendo網格組件,該組件在每次按鍵時都失去對過濾器文本字段的關注。 我的組件如下所示-

    <kendo-grid [data]="getKendoRecords()"
                [skip]="kendoGridPageDataSkip"
                [pageable]="true"
                [pageSize]="getPageSize(options)"
                [navigable]="true"
                [resizable]="true"
                [filterable]="true"
                [filter]="filter"
                [selectable]="{enabled: true, checkboxOnly: true }"
                [kendoGridSelectBy]="'record'"
                [selectedKeys]="kendoSelectedItems"
                (cellClick)="gridCellClick($event)"
                (selectedKeysChange)="onSelectedKeysChange($event)"
                (pageChange)="kendoPageChange($event)"
                (filterChange)="applyFilter($event)"
                >
      <kendo-grid-checkbox-column *ngIf="hasCheckbox()" width="45" showSelectAll="true" [resizable]="false">
        <ng-template kendoGridHeaderTemplate>
          <input class="k-checkbox" id="{{'selectAllCheckboxId_' + options.listId}}" kendoGridSelectAllCheckbox
                 [state]="selectAllState" [disabled]="isReadOnly()"
                 (selectAllChange)="onSelectAllChange($event)">
          <label class="k-checkbox-label" for="{{'selectAllCheckboxId_' + options.listId}}"></label>
        </ng-template>
      </kendo-grid-checkbox-column>
      <kendo-grid-column *ngFor="let property of selectedView.properties" 
                         field="{{getKendoFieldName(property.propertyName)}}"
                         title="{{getKendoFieldName(property.propertyLabel)}}"
                         [filterable]="isSearchableProperty(property, options)"
                         [minResizableWidth]="30">
        <ng-template kendoGridFilterCellTemplate let-filter let-column="column">
          <kendo-grid-string-filter-cell [column]="column" [filter]="filter" [showOperators]="false" operator="contains">
            <kendo-filter-contains-operator></kendo-filter-contains-operator>
          </kendo-grid-string-filter-cell>
        </ng-template>
         <ng-template kendoGridHeaderTemplate>
           {{property.propertyLabel}}
         </ng-template>
         <ng-template *ngIf="getKendoEditorType(property)=='date'" kendoGridCellTemplate let-dataItem>
           {{getKendoRecordValue(property, dataItem) | date:formatDate()}}
         </ng-template>
         <ng-template *ngIf="getKendoEditorType(property)=='time'" kendoGridCellTemplate let-dataItem>
           {{getKendoRecordValue(property, dataItem) | time:formatTime()}}
         </ng-template>
         <ng-template *ngIf="getKendoEditorType(property)=='boolean'" kendoGridCellTemplate let-dataItem>
           <input class="k-checkbox" type="checkbox" [checked]="getKendoRecordValue(property, dataItem)" [disabled]="true" />
           <label class="k-checkbox-label"></label>
         </ng-template>
         <ng-template *ngIf="getKendoEditorType(property)!='date' && getKendoEditorType(property)!='boolean'" kendoGridCellTemplate let-dataItem>
           {{getKendoRecordValue(property, dataItem)}}
         </ng-template>
       </kendo-grid-column>
       <ng-template kendoPagerTemplate let-totalPages="totalPages" let-currentPage="currentPage">
         <kendo-pager-prev-buttons></kendo-pager-prev-buttons>
         <kendo-pager-info></kendo-pager-info>
         <kendo-pager-next-buttons></kendo-pager-next-buttons>
         <kendo-pager-page-sizes *ngIf="options.displayPageSizeSelector" [pageSizes]="pageSizeOptions"></kendo-pager-page-sizes>
       </ng-template>
    </kendo-grid>

代碼文件是-

    import { Component, Input, Output, EventEmitter, OnInit, OnChanges } from '@angular/core';
    import { FormBuilder, FormGroup } from '@angular/forms';
    import * as _ from 'lodash';
    import { PropertyType, MessageType } from '../../../entity-common';
    import { ListService, LabelService } from '../../../app/services';
    import { EntityListHelper } from '../../../helpers';
    import { PageChangeEvent, SelectAllCheckboxState } from '@progress/kendo-angular-grid';
    import { Map } from 'immutable';

    @Component({
      selector: 'mgr-entity-list-kendo-grid',
      templateUrl: './entity-list-kendo-grid.component.html',
      providers: [EntityListHelper]
    })
    export class EntityListKendoGridComponent implements OnInit, OnChanges {
      @Input() options: any;
      @Input() endpoint: any;
      @Input() formReadOnly: boolean;
      @Input() selectedView: any;
      @Input() multiSelectValue: any;
      @Input() selectedAllPages: any;
      @Input() multiSelectField: any;
      @Input() inlineAddAction: any;
      @Input() inlineEditAction: any;
      @Input() multiAddAction: any;

      @Output() lookupSelectedEvent: EventEmitter<any> = new EventEmitter<any>();
      @Output() multiSelectIdsEvent: EventEmitter<any> = new EventEmitter<any>();

      multiSelectIds: Array<number> = [];
      kendoSelectedItems: Array<any> = [];
      PropertyType = PropertyType;
      MessageType = MessageType;

      newItem: any = { rowProperties: { editMode: false }, record: undefined };
      isSorting: boolean;
      collapsed = false;

      multiSelectSeparator = ';';

      searchParams = {
        Criteria: [],
        AdvancedConditions: ''
      };

      public checkboxOnly = false;
      public mode = 'multiple';
      public mySelection: number[] = [];
      public selectAllState: SelectAllCheckboxState = 'unchecked';
      public kendoGridPageDataSkip = 0;
      public pageSizeOptions = [];
      public filter: any;

      constructor(
        private listService: ListService,
        private labelService: LabelService,
        private helper: EntityListHelper,
        private formBuilder: FormBuilder) {
      }

      ngOnInit() {
        this.setupBase();

        if (this.options.displayPageSizeSelector) {
          this.pageSizeOptions = [5, 20, 50, 100, 200];
        }
      }

      ngOnChanges() {
        this.multiSelectIds = [];
        this.selectedAllPages = [];
        this.kendoSelectedItems = [];
        this.selectedView = this.helper.getSelectedView(this.options);
        this.options.formLayout = this.selectedView ? this.selectedView.formLayout : null;

        this.setupBase();
      }

      private setupBase() {
        if (this.options.actions) {
          this.inlineAddAction = this.options.actions.find(action => action.action === 'inlineAdd');
          this.inlineEditAction = this.options.actions.find(action => action.action === 'inlineEdit');
          this.multiAddAction = this.options.actions.find(action => action.action === 'newFromLookup');
        }

        if (this.multiSelectIds.length === 0) {
          this.selectAllState = 'unchecked';
        }
      }

      getCount(): number {
        if (this.options.records) {
          return this.options.totalCount;
        }
        return 0;
      }

      isReadOnly() {
        return this.options.readOnly || this.formReadOnly;
      }

      hasCheckbox(): boolean {
        if (this.options.actions &&
          this.options.actions.length > 0 && !this.options.disableRowSelector) {
          return true;
        } else {
          return false;
        }
      }

      rowClick(item) {
        if (this.multiSelectField) {
          this.updateMultiSelectItems(item);
          return;
        } else if (!this.options.rowClickAction) {
          return;
        } else if (this.options.rowClickAction.action.toLowerCase() === 'selectlookupvalue') {
          this.lookupSelectedEvent.emit(item);
        }

        this.options.rowClickAction.actionFunction(item);
      }

      // multiSelect logic
      updateMultiSelectItems(item) {
        if (this.multiSelectIds.indexOf(item.record.id) === -1) {
          this.addMultiSelect(item);
        } else {
          this.removeMultiSelect(item);
        }

        this.multiSelectIdsEvent.emit(this.multiSelectIds);
      }

      addMultiSelect(item) {
        if (this.multiSelectValue !== '') {
          this.multiSelectValue += this.multiSelectSeparator + ' ';
        }

        this.multiSelectValue += item.record[this.multiSelectField];
        this.multiSelectIds.push(item.record.id);
      }

      removeMultiSelect(item) {
        this.multiSelectValue = this.multiSelectValue.replace(item.record[this.multiSelectField], '');
        this.multiSelectValue = this.multiSelectValue.replace(this.multiSelectSeparator + ' ', '');

        this.multiSelectIds.splice(this.multiSelectIds.indexOf(item.record.id), 1);

        if (this.selectedAllPages.indexOf(this.options.page) >= 0) {
          this.selectedAllPages.splice(this.selectedAllPages.indexOf(this.options.page), 1);
        }
      }

      multiSelectAllCurrentPage() {
        if (this.selectedAllPages.indexOf(this.options.page) === -1) {
          this.selectedAllPages.push(this.options.page);

          for (let i = 0; i < this.options.records.length; i++) {
            if (this.multiSelectIds.indexOf(this.options.records[i].record.id) === -1) {
              this.addMultiSelect(this.options.records[i]);
            }
          }
        } else {
          this.selectedAllPages.splice(this.selectedAllPages.indexOf(this.options.page), 1);

          for (let i = 0; i < this.options.records.length; i++) {
            if (this.multiSelectIds.indexOf(this.options.records[i].record.id) >= 0) {
              this.removeMultiSelect(this.options.records[i]);
            }
          }
        }

        this.multiSelectIdsEvent.emit(this.multiSelectIds);
      }

      onListFilterSearch() {
        this.options.filterListFunction(this.searchParams);
      }

      getPageSize(options): number {
        if (!options.displayPageSizeSelector) {
          return options.pageSize;
        }

        return this.helper.getLookupPageSize(options);
      }

      getKendoRecords() {
        const totalCount = this.getCount();
        return {
          data: this.options.records,
          total: totalCount
        };
      }

      getKendoRecordValue(property, item) {
        const properties = property.propertyName.split('.');
        let object = item ? item.record : this.options.records[0].record;

        for (let i = 0; i < properties.length; i++) {
          if (!object) {
            break;
          }
          const propertyValue = properties[i];
          object = object[propertyValue];
        }
        return object;
      }

      getKendoEditorType(property) {
        switch (property.propertyType) {
          case (this.PropertyType.string):
            return 'string';
          case (this.PropertyType.checkbox || this.PropertyType.radio || this.PropertyType.boolean):
            return 'boolean';
          case (this.PropertyType.integer || this.PropertyType.number):
            return 'numeric';
          case (this.PropertyType.date):
            return 'date';
          case (this.PropertyType.time):
            return 'time';
          default:
            return 'string';
        }
      }

      getKendoFieldName(property) {
        return property.replace(/\W+/g, '');
      }

      cellClickHandler({ sender, rowIndex, columnIndex, dataItem, isEdited }) {
        if (!isEdited) {
          sender.editCell(rowIndex, columnIndex, this.createFormGroup(dataItem));
        }
      }

      private createFormGroup(dataItem: any): FormGroup {
        const newFormGroup = {};

        this.selectedView.properties.forEach(property => {
          newFormGroup[this.getKendoFieldName(property.propertyLabel)] = this.getKendoRecordValue(property, dataItem);
        });

        return this.formBuilder.group(newFormGroup);
      }

      formatDate() {
        if (!this.options.fieldFormats) {
          return '';
        }

        return this.options.fieldFormats.dateFormat.toUpperCase().toString();
      }

      formatTime() {
        if (!this.options.fieldFormats) {
          return '';
        }

        return this.options.fieldFormats.timeFormat;
      }

      gridCellClick(event) {
        if (event.dataItem.rowProperties && event.dataItem.rowProperties !== null) {
          this.rowClick(this.getRecordItembypageIdLink(event.dataItem.record.id, event.dataItem.rowProperties.pageIdLink));
        } else {
          this.rowClick(this.getRecordItem(event.dataItem.record.id));
        }
      }

      getRecordItembypageIdLink(id, pageIdLink) {
        return this.options.records.find(item => item.record.id === id && item.rowProperties.pageIdLink === pageIdLink);
      }

      getRecordItem(id) {
        return this.options.records.find(item => item.record.id === id);
      }

      public onSelectedKeysChange(event) {
        this.multiSelectIds = this.kendoSelectedItems.map(record => record.id);
        this.multiSelectIdsEvent.emit(this.multiSelectIds);

        const len = this.multiSelectIds.length;

        if (len === 0) {
          this.selectAllState = 'unchecked';
        } else if (len > 0 && len < this.options.records.length) {
          this.selectAllState = 'indeterminate';
        } else {
          this.selectAllState = 'checked';
        }
      }

      public onSelectAllChange(checkedState: SelectAllCheckboxState) {
        this.multiSelectAllCurrentPage();

        if (this.multiSelectIds.length > 0) {
          this.selectAllState = 'checked';
        } else {
          this.selectAllState = 'unchecked';
        }
      }

      public kendoPageChange(event: PageChangeEvent): void {
        this.kendoGridPageDataSkip = event.skip;
        const pageSize = event.take;

        if (this.kendoGridPageDataSkip === 0) {
          this.options.page = 1;
        } else {
          this.options.page = (this.kendoGridPageDataSkip / pageSize) + 1;
        }

        const pageEvent = { pageIndex: this.options.page, pageSize: pageSize };

        this.options.paginateFunction(pageEvent);
      }

      public isSearchableProperty(property) {
        return property &&
          property.propertyType === PropertyType.string &&
          !property.prohibited &&
          this.options &&
          this.options.filterListFunction &&
          typeof this.options.filterListFunction === 'function';
      }

      public applyFilter(event: any) {
        this.filter = event;
        this.searchParams = {
          Criteria: [],
          AdvancedConditions: ''
        };

        if (!event.filters || event.filters == null || event.filters.count === 0) {
          return;
        }

        let filters: any;
        let key: string;
        let value: string;
        let operator: string;
        const conjunction = 'AND';

        event.filters.forEach(filter => {
          key = this.getKendoFieldName(filter.field);
          value = filter.value;
          operator = filter.operator;

          if (operator === 'contains') {
            value = '*' + value + '*';
          }

          filters = Map([[key, value]]);

          const newSearchParams = this.helper.createSearchParams(filters, conjunction);

          this.searchParams.Criteria = this.listService.mergeCriteria(this.searchParams.Criteria, newSearchParams.Criteria);
          this.searchParams.AdvancedConditions = this.searchParams.Criteria.map((r, index) => {
            return index + 1;
          }).join(' ' + conjunction + ' ');
        });

        this.onListFilterSearch();
      }
    }

一切工作正常,但每次按鍵時焦點都從過濾器文本框中丟失。 過濾時,系統將返回服務器並獲取過濾的數據。

我的第一個目標是將注意力集中在過濾器字段上,以便用戶可以繼續輸入。

第二個目標是不要在每次按鍵時都轉到服務器,而是在用戶按下Enter或Tab鍵或輸入字段失去焦點時調用服務器。

請隨時詢問是否需要進一步說明。

好。 在這種情況下,我有一種解決方法。 萬一有幫助

我用的是KeyDown而不是KeyPress。

在.ts文件中還更改了一些-

使用過的keydownfilter事件-

keyDownOnFilter(event: any) {
  if (event && (event.keyCode === 9 || event.keyCode === 13)) {
    this.filterGrid();
  }
}

filterGrid() {
  this.onListFilterSearch();
}

從applyFilter方法中刪除了onListFilterSearch命令,因為我不需要在每個keydown上進行過濾..僅當按下Tab或Enter時,網格才會過濾數據。

謝謝

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM