UNPKG

angular2-data-table

Version:

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

102 lines (79 loc) 2.62 kB
import { Directive, Output, EventEmitter, ContentChildren, QueryList, KeyValueDiffers, AfterContentInit, OnDestroy } from '@angular/core'; import { DraggableDirective } from './draggable.directive'; @Directive({ selector: '[orderable]' }) export class OrderableDirective implements AfterContentInit, OnDestroy { @Output() reorder: EventEmitter<any> = new EventEmitter(); @ContentChildren(DraggableDirective, { descendants: true }) draggables: QueryList<DraggableDirective>; positions: any; differ: any; constructor(differs: KeyValueDiffers) { this.differ = differs.find({}).create(null); } ngAfterContentInit(): void { // HACK: Investigate Better Way this.updateSubscriptions(); this.draggables.changes.subscribe( this.updateSubscriptions.bind(this)); } ngOnDestroy(): void { this.draggables.forEach(d => { d.dragStart.unsubscribe(); d.dragEnd.unsubscribe(); }); } updateSubscriptions(): void { const diffs = this.differ.diff(this.draggables.toArray()); if(diffs) { const subscribe = ({ currentValue, previousValue }: any) => { unsubscribe({ previousValue }); if(currentValue) { currentValue.dragStart.subscribe(this.onDragStart.bind(this)); currentValue.dragEnd.subscribe(this.onDragEnd.bind(this)); } }; const unsubscribe = ({ previousValue }: any) => { if(previousValue) { previousValue.dragStart.unsubscribe(); previousValue.dragEnd.unsubscribe(); } }; diffs.forEachAddedItem(subscribe.bind(this)); diffs.forEachChangedItem(subscribe.bind(this)); diffs.forEachRemovedItem(unsubscribe.bind(this)); } } onDragStart(): void { this.positions = {}; let i = 0; for(let dragger of this.draggables.toArray()) { let elm = dragger.element; this.positions[dragger.dragModel.prop] = { left: parseInt(elm.offsetLeft.toString(), 0), index: i++ }; } } onDragEnd({ element, model }: any) { const newPos = parseInt(element.offsetLeft.toString(), 0); const prevPos = this.positions[model.prop]; let i = 0; for(let prop in this.positions) { let pos = this.positions[prop]; let movedLeft = newPos < pos.left && prevPos.left > pos.left; let movedRight = newPos > pos.left && prevPos.left < pos.left; if(movedLeft || movedRight) { this.reorder.emit({ prevIndex: prevPos.index, newIndex: i, model }); } i++; } element.style.left = 'auto'; } }