Angular 7 - virtual scroll table with support draggable, pagination, server side, sorting, filtering, resizing and dynamic component
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github/ISSUE_TEMPLATE
appTest
docs
lib
.gitignore
.prettierrc
.travis.yml feat(travis): add travis Oct 27, 2018
LICENSE
README.md
jest-global-mocks.ts
package.json
setupJest.ts
tsconfig.json
tsconfig.spec.json
tslint.json
yarn.lock

README.md

ng-virtual-table

Angular 7 virtual scroll table with support dynamic component, draggable, filtering, sorting, paginations, resizable and custom config for each column

Travis CI Coverage Npm Npm Downloads Licence

Install and Use

npm i ng-virtual-table
yarn add ng-virtual-table

Make sure you have: @angular/cdk @angular/material @angular/forms

import { NgVirtualTableModule } from 'ng-virtual-table';

imports: [NgVirtualTableModule],
<ng-virtual-table [dataSource]="dataSource"></ng-virtual-table>

📺 STACKBLITZ

📺 Demo

NPM

Configuration

  @Input() itemSize = 25;

  @Input() dataSource: Observable<Array<VirtualTableItem | number | string | boolean>>;

  @Input() filterPlaceholder = 'Filter';

  @Input() dataSetEmptyPlaceholder = 'Data is empty';

  @Input() config: VirtualTableConfig;

  @Input() onRowClick: (item: VirtualTableItem) => void;
export type sortColumn = 'asc' | 'desc' | null | false;


export interface VirtualPageChange {
  pageSize?: number; // pagination size
  pageIndex?: number; // page index 
}

export interface VirtualSortEffect {
  sortColumn: string; // column for sort
  sortType?: sortColumn; // type sort
}

export interface VirtualTableColumn {
  name?: string; // Label for field, if absent will be use key
  key: string; // Uniq key for filed, 
  func?: (item: VirtualTableItem) => any; // function for get value from dataSource item
  comp?: (a: any, b: any) => number; // function for compare two item, depend from `func` function
  sort?: 'asc' | 'desc' | null | false;  // sort by default(support only one sort), false for disable
  resizable?: boolean; // default true(if not set `true`)
  draggable?: boolean; // default true (if not set `true`)
  component?: VirtualTableColumnComponent | false; // default false (You class component must be part of entryComponents in yor Module!!!!!)
}

export interface VirtualTableColumnComponent {
  componentConstructor: Type<any>;
  inputs?: Object; // default {}
  outputs?: Object;
}

export interface VirtualTablePaginator {
  pageSize?: number; // default 10
  pageSizeOptions?: Array<number>; // default [5, 10, 25, 100];
  showFirstLastButtons?: boolean; //default false;
}

export interface ResponseStreamWithSize {
  stream: Array<any>; // stream for Server Side strategy
  totalSize: number; // total size of stream
}

export interface VirtualTableEffect {
  filter?: string; // filter string
  sort?: VirtualSortEffect; // sort effect
  pagination?: VirtualPageChange; // pagination effect
}

export interface VirtualTableConfig {
  column?: Array<VirtualTableColumn>; // if config not provide will be auto generate column
  header?: boolean; // default false
  filter?: boolean; // default true
  pagination?: VirtualTablePaginator | boolean; // default false
  serverSide?: boolean; // default false;
  serverSideResolver?: (effects: VirtualTableEffect) => Observable<ResponseStreamWithSize>;
}

Example

import { VirtualTableConfig } from 'ng-virtual-table';

  clickToItem(item: any) {
    console.log(item);
  }

  dataSource = of(
    Array(1000).fill(0).map((e) => ({
      name: Math.random().toString(36).substring(7),
      age: Math.round(Math.random() * 1000),
    })),
  );

  dataSource1 = of(
    Array(1000).fill(0).map((e) => ({
      name: Math.random().toString(36).substring(7),
      age: Math.round(Math.random() * 1000),
      age2: Math.round(Math.random() * 1000),
      label: {
        type: Math.random().toString(36).substring(7),
      },
    })),
  );

  config: VirtualTableConfig = {
    column: [
      {
        key: 'name',
        name: 'Full name',
        sort: false // disable sort
      },
      {
        key: 'age',
        name: 'Full Age',
        sort: 'desc', // pre defined sort
        component: {
          componentConstructor: InfoComponent,
          inputs: {
            title: (e) => e.age,
          },
        },
      },
      {
        key: 'label',
        name: 'Full Label',
        func: (e) => e.label.type,
        comp: (a, b) => a.indexOf('5') - b.indexOf('5'), // here a and b (e) => e.label.type
      },
    ],
  };

  

@Component({
  selector: 'app-info',
  templateUrl: './info.component.html',
  styleUrls: ['./info.component.scss'],
})
export class InfoComponent {
  @Input() title: string;

  constructor() {}
}
 
<ng-virtual-table [dataSource]="dataSource"></ng-virtual-table>

<ng-virtual-table [dataSource]="dataSource1" [onRowClick]="clickToItem" [config]="config"></ng-virtual-table>