상태별로 검색할 수 있는 custom filter 추가

상태별로 검색할 수 있는 custom filter 추가
TP 교정가이드 주문 사이트의 주문 리스트에서 전보다 쉽게 주문 상태별로 검색할 수 있는 filter가 필요했다. 따라서 clarity의 datagrid 컴포넌트에 추가할 custom filter를 만들었다.

order-list.component.html

<clr-dg-column [clrDgField]="'status.description'">
  Status
  <clr-dg-filter [clrDgFilter]="statusFilter">
    <status-filter #statusFilter [items]="statusFilterOptions"></status-filter>
  </clr-dg-filter>
</clr-dg-column>

order-list.component.ts

보여질 옵션들을 정의하고, 옵션들이 체크/해제되었을 때의 이벤트를 받기위한 refresh함수를 정의한다.
statusFilterOptions = [
  { key: 'new', value: '주문 등록' },
  { key: 'modeling-working', value: '작업 중' },
  { key: 'data-error', value: '데이터 오류' },
  { key: 'modeling-done', value: '작업 완료' },
  { key: 'request-production', value: '제작 요청' },
  { key: 'modeling-re-work', value: '재작업 요청' },
  { key: 'guide-in-production', value: '제작 중' },
  { key: 'production-sent', value: '제작 완료 및 발송' },
  { key: 'guide-recieve', value: '수령 완료' },
  { key: 're-production', value: '재제작 요청' },
  { key: 'order-complete', value: '주문 처리 완료' }
  ];
  
  refresh(event) {
    if (!event) {
      return;
    }

    const state = {
      limit: event.page.size,
      skip: event.page.from
    };

    if (event.sort) {
      const sort = {};
      sort[event.sort.by] = event.sort.reverse ? 1 : -1;
      state['sort'] = sort;
    }
    if (event.filters) {
      const query = {};
      for (const filter of event.filters) {
        query[filter.property] = typeof filter.value === 'string' ? { $regex: filter.value } : filter.value;
      }
      state['query'] = query;
    }
  }

status-filter.component.html

미리 정의한 옵션에 대한 html 코드를 작성한다.
<div>
  <ul style="list-style: none;">
    <li *ngFor="let item of items">
      <clr-checkbox (change)="onItemChanged(item)" [(clrChecked)]="item.checked" [clrDisabled]="item.disabled">
        <span>{{ item.value }}</span>
      </clr-checkbox>
    </li>
  </ul>
</div

status-filter.component.ts

custom filter를 만들 때에는 isActive(), accepts(item), changes: Observable을 인터페이스로 제공한다. 인터페이스를 상속받아 구현한다.
@Input() public items: Array<{ key: string, value: string, checked: boolean }>;
public selectedItems: Array<{ key: string, value: string }> = [];
public changes = new Subject<any>();

public onItemChanged(item) {
  if (item.checked) {
    this.selectedItems.push(item);
  } else {
    let index = this.selectedItems.indexOf(item);
    if (index >= 0) {
      this.selectedItems.splice(index, 1);
    }
  }
  this.changes.next(true);
}

public accepts(item): boolean {
  for (let currentItem of this.items) {
    if (currentItem.checked && currentItem.key === item.status.code) {
      return true;
    }
  }
  return false;
}

public isActive(): boolean {
  return this.selectedItems != null && this.selectedItems.length > 0;
}

댓글

가장 많이 본 글