UNPKG

angular4-collapsible

Version:

Angular 2 / 4 Materialize CSS collapsible components

337 lines (293 loc) 14.1 kB
import { Component, OnInit, AfterContentInit, Input, HostBinding, HostListener, ElementRef } from '@angular/core'; import { DomSanitizer, SafeStyle } from '@angular/platform-browser'; import { CollapsibleTableRowDetailComponent } from './collapsible-table-row-detail.component'; import { CollapsibleTableComponent } from './collapsible-table.component'; import { CollapsibleService } from './collapsible.service'; @Component({ selector: 'collapsible-table-row', template: `<ng-content></ng-content>`, styles: [` :host { display: table-row; transition-property: background-color, color; } `], }) export class CollapsibleTableRowComponent implements OnInit, AfterContentInit { private static EASE_OUT_QUAD = 'cubic-bezier(0.25, 0.46, 0.45, 0.94)'; public static DEFAULT_STRIPED_ODD_ROW_COLOR = 'rgba(242,242,242,0.8)'; public static DEFAULT_STRIPED_EVEN_ROW_COLOR = 'transparent'; public static DEFAULT_HIGHLIGHT_ROW_COLOR = 'rgba(222,222,222, 0.8)'; public static DEFAULT_ACTIVE_ROW_COLOR = 'rgba(212,212,212, 0.8)'; public static DEFAULT_SELECTED_ROW_COLOR = 'rgba(212,212,212, 0.8)'; public static DEFAULT_ROW_TEXT_COLOR = 'black'; @Input() detail: CollapsibleTableRowDetailComponent; @HostBinding('style.color') rowTextColor: string; @HostBinding('style.background-color') rowBackgroundColor: string; @HostBinding('style.transition-duration') backgroundTransitionDuration = '0.3s'; // transition-timing-function: easeInQuad @HostBinding('style.transition-timing-function') backgroundTransitionTimingFunction = this.sanitizer .bypassSecurityTrustStyle(CollapsibleTableRowComponent.EASE_OUT_QUAD); @HostBinding('class.selected') selected: boolean; isHeadRow = false; isBodyRow = false; isOddRow = false; isEvenRow = false; isParentStriped = false; isParentHighlight = false; parentAllowsSelect = false; parentAllowsSelectMultipleRows = false; parentStripedRowBackgroundColor: string; parentStripedRowTextColor: string; parentHighlightRowBackgroundColor: string; parentHighlightRowTextColor: string; activeRowBackgroundColor: string; activeRowTextColor: string; selectedRowBackgroundColor: string; selectedRowTextColor: string; parentAllowsDeselectingRows = false; index: number; private parentCollapsibleTable: CollapsibleTableComponent; private prevSelectedRows: Array<number>; private dragSelection = false; constructor( private el: ElementRef, private sanitizer: DomSanitizer, private collapsibleService: CollapsibleService) { } ngOnInit() { let elem: Element = this.el.nativeElement; let tbody: Element = elem.parentElement; if (tbody.tagName === 'TBODY') { // console.debug(elem); let collapsibleTableRows: NodeListOf<Element> = tbody.querySelectorAll('collapsible-table-row'); for (let i = 0; i < collapsibleTableRows.length; i++) { let collapsibleTableRow: Element = collapsibleTableRows[i]; if (collapsibleTableRow === elem) { this.index = i + 1; break; } } } // retrieve parent CollapsibleTableComponent through the CollapsibleService this.parentCollapsibleTable = this.collapsibleService.getCollapsibleTable(); // check if collapsible-table is marked to show striped table this.isParentStriped = this.parentCollapsibleTable.striped; // check if collapsible-table is marked to highlight current row this.isParentHighlight = this.parentCollapsibleTable.highlight; this.parentHighlightRowBackgroundColor = this.parentCollapsibleTable.highlightColor || CollapsibleTableRowComponent.DEFAULT_HIGHLIGHT_ROW_COLOR; this.parentHighlightRowTextColor = this.parentCollapsibleTable.highlightTextColor || CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR; // check if collapsible-table specifies the active row color this.activeRowBackgroundColor = this.parentCollapsibleTable.activeColor || CollapsibleTableRowComponent.DEFAULT_ACTIVE_ROW_COLOR; this.activeRowTextColor = this.parentCollapsibleTable.activeTextColor || CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR; // check if collapsible-table allows selecting rows this.parentAllowsSelect = this.parentCollapsibleTable.select; this.parentAllowsSelectMultipleRows = this.parentCollapsibleTable.selectMultipleRows; // check if collapsible-table specifies a color for the selected row this.selectedRowBackgroundColor = this.parentCollapsibleTable.selectColor || CollapsibleTableRowComponent.DEFAULT_SELECTED_ROW_COLOR; this.selectedRowTextColor = this.parentCollapsibleTable.selectTextColor || CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR; // check if collapsible-table allows to deselect rows this.parentAllowsDeselectingRows = this.parentCollapsibleTable.allowDeselectingRows != null ? this.parentCollapsibleTable.allowDeselectingRows : false; } ngAfterContentInit(): void { // console.debug(`CollapsibleTableRowComponent::ngAfterContentInit()`); this.updateRow(); } updateRow(): void { let elem: Element = this.el.nativeElement; // determine if the row is inside the 'thead' let th = elem.querySelector('th'); if (th != null) { this.isHeadRow = true; } // determine if the row is inside the 'tbody' let td = elem.querySelector('td'); if (td != null) { this.isBodyRow = true; // determine if the row is 'odd' or 'event' if (this.index % 2 === 0) { this.isEvenRow = true; this.parentStripedRowBackgroundColor = this.parentCollapsibleTable.stripedEvenColor || CollapsibleTableRowComponent.DEFAULT_STRIPED_EVEN_ROW_COLOR; this.parentStripedRowTextColor = this.parentCollapsibleTable.stripedEvenTextColor || CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR; } else { this.isOddRow = true; this.parentStripedRowBackgroundColor = this.parentCollapsibleTable.stripedOddColor || CollapsibleTableRowComponent.DEFAULT_STRIPED_ODD_ROW_COLOR; this.parentStripedRowTextColor = this.parentCollapsibleTable.stripedOddTextColor || CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR; } switch (true) { case this.parentAllowsSelect && this.selected: this.rowBackgroundColor = this.selectedRowBackgroundColor; this.rowTextColor = this.selectedRowTextColor; break; case this.isParentStriped: this.rowBackgroundColor = this.parentStripedRowBackgroundColor; this.rowTextColor = this.parentStripedRowTextColor; break; } } } getHeight(): number { return this.el.nativeElement.offsetHeight; } private isLeftMouseButton(event: MouseEvent): boolean { // console.debug(`isLeftMouseButton`); if ('button' in event) { return event.button === 0; } let button = event.which || event.button; return button === 1; } @HostListener('mousedown', ['$event']) mousedown(event: MouseEvent) { // handle only if the Left mouse button pressed // and the row is a body row if (this.isLeftMouseButton(event) && this.isBodyRow) { // console.debug(`mousedown`); if (this.parentCollapsibleTable.noTextSelect) { event.preventDefault(); } if (this.isBodyRow) { if (this.parentAllowsSelect && !this.parentAllowsDeselectingRows) { this.prevSelectedRows = this.parentCollapsibleTable.selectedRows; this.parentCollapsibleTable.clearSelectedRows(); this.parentCollapsibleTable.deselectAllRows(); } this.rowBackgroundColor = this.activeRowBackgroundColor; this.rowTextColor = this.activeRowTextColor; } } } @HostListener('mouseup', ['$event']) mouseup(event: MouseEvent) { // handle only if the Left mouse button pressed // and the row is a body row if (this.isLeftMouseButton(event) && this.isBodyRow) { // console.debug(`mouseup`); // handle selection if (this.parentAllowsSelect) { if (!this.parentAllowsDeselectingRows) { this.parentCollapsibleTable.selectRow(this.index); } else { if (!this.dragSelection) { this.parentCollapsibleTable.toggleRowSelection(this.index); } } } // check row state this.parentCollapsibleTable.updateTable(); /*switch (true) { // parent allows selecting rows and the row is selected case this.parentAllowsSelect && this.selected: this.rowBackgroundColor = this.selectedRowBackgroundColor; this.rowTextColor = this.selectedRowTextColor; this.parentCollapsibleTable.updateTable(); break; // highlighted case this.isParentHighlight: this.rowBackgroundColor = this.parentHighlightRowBackgroundColor; this.rowTextColor = this.parentHighlightRowTextColor; break; // striped case this.isParentStriped: this.rowBackgroundColor = this.parentStripedRowBackgroundColor; this.rowTextColor = this.parentStripedRowTextColor; break; default: this.rowBackgroundColor = undefined; this.rowTextColor = undefined; break; }*/ // select multiple rows using the 'Shift' key if (this.parentAllowsSelect && this.parentAllowsSelectMultipleRows && event != null && event.shiftKey) { if (this.prevSelectedRows != null && this.prevSelectedRows.length > 0 && this.parentCollapsibleTable.selectedRows.length > 0) { let rangeSelectedRows = this.prevSelectedRows.concat(this.parentCollapsibleTable.selectedRows); rangeSelectedRows.sort((a, b) => a - b); let firstRowIndex = Math.min.apply(null, rangeSelectedRows); let lastRowIndex = Math.max.apply(null, rangeSelectedRows); console.log(`rangeSelectedRows = ${rangeSelectedRows},` + ` firstRowIndex = ${firstRowIndex}, lastRowIndex = ${lastRowIndex} `); this.parentCollapsibleTable.selectRows(firstRowIndex, lastRowIndex); } } // set dragSelection flag to false. Prevents selection drag behavior this.dragSelection = false; } // focus the collapsible table this.parentCollapsibleTable.focus(); } @HostListener('mouseenter', ['$event']) mouseenter(event: MouseEvent) { // console.debug(`mouseenter`); // handle only if the row is a body row if (this.isBodyRow) { switch (true) { // the use is trying to select multiple rows by holding a mouse button case this.parentAllowsSelect && this.parentAllowsSelectMultipleRows && this.parentCollapsibleTable.mouseDownHold: this.parentCollapsibleTable.selectRow(this.index); this.dragSelection = true; break; // parent allows selecting rows and the row is selected case this.parentAllowsSelect && this.selected: break; // highlighted case this.isParentHighlight: this.rowBackgroundColor = this.parentHighlightRowBackgroundColor; this.rowTextColor = this.parentHighlightRowTextColor; break; } } } @HostListener('mouseleave', ['$event']) mouseleave(event: MouseEvent) { // console.debug(`mouseleave`); // handle only if the row is a body row if (this.isBodyRow) { // check row state switch (true) { // the use is trying to select multiple rows by holding a mouse button case this.parentAllowsSelect && this.parentAllowsSelectMultipleRows && this.parentCollapsibleTable.mouseDownHold: this.parentCollapsibleTable.selectRow(this.index); this.dragSelection = false; break; // parent allows selecting rows and the row is selected case this.parentAllowsSelect && this.selected: break; // stripped case this.isParentStriped: this.rowBackgroundColor = this.parentStripedRowBackgroundColor; this.rowTextColor = this.parentStripedRowTextColor; break; default: this.rowBackgroundColor = undefined; this.rowTextColor = undefined; break; } } } @HostListener('click') click() { if (this.detail != null) { this.detail.subject.next(); } } }