ng2-dnd
Version:
Angular 2 Drag-and-Drop without dependencies
152 lines (128 loc) • 6.51 kB
text/typescript
// Copyright (C) 2016 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg/ng2-dnd
import {Injectable} from 'angular2/core';
import {Directive, Input, Output, EventEmitter, ElementRef} from 'angular2/core';
import {AbstractComponent} from './dnd.component';
import {DragDropConfig, DragImage} from './dnd.config';
import {DroppableComponent} from './dnd.droppable';
import {DraggableComponent} from './dnd.draggable';
import {DragDropService, DragDropSortableService} from './dnd.service';
export class SortableContainer extends AbstractComponent {
set draggable(value:boolean) {
this.dragEnabled = !!value;
}
private _sortableData: Array<any> = [];
set sortableData(sortableData: Array<any>) {
this._sortableData = sortableData;
//
this.dropEnabled = this._sortableData.length === 0;
// console.log("collection is changed, drop enabled: " + this.dropEnabled);
}
get sortableData(): Array<any> {
return this._sortableData;
}
set dropzones(value:Array<string>) {
this.dropZones = value;
}
constructor(elemRef: ElementRef, _dragDropService: DragDropService, _config:DragDropConfig, private _sortableDataService: DragDropSortableService) {
super(elemRef, _dragDropService, _config);
this.dragEnabled = false;
}
_onDragEnterCallback(event: Event) {
let item:any = this._sortableDataService.sortableData[this._sortableDataService.index];
// Check does element exist in sortableData of this Container
if (this._sortableData.indexOf(item) === -1) {
// Let's add it
// console.log('Container._onDragEnterCallback. drag node [' + this._sortableDataService.index.toString() + '] over parent node');
// Remove item from previouse list
this._sortableDataService.sortableData.splice(this._sortableDataService.index, 1);
// Add item to new list
this._sortableData.push(item);
this._sortableDataService.sortableData = this._sortableData;
this._sortableDataService.index = 0;
}
}
}
export class SortableComponent extends AbstractComponent {
index: number;
set draggable(value:boolean) {
this.dragEnabled = !!value;
}
set droppable(value:boolean) {
this.dropEnabled = !!value;
}
/**
* The data that has to be dragged. It can be any JS object
*/
dragData: any;
/**
* Callback function called when the drag action ends with a valid drop action.
* It is activated after the on-drop-success callback
*/
onDragSuccessCallback: EventEmitter<any> = new EventEmitter<any>();
/**
* Callback function called when the drop action completes correctly.
* It is activated before the on-drag-success callback.
*/
onDropSuccessCallback: EventEmitter<any> = new EventEmitter<any>();
constructor(elemRef: ElementRef, _dragDropService: DragDropService, _config:DragDropConfig, private _sortableContainer: SortableContainer, private _sortableDataService: DragDropSortableService) {
super(elemRef, _dragDropService, _config);
this.dropZones = this._sortableContainer.dropZones;
this.dragEnabled = true;
this.dropEnabled = true;
}
_onDragStartCallback(event: Event) {
// console.log('_onDragStartCallback. dragging elem with index ' + this.index);
this._sortableDataService.sortableData = this._sortableContainer.sortableData;
this._sortableDataService.index = this.index;
this._sortableDataService.markSortable(this._elem);
// Add dragData
this._dragDropService.dragData = this.dragData;
this._dragDropService.onDragSuccessCallback = this.onDragSuccessCallback;
}
_onDragOverCallback(event: Event) {
if (this._elem != this._sortableDataService.elem) {
// console.log('_onDragOverCallback. dragging elem with index ' + this.index);
this._sortableDataService.sortableData = this._sortableContainer.sortableData;
this._sortableDataService.index = this.index;
this._sortableDataService.markSortable(this._elem);
}
}
_onDragEndCallback(event: Event) {
// console.log('_onDragEndCallback. end dragging elem with index ' + this.index);
this._sortableDataService.sortableData = null;
this._sortableDataService.index = null;
this._sortableDataService.markSortable(null);
// Add dragGata
this._dragDropService.dragData = null;
this._dragDropService.onDragSuccessCallback = null;
}
_onDragEnterCallback(event: Event) {
this._sortableDataService.markSortable(this._elem);
if ((this.index !== this._sortableDataService.index) ||
(this._sortableDataService.sortableData != this._sortableContainer.sortableData)) {
// console.log('Component._onDragEnterCallback. drag node [' + this.index + '] over node [' + this._sortableDataService.index + ']');
// Get item
let item:any = this._sortableDataService.sortableData[this._sortableDataService.index];
// Remove item from previouse list
this._sortableDataService.sortableData.splice(this._sortableDataService.index, 1);
// Add item to new list
this._sortableContainer.sortableData.splice(this.index, 0, item);
this._sortableDataService.sortableData = this._sortableContainer.sortableData;
this._sortableDataService.index = this.index;
}
}
_onDropCallback (event: Event) {
if (this.onDropSuccessCallback) {
// console.log('onDropCallback.onDropSuccessCallback.dragData', this._dragDropService.dragData);
this.onDropSuccessCallback.emit(this._dragDropService.dragData);
}
if (this._dragDropService.onDragSuccessCallback) {
// console.log('onDropCallback.onDragSuccessCallback.dragData', this._dragDropService.dragData);
this._dragDropService.onDragSuccessCallback.emit(this._dragDropService.dragData);
}
}
}