3

Using angular2 material and dragula, I want to drag and drop chips with ng2-dragula library.

Specifying the dragula containers:

<md-chip-list [dragula]="'bag-chips'">
  <md-chip>Chip 1</md-chip>
  <md-chip>Chip 2</md-chip>
</md-chip-list>

<md-chip-list [dragula]="'bag-chips'">
  <md-chip>Chip 3</md-chip>
  <md-chip>Chip 4</md-chip>
</md-chip-list>

The above doesn't work because Angular-material creates a wrapper div.md-chip-list-wrapper inside md-chip-list. When we attempt to drag and drop, the whole wrapper gets dragged.

I tried to fix the problem with dragula's isContainer method, but dragging didn't work at all.

constructor(private dragula: DragulaService) {
  dragula.setOptions('bag-chips', {
    isContainer(el) {
      return el.classList.contains('md-chip-list-wrapper');
    }
  }
}

I tried to fix the problem by adding a div wrapper inside md-chip-list, but that seems to error in angular material.

<md-chip-list>
  <div [dragula]="'bag-chips'">
    <md-chip>Chip</md-chip>
  </div>
</md-chip-list>

So how to make the md-chip-list work with ng2-dragula?

mrkvon
  • 3,507
  • 2
  • 21
  • 26
  • 1
    An advice from a personal point of view ; I had issues with `Dragula` and I found an awesome easy to use alternative : https://github.com/akserg/ng2-dnd .. hope that will help once you'll find your self on a dead end. – SeleM Feb 17 '17 at 23:33
  • 1
    Thank you @5313m, I'm in the process of exploring `ng2-dnd` as an alternative. Also, hopefully drag and drop feature would be implemented in Angular material natively. – mrkvon Feb 17 '17 at 23:51
  • 1
    Sorry, but what is wrong here? https://plnkr.co/edit/eFKVzwG1GmrNV9sfwesX?p=preview – yurzui Feb 18 '17 at 06:40
  • @yurzui, thanks. Seeing your example, I removed the `[dragula]="'bag-foo'"` from the template and added `direction: horizontal` to my drake options and it worked. It still feels a bit hacky solution, because it depends on implementation of angular-material (refering to `md-chip-list-wrapper` class). If anything changes there, this will cease to work. Anyways, if you make this to an answer, I'll accept it. Otherwise I'll write one. – mrkvon Feb 19 '17 at 15:10
  • There is another issue with rearranging the `md-chip-list`. After rearranging by drag and drop, it keeps the original order when selected and navigated with arrows. The order doesn't update, as can be seen on plunker by @yurzui. Not sure if that's the scope of this question, though. – mrkvon Feb 19 '17 at 16:25

1 Answers1

4

A dragula solution

Using dragula options isContainer and direction seem to do the trick:

// drake-example.component.ts
constructor(private dragula: DragulaService) {
  dragula.setOptions('bag-chips', {
    isContainer(el) {
      return el.classList.contains('md-chip-list-wrapper');
    },
    direction: 'horizontal' // or 'vertical'
  }
}
<!-- drake-example.component.html -->
<md-chip-list>
  <md-chip>Chip 1</md-chip>
  <md-chip>Chip 2</md-chip>
</md-chip-list>

<md-chip-list>
  <md-chip>Chip 3</md-chip>
  <md-chip>Chip 4</md-chip>
</md-chip-list>

Credits for a plunker go to @yurzui

Warnings

  • The md-chip-list-wrapper class might need to be changed according to the current angular-material implementation.
  • The order of md-chips in md-chip-list doesn't update. i.e. after rearranging md-chips, navigating them with arrows will be confused (see the plunker above).

The actual solution (digression)

I went with ng2-dnd library. It provides dnd-draggable and dnd-droppable directives to explicitly state which elements can be dragged and where they can be dropped.

Overall, the solution is more complex, but also more customizable and intuitive. The draggable doesn't have to be the immediate parent of the droppable.

Community
  • 1
  • 1
mrkvon
  • 3,507
  • 2
  • 21
  • 26