Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to drag/drop to multiple Angular2 component using ng2-dragula

I have a Angular2 component using ng2-dragula to drag/drop like this:

@Component({
  selector: 'my-comp',
  directives: [
    Dragula
  ],
  viewProviders: [
    DragulaService
  ],
  template: `
    <div class="my-div">
      <div *ngFor="#item of items" [dragula]='"card-bag"' [dragulaModel]='items'>
      ...
      </div>
    </div>
  `
})

My issue: if I create multiple "my-comp" component, item inside "card-bag" can not drag/drop across these component although they have the same bag name. These item are only able to drag/drop inside it owned component.

Do we have any configs for drag/drop across components, or this is ng2-dragula limitation?

Thanks.

like image 401
qnreck Avatar asked Mar 14 '16 06:03

qnreck


2 Answers

If you are not using [dragulaModel] then drag and drop between nested components works well as long as you only set viewProviders: [ DragulaService ] once in the top/root component.

Remember not to set viewProviders: [ DragulaService ] in other components as it creates new instances for every component.

Edit: Recently I have implemented the given scenario using ng2-dnd npm package. Its better than ng2-dragula and offers easy object passing and other things. It might Solve your issue.

like image 120
Bhushan Gadekar Avatar answered Oct 20 '22 00:10

Bhushan Gadekar


I got a tree structure drag and drop working like this:

Top level component

  • CSS ViewEncapsulation.None, include any css here
  • Dragula Directive
  • DragulaService ViewProvider
  • Registering an accepts filter on the dragula service that stops items from being dropped inside themselves

    accepts: (el: Element, target: Element, source: Element, sibling: Element): boolean => {
     return !el.contains(target); // elements can not be dropped within themselves
    },
    
  • Registering a moves filter on the dragula service so that an entire item is moved together

    moves: (el: Element, container: Element, handle: Element): boolean => {
      // only move favorite items, not the icon element
      return el.tagName.toLowerCase() === 'mvp-navigation-item';
    },
    
  • Html template looks like this

    <div class="nav--favorites__root" [class.is-dragging]="isDragging" [dragula]="'favorites'" [dragulaModel]="favoriteLinks">
      <navigation-item *ngFor="let link of links" [link]="link">
      </navigation-item>
    </div>
    

Navigation item component

  • Dragula Directive
  • No DragulaService ViewProvider
  • Html template looks like this

    <a href class="list-group-item" linkActive="active" [linkTo]="link?.url" (click)="followLink($event, link)">
      <span class="glyphicon glyphicon-{{link?.icon ? link?.icon : 'unchecked'}}"></span>
      <span class="nav__label">{{link?.label}}</span>
    </a>
    <div *ngIf="link?.children" class="list-group list-group-inverse nav--favorites__submenu" [class.is-expanded]="link?.isExpanded" [class.is-empty]="link?.children?.length === 0" [dragula]="'favorites'" [dragulaModel]="link?.children">
      <navigation-item *ngFor="let childLink of link?.children" [link]="childLink">
      </navigation-item>
      <!-- the nav favorites items must be the first elements in the dragula container or the model sync gets confused -->
      <a class="btn btn-link toggle" (click)="link.isExpanded = !link.isExpanded; $event.preventDefault();"><span class="glyphicon glyphicon-triangle-{{link?.isExpanded ? 'top' : 'bottom'}}"></span></a>
    </div>
    

You'll need to style things to make the .nav--favorites__submenu visible as a drop target while dragging an item.

like image 41
Isaac Avatar answered Oct 20 '22 01:10

Isaac