import {Component, Input, Output, OnInit, AfterViewInit, EventEmitter,
- OnDestroy, ViewChild, ViewEncapsulation} from '@angular/core';
+ OnDestroy, ViewChild, ViewEncapsulation, Renderer2, ElementRef} from '@angular/core';
import {IdlService} from '@eg/core/idl.service';
import {OrgService} from '@eg/core/org.service';
import {ServerStoreService} from '@eg/core/server-store.service';
private idl: IdlService,
private org: OrgService,
private store: ServerStoreService,
- private format: FormatService
+ private format: FormatService,
+ private renderer: Renderer2,
+ private gridTable: ElementRef
) {
this.context =
- new GridContext(this.idl, this.org, this.store, this.format);
+ new GridContext(this.idl, this.org, this.store, this.format, this.renderer, this.gridTable);
this.onRowActivate = new EventEmitter<any>();
this.onRowClick = new EventEmitter<any>();
this.rowSelectionChange = new EventEmitter<string[]>();
/**
* Collection of grid related classses and interfaces.
*/
-import {TemplateRef, EventEmitter, QueryList} from '@angular/core';
+import {TemplateRef, EventEmitter, AfterViewInit, QueryList, Renderer2, ElementRef} from '@angular/core';
import {Observable, Subscription, empty} from 'rxjs';
import {IdlService, IdlObject} from '@eg/core/idl.service';
import {OrgService} from '@eg/core/org.service';
showDeclaredFieldsOnly: boolean;
cellTextGenerator: GridCellTextGenerator;
reloadOnColumnChange: boolean;
+ ColX: number;
+ ColW: number;
+ charWidth: number;
// Allow calling code to know when the select-all-rows-in-page
// action has occurred.
idl: IdlService,
org: OrgService,
store: ServerStoreService,
- format: FormatService) {
+ format: FormatService,
+ private renderer: Renderer2,
+ private gridTable: ElementRef) {
this.idl = idl;
this.org = org;
this.pager.limit = this.disablePaging ? MAX_ALL_ROW_COUNT : 10;
}
this.generateColumns();
+ this.generateColumnResizers();
}
// Load initial settings and data.
if (col.cellTemplate) {
return ''; // avoid 'undefined' values
} else {
- return this.getRowColumnValue(row, col);
+ let str = this.getRowColumnValue(row, col);
+ switch (col.name) {
+ case 'name':
+ case 'url':
+ case 'email':
+ //TODO: insert <wbr> around punctuation
+ break;
+ default: break;
+ }
+ return str;
}
}
}
// smush into string and replace dots in name and path
return classes.join(' ').replaceAll('.', '');
}
+
+ generateColumnResizers() {
+ if (!this.gridTable) { return; }
+
+ const cols = this.gridTable.nativeElement.querySelectorAll('th');
+ cols.forEach((col) => {
+ // Find resizer element
+ const resizer = col.nativeElement.querySelector('button.col-resize');
+ if (resizer) {
+ this.createResizableColumn(col, resizer);
+ }
+ });
+ }
+
+ createResizableColumn(col, resizer) {
+ // Track the current position of mouse
+ let x = 0;
+ let w = 0;
+
+ const mouseDownHandler = function ($event) {
+ // Get the current mouse position
+ x = $event.clientX;
+
+ // Calculate the current width of column
+ const styles = window.getComputedStyle(col);
+ w = parseInt(styles.width);
+
+ // Attach listeners for document's events
+ document.addEventListener('pointermove', mouseMoveHandler);
+ document.addEventListener('pointerup', mouseUpHandler);
+ };
+
+ const mouseMoveHandler = function ($event) {
+ // Determine how far the mouse has been moved
+ const dx = $event.clientX - x;
+
+ // Update the width of column
+ col.style.width = `${w + dx}px`;
+ };
+
+ // When user releases the mouse, remove the existing event listeners
+ // also recalculate grabber height
+ // also save column width to user prefs
+ const mouseUpHandler = function ($event) {
+ document.removeEventListener('pointermove', mouseMoveHandler);
+ document.removeEventListener('pointerup', mouseUpHandler);
+
+ /* Recalculate grabber height in case cells reflowed */
+ this.setColumnHandleHeight(this.gridTable);
+
+ // TODO: save column width in ch
+ };
+
+ resizer.addEventListener('pointerdown', mouseDownHandler);
+
+ // Handle keyboard events
+
+ resizer.addEventListener("keydown", ($event) => {
+ const th = $event.currentTarget.closest("th");
+
+ // TODO: find out if screen reader users would prefer we use a combo (probably)
+ if ($event.code == "ArrowLeft") {
+ th.style.width = (th.offsetWidth - this.charWidth) + 'px';
+ }
+ if ($event.code == "ArrowRight") {
+ th.style.width = (th.offsetWidth + this.charWidth) + 'px';
+ }
+
+ /* Recalculate grabber height in case cells reflowed */
+ this.setColumnHandleHeight(this.gridTable);
+ });
+ }
+
+ setColumnHandleHeight($event) {
+ /* Recalculate all handle heights in case cells reflowed */
+ const tableHeight = this.gridTable.nativeElement.offsetHeight + 'px';
+ console.log("table height is " + tableHeight);
+ this.gridTable.nativeElement.querySelectorAll('.col-resize').forEach((btn) => {
+ this.renderer.setStyle(btn, 'height', tableHeight);
+ });
+ }
}