reppners / ngx-drag-drop

Angular directives using the native HTML Drag And Drop API
https://reppners.github.io/ngx-drag-drop/
BSD 3-Clause "New" or "Revised" License
299 stars 118 forks source link

Listitem draggable and dropzone on condition #32

Closed Keksdroid closed 5 years ago

Keksdroid commented 5 years ago

Is your feature request related to a problem? Please describe. I'm trying to implement a list that contains Items and Folders, just like a Windows Explorer. The list is sortable via drag and drop and items can be moved inside folder, but, folders cant moved into items. Is it possible to implement something like this with this library?

Describe the solution you'd like Here is what I tried so far, but with this way folders cant be moved.

<tbody class="table-body dndList" 
    dndDropzone 
    (dndDragover)="onDragover($event)"
    dndEffectAllowed="copyMove"
    (dndDrop)="onDrop($event, listEntries)" >

     <!--optional placeholder element for dropzone-->
    <!--will be removed from DOM on init-->
    <div  dndPlaceholderRef class="dndPlaceholder"></div>

    <tr class="table-row"  *ngFor="let entry of listEntries"
        [dndDraggable]="entry"
                [dndDisableIf]="false"
                (dndStart)="onDragStart($event)"
                (dndMoved)="onDragged(entry, listEntries, 'move')"
                (dndCanceled)="onDragged(entry, listEntries, 'none')"
        (dndEnd)="onDragEnd($event)"
        [dndEffectAllowed]="!entry.hasOwnProperty('isFolder') ? 'move' : null"

        [attr.dndDropzone] = "entry.hasOwnProperty('isFolder') ? '' : null" 
        (dndDragover)="entry.hasOwnProperty('isFolder') && onDragover($event)"
        [attr.dndEffectAllowed]="entry.hasOwnProperty('isFolder') ? 'copyMove' : null"
        (dndDrop)="entry.hasOwnProperty('subfolders') && onDrop($event, listEntries)" >
</tr>
</tbody>
onDragged(item: any, list: any[], effect: DropEffect) {
    if (effect === 'move') {

      const index = list.indexOf(item);
      list.splice(index, 1);
    }
  }

  onDrop(event: DndDropEvent, list?: any[]) {

    if (list && (event.dropEffect === 'copy'  || event.dropEffect === 'move')) {

      let index = event.index;

      if (typeof index === 'undefined') {

        index = list.length;
      }

      list.splice(index, 0, event.data);
    }
  }
reppners commented 5 years ago

Does this help you as a starting point? https://stackblitz.com/edit/ngx-drag-drop-issue-template-9dgxtj?file=src%2Fapp%2Fapp.component.html

Keksdroid commented 5 years ago

Hey, thanks for this example. Unfortunately, expanding directories inside the list is not allowed. The listitem itself should become a dropzone on dragover.

reppners commented 5 years ago

Second try https://stackblitz.com/edit/ngx-drag-drop-issue-template-9dgxtj?file=src%2Fapp%2Fapp.component.html

Keksdroid commented 5 years ago

Exactly what I was looking for! Thanks a lot! It works in my project. Just two minor problem:

  1. If there is an directory at the top of the list, I'm unable to drop a file above it. You can reproduce it in your example. If there is a file at the first index, everything is fine. I already tried some workaround with padding or margin, but nothing worked. Same problem if I want two drop a file between two folders.
  2. My console is full with "cannot read property 'removeChild' of null, at ...DndDropzoneDirective.cleanupDragoverState and .DndDropzoneDirective.onDragLeave" while dragging. Any idea what could cause this?

I also had a kinda hard time to make this work inside a table instead of div's. It works, but is a pretty ugly way with ng-container and div between tbody and tr. If you have any tips for a clean way inside a table, I would aprreciate it. Every tr is a draggable (and dropable if it is a directory).

reppners commented 5 years ago

My console is full with "cannot read property 'removeChild' of null, at ...DndDropzoneDirective.cleanupDragoverState and .DndDropzoneDirective.onDragLeave" while dragging. Any idea what could cause this?

Can you reproduce these console messages based on the stackblitz?

If there is an directory at the top of the list, I'm unable to drop a file above it. You can reproduce it in your example. If there is a file at the first index, everything is fine. I already tried some workaround with padding or margin, but nothing worked. Same problem if I want two drop a file between two folders.

I was able to workaround this with some padding - but when using tables this is not possible anymore. I've too struggled to get it right with tables and haven't really gotten to a solution I would be happy with.

You can check it out anyway https://stackblitz.com/edit/ngx-drag-drop-issue-template-9dgxtj?file=src%2Fapp%2Fapp.component.html

Do you absolutely need to use table markup?

sharmatushar04 commented 5 years ago

how can i implement nested dropzones. I have been trying it for last few days did a lot of research but couldn't find a solution and i have to use ngx-drag-drop only. Please help. Thanks

reppners commented 5 years ago

how can i implement nested dropzones. I have been trying it for last few days did a lot of research but couldn't find a solution and i have to use ngx-drag-drop only. Please help. Thanks

Did you take a look at the nested example?

https://reppners.github.io/ngx-drag-drop/ https://github.com/reppners/ngx-drag-drop/tree/master/demo/app/nested

Here is stackblitz where its as simple as just nesting divs that have the dndDropzone directive https://stackblitz.com/edit/ngx-drag-drop-issue-template-8t7imw?file=src%2Fapp%2Fapp.component.html

reppners commented 5 years ago

Closing as answered question.