Skip to content

Angular 7 - virtual scroll table with support draggable, pagination, server side, sorting, filtering, resizing and dynamic component

License

Notifications You must be signed in to change notification settings

fgerges/ng-virtual-table

 
 

Repository files navigation

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>

About

Angular 7 - virtual scroll table with support draggable, pagination, server side, sorting, filtering, resizing and dynamic component

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 90.9%
  • CSS 5.1%
  • HTML 3.8%
  • HCL 0.2%