Using ng2-dragula to drag and swap grid lists

2.2k Views Asked by At

I have a grid of lists and am trying to drag and swap the tiles of the grid with each other using ng2-dragula

some.component.html

   <md-grid-list rowHeight="200px" id = "cover" >
      <md-grid-tile *ngFor="let werbedata of werbedaten" 
       [class.selected]="werbedata === selectedWerbedata"
       [routerLink]="['/flyerdetail',werbedata.artnr]"
       [style.background]="'lightblue'" class = "blocks"
       [dragula]='"bag-one"'>

     <md-list class="example-card">
         <md-list-item>Produktname: {{ werbedata.werbetext }}</md-list-item>
         <md-list-item>Euro: {{ werbedata.euro }}</md-list-item>
         <h3 md-line> Artnr: {{ werbedata.artnr }} </h3>
         <p md-line> Werbetext: {{ werbedata.werbetext }}  </p>
     </md-list>

   </md-grid-tile>
</md-grid-list>

some.component.ts

export class FlyerComponent implements OnInit { 
    werbedaten: WerbeData[];
    selectedWerbedata: WerbeData;

    constructor( private werbedatenService: WerbeDatenService ){};

    ...
    ...
}

My idea was to swap data on the Drop event. Is there a onDrop event that can be added to the HTML like this?

(onDrop) = "swap(data)" and then do the swap(data:any)in the component class?

or must I initialize the dragulaservice? Is there a better way to swap instead?

I'm absolutely new to angular and I'm finding this ridiculously difficult to follow along. Any tip would be greatly appreciated?

1

There are 1 best solutions below

2
On

For simple dragging from one list to another with ng2-dragula you don't need to act on any event, the directives handle that for you. Swapping from one list to another doesn't appear to be supported, but I've provided a simple setyp and hopefully this will help get you on your way.

First, make sure it is included in your app.module.ts correctly

import { DragulaModule } from 'ng2-dragula';
...
@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        DragulaModule,
        ...
    ],
    providers: [],
      bootstrap: [AppComponent]
    })

export class AppModule {}

In your component you need to create your lists. You may also need to include the css file from node_modules/dragula/dist/dragula.css.

I've added binding to the drop event, as that what you were curious about. This scenario simply prints the new lists to the console and demonstrates the two way binding.

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css', './dragula.min.css']
})

export class AppComponent {

    list1: number[] = [1, 2, 3, 4];
    list2: number[] = [5, 6, 7, 8];

    constructor(private dragulaService: DragulaService) {
        dragulaService.drop.subscribe((value) => {
            this.onDrop(value.slice(1));
        });
    }

    private onDrop(args) {
        console.log(this.list1);
        console.log(this.list2);
    }
}

In your template you need to add the dragula and dragulaModel directives which provides the two-way data binding. Note both lists have the same "bag".

<ul [dragula]='"bag-one"' [dragulaModel]='list1'>
  <li *ngFor="let item of list1">{{ item }}</li>
</ul>
<ul [dragula]='"bag-one"' [dragulaModel]='list2'>
  <li *ngFor="let item of list2">{{ item }}</li>
</ul>