@anglr/grid
Version:
Angular module displaying grid
168 lines • 6.89 kB
JavaScript
import { Directive, ElementRef, HostListener, Inject, Injector, Input, Optional, Renderer2, booleanAttribute, inject } from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';
import { nameof } from '@jscrpt/common';
import { Subscription } from 'rxjs';
import { GRID_INSTANCE, GRID_PLUGIN_INSTANCES, ORDERABLE_CELL } from '../../misc/tokens';
import * as i0 from "@angular/core";
/**
* Directive that is used for handling ordering of column
*/
export class OrderableDirective {
/**
* Gets instance of ordering
*/
get ordering() {
return this.plugins.Ordering;
}
//######################### constructor #########################
constructor(orderable) {
//######################### protected fields #########################
/**
* Subscriptions created during initialization
*/
this.initSubscriptions = new Subscription();
/**
* Indication whether is grid initialized
*/
this.gridInitialized = false;
/**
* Current html element that is this directive attached to
*/
this.element = inject((ElementRef));
/**
* Available instances of grid plugins
*/
this.plugins = inject(GRID_PLUGIN_INSTANCES);
/**
* Instance of renderer used for rendering html
*/
this.renderer = inject(Renderer2);
/**
* Instance of grid
*/
this.grid = inject(GRID_INSTANCE);
/**
* Angular injector used for injecting dependencies
*/
this.injector = inject(Injector);
//######################### public properties - inputs #########################
/**
* Gets or sets indication whether is column orderable or not
*/
this.orderable = false;
if (orderable) {
orderable.orderable = this;
}
}
//######################### public methods - implementation of OnInit #########################
/**
* Initialize component
*/
ngOnInit() {
this.initSubscriptions.add(this.grid.initialized.subscribe(initialized => {
this.gridInitialized = initialized;
this.orderingChangeSubscription?.unsubscribe();
this.orderingChangeSubscription = null;
this.initOrdering();
}));
}
//######################### public methods - implementation of OnChanges #########################
/**
* Called when input value changes
*/
ngOnChanges(changes) {
if (nameof('orderable') in changes) {
this.initOrdering();
}
}
//######################### public methods - implementation of OnDestroy #########################
/**
* Called when component is destroyed
*/
ngOnDestroy() {
this.initSubscriptions.unsubscribe();
this.indicatorRenderer?.destroy(this.element.nativeElement, this.renderer);
}
//######################### protected methods - host #########################
/**
* Handles click event, that should trigger ordering for column
* @param event - Event that occured
*/
orderBy(event) {
if (!this.orderable) {
return;
}
event.preventDefault();
event.stopPropagation();
if (!this.orderById) {
throw new Error('OrderableDirective: missing "orderById"');
}
const ordering = this.plugins.Ordering;
ordering.orderByColumn(this.orderById);
}
//######################### protected methods #########################
/**
* Initialized ordering according current ordering flag
*/
initOrdering() {
if (this.gridInitialized) {
//remove previous indicator and create new one
this.indicatorRenderer?.destroy(this.element.nativeElement, this.renderer);
this.indicatorRenderer = new this.ordering.options.indicatorRenderer();
//remove previous value
if (this.currentCssClass) {
for (const cls of this.currentCssClass.split(' ')) {
this.renderer.removeClass(this.element.nativeElement, cls);
}
this.currentCssClass = null;
}
//is orderable
if (this.orderable) {
//create indicator and apply current ordering
this.indicatorRenderer?.create(this.element.nativeElement, this.renderer);
//add new class
if (this.ordering.options.cssClasses.orderable) {
for (const cls of this.ordering.options.cssClasses.orderable.split(' ')) {
this.renderer.addClass(this.element.nativeElement, cls);
}
this.currentCssClass = this.ordering.options.cssClasses.orderable;
}
}
this.orderingChangeSubscription = toObservable(this.ordering.ordering, { injector: this.injector }).subscribe(() => this.applyCssClasses());
}
}
/**
* Applies css classes according current ordering state
*/
applyCssClasses() {
if (!this.orderable) {
return;
}
if (!this.orderById) {
throw new Error('OrderableDirective: missing "orderById"');
}
this.indicatorRenderer?.apply(this.ordering.getCssClassesForColumn(this.orderById), this.renderer);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.0", ngImport: i0, type: OrderableDirective, deps: [{ token: ORDERABLE_CELL, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.1.0", type: OrderableDirective, isStandalone: true, selector: "[orderable]", inputs: { orderable: ["orderable", "orderable", booleanAttribute], orderById: "orderById" }, host: { listeners: { "click": "orderBy($event)" } }, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0", ngImport: i0, type: OrderableDirective, decorators: [{
type: Directive,
args: [{
selector: '[orderable]',
}]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [ORDERABLE_CELL]
}, {
type: Optional
}] }], propDecorators: { orderable: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], orderById: [{
type: Input
}], orderBy: [{
type: HostListener,
args: ['click', ['$event']]
}] } });
//# sourceMappingURL=orderable.directive.js.map