<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://unpkg.com/ng2-dnd@5.0.0/bundles/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<title>NG2-DnD Demo</title>
<base href="">
</head>
<body style="padding-top: 5rem;">
<div class="container">
<my-app>
<span class="sr-only">Loading...</span>
</my-app>
</div>
<script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js/dist/zone.js"></script>
<script src="https://unpkg.com/zone.js/dist/long-stack-trace-zone.js"></script>
<script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
<script src="https://unpkg.com/systemjs@0.19.31/dist/system.js"></script>
<script src="config.js"></script>
<script>
System.import('app').catch(function (err) {
console.error(err);
});
</script>
</body>
</html>
// Copyright (C) 2016-2018 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
System.config({
//use typescript for compilation
transpiler: 'typescript',
//typescript compiler options
typescriptOptions: {
emitDecoratorMetadata: true
},
paths: {
'npm:': 'https://unpkg.com/'
},
//map tells the System loader where to look for things
map: {
'app': './src',
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
'rxjs': 'npm:rxjs',
'typescript': 'npm:typescript@2.0.2/lib/typescript.js',
'ng2-dnd': 'npm:ng2-dnd@5.0.0/bundles/ng2-dnd.umd.js'
},
//packages defines our app package
packages: {
app: {
main: './main.ts',
defaultExtension: 'ts'
},
rxjs: {
defaultExtension: 'js'
}
}
});
// Copyright (C) 2016-2018 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import { Component, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { SimpleDndComponent } from 'src/simple-dnd';
import { ZoneDndComponent } from 'src/zone-dnd';
import { CustomDataDndComponent } from 'src/custom-data-dnd';
import { CustomFunctionDndComponent } from 'src/custom-function-dnd';
import { ShoppingBasketDndComponent } from 'src/shopping-basket-dnd';
import { SimpleSortableComponent } from 'src/simple-sortable';
import { RecycleMultiSortableComponent } from 'src/recycle-multi-sortable';
import { SimpleSortableCopyComponent } from 'src/simple-sortable-copy';
import { MultiSortableComponent } from 'src/multi-sortable';
import { EmbeddedSortableComponent } from 'src/embedded-sortable';
import { DndModule } from 'ng2-dnd';
@Component({
selector: 'my-app',
template: `
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="https://github.com/akserg/ng2-dnd">NG2-DnD</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a [routerLink]="['/simple']">Simple DnD</a></li>
<li><a [routerLink]="['/simple-zone']">Zone Areas</a></li>
<li><a [routerLink]="['/simple-custom-data']">Custom Data</a></li>
<li><a [routerLink]="['/simple-custom-function']">Custom Functions</a></li>
<li><a [routerLink]="['/simple-shopping']">Shopping Example</a></li>
<li role="separator" class="divider"></li>
<li><a [routerLink]="['/sortable']">Sortable</a></li>
<li><a [routerLink]="['/sortable-recycle']">Recycle bin</a></li>
<li><a [routerLink]="['/sortable-copy']">Copy example</a></li>
<li><a [routerLink]="['/sortable-multy']">Multi Sortable</a></li>
<li><a [routerLink]="['/sortable-embedded']">Embedded</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<router-outlet></router-outlet>`
})
export class App {
}
@NgModule({
imports: [ BrowserModule, DndModule.forRoot(), FormsModule,
RouterModule.forRoot([
{ path: '', redirectTo: '/simple', pathMatch: 'full' },
{ path: 'simple', component: SimpleDndComponent },
{ path: 'simple-zone', component: ZoneDndComponent },
{ path: 'simple-custom-data', component: CustomDataDndComponent },
{ path: 'simple-custom-function', component: CustomFunctionDndComponent },
{ path: 'simple-shopping', component: ShoppingBasketDndComponent },
{ path: 'sortable', component: SimpleSortableComponent },
{ path: 'sortable-recycle', component: RecycleMultiSortableComponent },
{ path: 'sortable-copy', component: SimpleSortableCopyComponent },
{ path: 'sortable-multy', component: MultiSortableComponent },
{ path: 'sortable-embedded', component: EmbeddedSortableComponent },
])
],
declarations: [ App,
SimpleDndComponent, ZoneDndComponent, CustomFunctionDndComponent, CustomDataDndComponent, ShoppingBasketDndComponent,
SimpleSortableComponent, RecycleMultiSortableComponent, SimpleSortableCopyComponent, MultiSortableComponent, EmbeddedSortableComponent,
],
bootstrap: [ App ]
})
export class AppModule {
}
// Copyright (C) 2016-2018 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from './app';
platformBrowserDynamic().bootstrapModule(AppModule)
// Copyright (C) 2016-2018 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import {Component} from '@angular/core';
@Component({
selector: 'simple-dnd',
template: `
<h4>Simple Drag-and-Drop operations with no code</h4>
<div class="row">
<div class="col-sm-3">
<div class="panel panel-success">
<div class="panel-heading">Available to drag</div>
<div class="panel-body">
<div class="panel panel-default" dnd-draggable [dragEnabled]="true">
<div class="panel-body">
<div>Drag Me</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div dnd-droppable class="panel panel-info" (onDropSuccess)="simpleDrop=$event">
<div class="panel-heading">Place to drop</div>
<div class="panel-body">
<div *ngIf="simpleDrop">Item was dropped here</div>
</div>
</div>
</div>
</div>`
})
export class SimpleDndComponent {
simpleDrop: any = null;
}
// Copyright (C) 2016-2018 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import {Component} from '@angular/core';
@Component({
selector: 'zone-dnd',
template: `
<h4>Restricted Drag-and-Drop with zones</h4>
<div class="row">
<div class="col-sm-3">
<div class="panel panel-primary">
<div class="panel-heading">Available to drag</div>
<div class="panel-body">
<div class="panel panel-default" dnd-draggable [dragEnabled]="true" [dropZones]="['zone1']">
<div class="panel-body">
<div>Drag Me</div>
<div>Zone 1 only</div>
</div>
</div>
</div>
</div>
<div class="panel panel-success">
<div class="panel-heading">Available to drag</div>
<div class="panel-body">
<div class="panel panel-default" dnd-draggable [dragEnabled]="true" [dropZones]="['zone1', 'zone2']">
<div class="panel-body">
<div>Drag Me</div>
<div>Zone 1 & 2</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div dnd-droppable class="panel panel-info" [dropZones]="['zone1']" (onDropSuccess)="restrictedDrop1=$event">
<div class="panel-heading">Zone 1</div>
<div class="panel-body">
<div *ngIf="restrictedDrop1">Item was dropped here</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div dnd-droppable class="panel panel-warning" [dropZones]="['zone2']" (onDropSuccess)="restrictedDrop2=$event">
<div class="panel-heading">Zone 2</div>
<div class="panel-body">
<div *ngIf="restrictedDrop2">Item was dropped here</div>
</div>
</div>
</div>
</div>`
})
export class ZoneDndComponent {
restrictedDrop1: any = null;
restrictedDrop2: any = null;
}
// Copyright (C) 2016-2018 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import {Component} from '@angular/core';
@Component({
selector: 'custom-data-dnd',
template: `
<h4>Transfer custom data in Drag-and-Drop</h4>
<div class="row">
<div class="col-sm-3">
<div class="panel panel-success">
<div class="panel-heading">Available to drag</div>
<div class="panel-body">
<div class="panel panel-default" dnd-draggable [dragEnabled]="true" [dragData]="transferData">
<div class="panel-body">
<div>Drag Me</div>
<div>{{transferData | json}}</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div dnd-droppable class="panel panel-info" (onDropSuccess)="transferDataSuccess($event)">
<div class="panel-heading">Place to drop (Items:{{receivedData.length}})</div>
<div class="panel-body">
<div [hidden]="!receivedData.length > 0" *ngFor="let data of receivedData">{{data | json}}</div>
</div>
</div>
</div>
</div>`
})
export class CustomDataDndComponent {
transferData: Object = {id: 1, msg: 'Hello'};
receivedData: Array<any> = [];
transferDataSuccess($event: any) {
this.receivedData.push($event);
}
}
// Copyright (C) 2016-2018 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import { Component } from '@angular/core';
@Component({
selector: 'custom-function-dnd',
template: `
<h4>Use a custom function to determine where dropping is allowed</h4>
<div class="row">
<div class="col-sm-3">
<div class="panel panel-success">
<div class="panel-heading">Available to drag</div>
<div class="panel-body">
<div class="panel panel-default" dnd-draggable [dragData]="6">
<div class="panel-body">dragData = 6</div>
</div>
<div class="panel panel-default" dnd-draggable [dragData]="10">
<div class="panel-body">dragData = 10</div>
</div>
<div class="panel panel-default" dnd-draggable [dragData]="30">
<div class="panel-body">dragData = 30</div>
</div>
</div>
</div>
</div>
<div class="col-sm-6">
<pre>allowDropFunction(baseInteger: any): any {{ '{' }}
return (dragData: any) => dragData % baseInteger === 0;
{{ '}' }}</pre>
<div class="row">
<div class="col-sm-6">
<div dnd-droppable class="panel panel-info" [allowDrop]="allowDropFunction(box1Integer)" (onDropSuccess)="addTobox1Items($event)">
<div class="panel-heading">
Multiples of
<input type="number" [(ngModel)]="box1Integer" style="width: 4em">
only
</div>
<div class="panel-body">
<div *ngFor="let item of box1Items">dragData = {{item}}</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div dnd-droppable class="panel panel-warning" [allowDrop]="allowDropFunction(box2Integer)" (onDropSuccess)="addTobox2Items($event)">
<div class="panel-heading">
Multiples of
<input type="number" [(ngModel)]="box2Integer" style="width: 4em">
only
</div>
<div class="panel-body">
<div *ngFor="let item of box2Items">dragData = {{item}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
`
})
export class CustomFunctionDndComponent {
box1Integer: number = 3;
box2Integer: number = 10;
box1Items: string[] = [];
box2Items: string[] = [];
allowDropFunction(baseInteger: number): any {
return (dragData: any) => dragData % baseInteger === 0;
}
addTobox1Items($event: any) {
this.box1Items.push($event.dragData);
}
addTobox2Items($event: any) {
this.box2Items.push($event.dragData);
}
}
// Copyright (C) 2016-2018 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import { Component } from '@angular/core';
@Component({
selector: 'shoping-basket-dnd',
template: `
<h4>Drag-and-Drop - Shopping basket</h4>
<div class="row">
<div class="col-sm-3">
<div class="panel panel-success">
<div class="panel-heading">Available products</div>
<div class="panel-body">
<div *ngFor="let product of availableProducts" class="panel panel-default"
dnd-draggable [dragEnabled]="product.quantity>0" [dragData]="product" (onDragSuccess)="orderedProduct($event)" [dropZones]="['demo1']">
<div class="panel-body">
<div [hidden]="product.quantity===0">{{product.name}} - \${{product.cost}}<br>(available: {{product.quantity}})</div>
<div [hidden]="product.quantity>0"><del>{{product.name}}</del><br>(NOT available)</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div dnd-droppable (onDropSuccess)="addToBasket($event)" [dropZones]="['demo1']" class="panel panel-info">
<div class="panel-heading">Shopping Basket<br>(to pay: \${{totalCost()}})</div>
<div class="panel-body">
<div *ngFor="let product of shoppingBasket" class="panel panel-default">
<div class="panel-body">
{{product.name}}<br>(ordered: {{product.quantity}}<br>cost: \${{product.cost * product.quantity}})
</div>
</div>
</div>
</div>
</div>
</div>`
})
export class ShoppingBasketDndComponent {
availableProducts: Array<Product> = [];
shoppingBasket: Array<Product> = [];
constructor() {
this.availableProducts.push(new Product('Blue Shoes', 3, 35));
this.availableProducts.push(new Product('Good Jacket', 1, 90));
this.availableProducts.push(new Product('Red Shirt', 5, 12));
this.availableProducts.push(new Product('Blue Jeans', 4, 60));
}
orderedProduct($event: any) {
let orderedProduct: Product = $event.dragData;
orderedProduct.quantity--;
}
addToBasket($event: any) {
let newProduct: Product = $event.dragData;
for (let indx in this.shoppingBasket) {
let product: Product = this.shoppingBasket[indx];
if (product.name === newProduct.name) {
product.quantity++;
return;
}
}
this.shoppingBasket.push(new Product(newProduct.name, 1, newProduct.cost));
this.shoppingBasket.sort((a: Product, b: Product) => {
return a.name.localeCompare(b.name);
});
}
totalCost(): number {
let cost: number = 0;
for (let indx in this.shoppingBasket) {
let product: Product = this.shoppingBasket[indx];
cost += (product.cost * product.quantity);
}
return cost;
}
}
class Product {
constructor(public name: string, public quantity: number, public cost: number) {}
}
// Copyright (C) 2016-2018 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import {Component} from '@angular/core';
@Component({
selector: 'simple-sortable',
template: `
<h4>Simple sortable</h4>
<div class="row">
<div class="col-sm-3">
<div class="panel panel-success">
<div class="panel-heading">
Favorite drinks
</div>
<div class="panel-body">
<ul class="list-group" dnd-sortable-container [sortableData]="listOne">
<li *ngFor="let item of listOne; let i = index" class="list-group-item" dnd-sortable [sortableIndex]="i">{{item}}</li>
</ul>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-body">
My prefences:<br/>
<span *ngFor="let item of listOne; let i = index">{{i + 1}}) {{item}}<br/></span>
</div>
</div>
</div>
</div>`
})
export class SimpleSortableComponent {
listOne: Array<string> = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];
}
// Copyright (C) 2016-2018 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import {Component} from '@angular/core';
@Component({
selector: 'recycle-multi-sortable',
template: `
<h4>Simple sortable With Drop into recycle bin</h4>
<div class="row">
<div class="col-sm-3">
<div class="panel panel-success">
<div class="panel-heading">
Favorite drinks
</div>
<div class="panel-body" dnd-sortable-container [sortableData]="listOne" [dropZones]="['delete-dropZone']">
<ul class="list-group">
<li *ngFor="let item of listOne; let i = index" class="list-group-item"
dnd-sortable [sortableIndex]="i">{{item}}</li>
</ul>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-body" dnd-sortable-container [dropZones]="['delete-dropZone']" [sortableData]="listRecycled">
Recycle bin: Drag into me to delete it<br/>
</div>
</div>
<div *ngIf="listRecycled.length">
<b>Recycled:</b> <span>{{listRecycled.toString()}} </span>
</div>
</div>
</div>`
})
export class RecycleMultiSortableComponent {
listOne: Array<string> = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];
listRecycled: Array<string> = [];
}
// Copyright (C) 2016-2018 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import {Component} from '@angular/core';
@Component({
selector: 'simple-sortable-copy',
template: `
<h4>Simple sortable With Drop into something, without delete it</h4>
<div class="row">
<div class="col-sm-3">
<div class="panel panel-warning"
dnd-sortable-container [sortableData]="sourceList" [dropZones]="['source-dropZone']">
<div class="panel-heading">Source List</div>
<div class="panel-body">
<ul class="list-group">
<li *ngFor="let source of sourceList; let x = index" class="list-group-item"
dnd-sortable [sortableIndex]="x" [dragEnabled]="true"
[dragData]="source">{{source.name}}</li>
</ul>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="panel panel-info">
<div class="panel-heading">Target List</div>
<div class="panel-body" dnd-droppable (onDropSuccess)="addTo($event)" [dropZones]="['source-dropZone']">
<ul class="list-group">
<li *ngFor="let target of targetList" class="list-group-item">
{{target.name}}
</li>
</ul>
</div>
</div>
</div>
</div>`
})
export class SimpleSortableCopyComponent {
sourceList: Widget[] = [
new Widget('1'), new Widget('2'),
new Widget('3'), new Widget('4'),
new Widget('5'), new Widget('6')
];
targetList: Widget[] = [];
addTo($event: any) {
this.targetList.push($event.dragData);
}
}
class Widget {
constructor(public name: string) {}
}
// Copyright (C) 2016-2018 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import { Component } from '@angular/core';
@Component({
selector: 'multi-sortable',
template: `
<h4>Multi list sortable</h4>
<div class="row">
<div class="col-sm-3">
<div class="panel panel-warning">
<div class="panel-heading">
Available boxers
</div>
<div class="panel-body" dnd-sortable-container [dropZones]="['boxers-zone']" [sortableData]="listBoxers">
<ul class="list-group" >
<li *ngFor="let item of listBoxers; let i = index" class="list-group-item" dnd-sortable [sortableIndex]="i">{{item}}</li>
</ul>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="panel panel-success">
<div class="panel-heading">
First Team
</div>
<div class="panel-body" dnd-sortable-container [dropZones]="['boxers-zone']" [sortableData]="listTeamOne">
<ul class="list-group" >
<li *ngFor="let item of listTeamOne; let i = index" class="list-group-item" dnd-sortable [sortableIndex]="i">{{item}}</li>
</ul>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="panel panel-info">
<div class="panel-heading">
Second Team
</div>
<div class="panel-body" dnd-sortable-container [dropZones]="['boxers-zone']" [sortableData]="listTeamTwo">
<ul class="list-group">
<li *ngFor="let item of listTeamTwo; let i = index" class="list-group-item" dnd-sortable [sortableIndex]="i">{{item}}</li>
</ul>
</div>
</div>
</div>
</div>`
})
export class MultiSortableComponent {
listBoxers: Array<string> = ['Sugar Ray Robinson', 'Muhammad Ali', 'George Foreman', 'Joe Frazier', 'Jake LaMotta', 'Joe Louis', 'Jack Dempsey', 'Rocky Marciano', 'Mike Tyson', 'Oscar De La Hoya'];
listTeamOne: Array<string> = [];
listTeamTwo: Array<string> = [];
}
// Copyright (C) 2016-2018 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import {Component} from '@angular/core';
@Component({
selector: 'embedded-sortable',
template: `
<h4>Move items between multi list sortable containers</h4>
<div class="row">
<div class="col-sm-3">
Drag Containers <input type="checkbox" [(ngModel)]="dragOperation"/>
<div dnd-sortable-container [sortableData]="containers" [dropZones]="['container-dropZone']">
<div class="col-sm3"
*ngFor="let container of containers; let i = index"
dnd-sortable [sortableIndex]="i" [dragEnabled]="dragOperation">
<div class="panel panel-warning"
dnd-sortable-container [sortableData]="container.widgets" [dropZones]="['widget-dropZone']">
<div class="panel-heading">
{{container.id}} - {{container.name}}
</div>
<div class="panel-body">
<ul class="list-group">
<li *ngFor="let widget of container.widgets; let x = index" class="list-group-item"
dnd-sortable [sortableIndex]="x" [dragEnabled]="!dragOperation"
[dragData]="widget">{{widget.name}}</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="panel panel-info">
<div class="panel-heading">Widgets</div>
<div class="panel-body" dnd-droppable (onDropSuccess)="addTo($event)" [dropZones]="['widget-dropZone']">
<div *ngFor="let widget of widgets" class="panel panel-default">
<div class="panel-body">
{{widget.name}}
</div>
</div>
</div>
</div>
</div>
</div>`
})
export class EmbeddedSortableComponent {
dragOperation: boolean = false;
containers: Array<Container> = [
new Container(1, 'Container 1', [new Widget('1'), new Widget('2')]),
new Container(2, 'Container 2', [new Widget('3'), new Widget('4')]),
new Container(3, 'Container 3', [new Widget('5'), new Widget('6')])
];
widgets: Array<Widget> = [];
addTo($event: any) {
if ($event) {
this.widgets.push($event.dragData);
}
}
}
class Container {
constructor(public id: number, public name: string, public widgets: Array<Widget>) {}
}
class Widget {
constructor(public name: string) {}
}