skip to Main Content

I am trying to build an Angular (v17) application which lets the user to move around with drag and drop HTML elements, even between multiple browser tabs. Similarly to what neo.mjs is capable of (here is a demo: https://www.youtube.com/watch?v=-L43hntj3jk).

I am currently using Material cdDrag, and thinking of writing a custom Angular shared web worker for this but it will be quite difficult if even possible.

Is there an easier way, or even a 3rd party package with which I could achieve this? Or could I somehow implement neo.mjs into my Angular application?

The project has to be Angular (client request).

2

Answers


  1. It’s not that complicated. In this example I have a draggable <li> element and an iframe (the iframe is just to show that you can drag from one document to another). In the parent document, on dragstart I set data on the dataTransfer object to the HTML code being dragged (the <li> element). In the iframe there are handlers for both dragover and drop. When you drop the <li> the HTML will be added to the <ul> in the iframe. Below is the HTML for the iframe.

    You can try to open the iframe document (the data URI string) in a separate tab, and test if you can drag the <li> from the example here to that tab.

    document.querySelector('ul').addEventListener('dragstart', e => {
      e.dataTransfer.setData("text/html", e.target.outerHTML);
    });
    body {
      display: flex;
    }
    <ul>
      <li draggable="true">Item 1</li>
      <li draggable="true">Item 2</li>
    </ul>
    
    <iframe src="data:text/html;base64,PCFET0NUWVBFIGh0bWw+CjxodG1sPgo8aGVhZD4KPHNjcmlwdD4KZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIGUgPT4gewogIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3VsJykuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ292ZXInLCBlID0+IHsKICAgIGUucHJldmVudERlZmF1bHQoKTsKICAgIGUuZGF0YVRyYW5zZmVyLmRyb3BFZmZlY3QgPSAibW92ZSI7CiAgfSk7CgogIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3VsJykuYWRkRXZlbnRMaXN0ZW5lcignZHJvcCcsIGUgPT4gewogICAgZS5wcmV2ZW50RGVmYXVsdCgpOwogICAgZS50YXJnZXQuaW5uZXJIVE1MICs9IGUuZGF0YVRyYW5zZmVyLmdldERhdGEoInRleHQvaHRtbCIpOwogIH0pOwp9KTsKPC9zY3JpcHQ+CjxzdHlsZT4KdWwge21pbi1oZWlnaHQ6IDNlbTsgYm9yZGVyOiB0aGluIGRvdHRlZCBncmF5O30KPC9zdHlsZT4KPC9oZWFkPgo8Ym9keT4KPGRpdj5Ecm9wIHpvbmU6PC9kaXY+Cjx1bD4KPC91bD4KPC9ib2R5Pgo8L2h0bWw+"></iframe>

    Iframe document:

    <!DOCTYPE html>
    <html>
    <head>
    <script>
    document.addEventListener('DOMContentLoaded', e => {
      document.querySelector('ul').addEventListener('dragover', e => {
        e.preventDefault();
        e.dataTransfer.dropEffect = "move";
      });
    
      document.querySelector('ul').addEventListener('drop', e => {
        e.preventDefault();
        e.target.innerHTML += e.dataTransfer.getData("text/html");
      });
    });
    </script>
    <style>
    ul {min-height: 3em; border: thin dotted gray;}
    </style>
    </head>
    <body>
    <div>Drop zone:</div>
    <ul>
    </ul>
    </body>
    </html>
    
    Login or Signup to reply.
  2. by using this third party package we are able to do drag and drop in between the tabs

      npm install interactjs
    

    we could intiate the drag drop and dragend

    interact.service.ts

    import { Injectable } from '@angular/core';
    import interact from 'interactjs';
    
    @Injectable({
      providedIn: 'root'
    })
    export class InteractService {
      constructor() {}
    
      initDragDrop() {
        interact('.draggable')
          .draggable({
            onmove: this.dragMoveListener,
            onend: this.dragEndListener
          })
          .dropzone({
            accept: '.draggable',
            ondrop: this.dropListener
          });
      }
    
      dragMoveListener(event) {
        // Handle drag move
      }
    
      dragEndListener(event) {
        // Handle drag end
      }
    
      dropListener(event) {
        // Handle drop
      }
    }
    

    drag-drop.component.ts

    import { Component, AfterViewInit } from '@angular/core';
    import { InteractService } from './interact.service';
    
    @Component({
      selector: 'app-drag-drop',
      templateUrl: './drag-drop.component.html',
      styleUrls: ['./drag-drop.component.css']
    })
    export class DragDropComponent implements AfterViewInit {
      constructor(private interactService: InteractService) {}
    
      ngAfterViewInit() {
        this.interactService.initDragDrop();
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search