UNPKG

angular2-data-table

Version:

angular2-data-table is a Angular2 component for presenting large and complex data.

167 lines (138 loc) 4.79 kB
import { Component, Input, Output, EventEmitter } from '@angular/core'; import { Keys, selectRows, selectRowsBetween } from '../../utils'; import { SelectionType } from '../../types'; export interface Model { type: string; event: MouseEvent | KeyboardEvent; row: any; rowElement: any; cellElement: any; cellIndex: number; } @Component({ selector: 'datatable-selection', template: ` <ng-content></ng-content> ` }) export class DataTableSelectionComponent { @Input() rows: any[]; @Input() selected: any[]; @Input() selectEnabled: boolean; @Input() selectionType: SelectionType; @Input() rowIdentity: any; @Input() selectCheck: any; @Output() activate: EventEmitter<any> = new EventEmitter(); @Output() select: EventEmitter<any> = new EventEmitter(); prevIndex: number; selectRow(event: KeyboardEvent | MouseEvent, index: number, row: any): void { if (!this.selectEnabled) return; const chkbox = this.selectionType === SelectionType.checkbox; const multi = this.selectionType === SelectionType.multi; let selected: any[] = []; if (multi || chkbox) { if (event.shiftKey) { const newSelected = [...this.selected]; selected = selectRowsBetween( newSelected, this.rows, index, this.prevIndex, this.getRowSelectedIdx.bind(this)); } else if (!event.shiftKey) { selected.push(row); } else { const newSelected = [...this.selected]; selected = selectRows(newSelected, row, this.getRowSelectedIdx.bind(this)); } } else { selected.push(row); } if(this.selectCheck) { selected = selected.filter(this.selectCheck.bind(this)); } this.selected.splice(0, this.selected.length); this.selected.push(...selected); this.prevIndex = index; this.select.emit({ selected }); } onActivate(model: Model, index: number): void { const { type, event, row } = model; const chkbox = this.selectionType === SelectionType.checkbox; const select = (!chkbox && (type === 'click' || type === 'dblclick')) || (chkbox && type === 'checkbox'); if(select) { this.selectRow(event, index, row); } else if(type === 'keydown') { if ((<KeyboardEvent>event).keyCode === Keys.return) { this.selectRow(event, index, row); } else { this.onKeyboardFocus(model); } } this.activate.emit(model); } onKeyboardFocus(model: Model): void { const { keyCode } = <KeyboardEvent>model.event; const shouldFocus = keyCode === Keys.up || keyCode === Keys.down || keyCode === Keys.right || keyCode === Keys.left; if(shouldFocus) { const isCellSelection = this.selectionType === SelectionType.cell; if(!model.cellElement || !isCellSelection) { this.focusRow(model.rowElement, keyCode); } else if(isCellSelection) { this.focusCell(model.cellElement, model.rowElement, keyCode, model.cellIndex); } } } focusRow(rowElement: any, keyCode: number): void { const nextRowElement = this.getPrevNextRow(rowElement, keyCode); if(nextRowElement) nextRowElement.focus(); } getPrevNextRow(rowElement: any, keyCode: number): any { const parentElement = rowElement.parentElement; if(parentElement) { let focusElement: HTMLElement; if(keyCode === Keys.up) { focusElement = parentElement.previousElementSibling; } else if(keyCode === Keys.down) { focusElement = parentElement.nextElementSibling; } if(focusElement && focusElement.children.length) { return focusElement.children[0]; } } } focusCell(cellElement: any, rowElement: any, keyCode: number, cellIndex: number): void { let nextCellElement: HTMLElement; if(keyCode === Keys.left) { nextCellElement = cellElement.previousElementSibling; } else if(keyCode === Keys.right) { nextCellElement = cellElement.nextElementSibling; } else if(keyCode === Keys.up || keyCode === Keys.down) { const nextRowElement = this.getPrevNextRow(rowElement, keyCode); if(nextRowElement) { const children = nextRowElement.getElementsByClassName('datatable-body-cell'); if(children.length) nextCellElement = children[cellIndex]; } } if(nextCellElement) nextCellElement.focus(); } getRowSelected(row: any): boolean { return this.getRowSelectedIdx(row, this.selected) > -1; } getRowSelectedIdx(row: any, selected: any[]): number { if(!selected || !selected.length) return -1; const rowId = this.rowIdentity(row); return selected.findIndex((r) => { const id = this.rowIdentity(r); return id === rowId; }); } }