Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using HTML5 drag and drop with Angular material 2 md-list

Consider the following Component template, I am trying to achieve ability to reorder list elements for angular material 2 and simple li-tag.

This functionality works perfectly for li-tag tag but fails to work in case of md-list-item

why is that?

My template:

<md-nav-list>
  <md-list-item *ngFor="let i of arr" draggable="true" (dragenter)="dragenter($event)" (dragstart)="dragstart($event)">
    {{i}}
  </md-list-item>
</md-nav-list>

<ul>
  <li *ngFor="let i of arr" draggable="true" (dragenter)="dragenter($event)" (dragstart)="dragstart($event)">{{i}}</li>
</ul>

Called functions:

  source: any;

  /**
   * CHECKS IF ONE ELEMENT LIES BEFORE THE OTHER
  */
  isbefore(a, b) {
    if (a.parentNode == b.parentNode) {
      for (var cur = a; cur; cur = cur.previousSibling) {
        if (cur === b) {
          return true;
        }
      }
    }
    return false;
  }
  /**
   * LIST ITEM DRAP ENTERED
  */
  dragenter($event) {
    if (this.isbefore(this.source, $event.target)) {
      $event.target.parentNode.insertBefore(this.source, $event.target); // insert before
    }
    else {
      $event.target.parentNode.insertBefore(this.source, $event.target.nextSibling); //insert after
    }
  }


  /**
   * LIST ITEM DRAG STARTED
   */
  dragstart($event) {
    this.source = $event.target;
    $event.dataTransfer.effectAllowed = 'move';
  }

Screenshot of the issue:

click to view this image

As visible in the screenshot when I drag any md-list-item browser starts dragging all content even from the parent component.

like image 678
Saif Avatar asked May 04 '26 06:05

Saif


1 Answers

Use event.currentTarget instead of event.target because md-list-item has nested div while you need to move md-list-item

/**
 * LIST ITEM DRAP ENTERED
 */
dragenter($event) {
    let target = $event.currentTarget;
    if (this.isbefore(this.source, target)) {
        target.parentNode.insertBefore(this.source, target); // insert before
    }
    else {
        target.parentNode.insertBefore(this.source, target.nextSibling); //insert after
    }
}


/**
 * LIST ITEM DRAG STARTED
 */
dragstart($event) {
    this.source = $event.currentTarget;
    $event.dataTransfer.effectAllowed = 'move';
}

and disable ripple effect

<md-list-item [disableRipple]="true"

to be able to drag only one item

Plunker Example

like image 90
yurzui Avatar answered May 05 '26 19:05

yurzui