Search code examples
angulartypescriptangular-materialdrag-and-dropangular-cdk-drag-drop

Drop an image in a specific region


I have an image gallery and I intend to drag and drop these images into a drop zone.

I tried to use it in two cases (using the mouse to drag the image and using the cdk drag & drop that allows me to move the image to the drops area as well).

Is there a way to get the object (name, id ...) from the image that is dropped in the drop zone? I try to drag the image to the drop zone and when I release it there, I want to know which image was dropped.

Is there a way to achieve this? Can someone help me?

Thank you very much!

DEMO - STACKBLITZ

.TS

     onFileDropped($event) {
        this.prepareFilesList($event);
        console.log("evt", $event )

      }

      fileBrowseHandler(files) {
      this.prepareFilesList(files);
      }

      async prepareFilesList(files: Array<any>) {

      }

   @HostBinding('class.fileover') fileOver: boolean;
    @HostBinding('style.background-color') private background = '#f5fcff'
    @Output() fileDropped = new EventEmitter<any>();

    // Dragover listener
    @HostListener('dragover', ['$event']) onDragOver(evt) {
      evt.preventDefault();
      evt.stopPropagation();
      this.fileOver = true;
      this.background = '#9ecbec';
    }

    // Dragleave listener
    @HostListener('dragleave', ['$event']) public onDragLeave(evt) {
      evt.preventDefault();
      evt.stopPropagation();
      this.background = '#f5fcff'
      this.fileOver = false;
    }

    // Drop listener
    @HostListener('drop', ['$event']) public ondrop(evt) {
      evt.preventDefault();
      evt.stopPropagation();
      this.background = '#f5fcff'
      this.fileOver = false;
      let files = evt.dataTransfer.files;

      this.fileDropped.emit(files);

    }

Using the images (cdkDrag) I was unable to get any events in the drop zone that detect the entry of something.

Using normal images, I was able to execute the function

 onFileDropped ($ event) {
    this.prepareFilesList ($ event);
    console.log ("evt", $ event)

  }

but I didn't get results as the image shows.

Image


Solution

  • One possibility is create a @input property in directive and assign value to that on mousedown from component

    dnd directive

     @Input() data;
    

    component.html

    //add [data]="selectedProduct" 
    
         <div class="card-body">
              <div class="mycontainer" appDnd [data]="selectedProduct" (fileDropped)="onFileDropped(sle)">
                  <div class="row" style="margin-left: 0; margin-right: 0; justify-content: center;">
                    <span>Drop your items here.</span>   
                  </div>
              </div>
            </div>
    
    //add (mousedown)="assignSelectedProduct(product)"
    
        <ng-container *ngFor="let product of data; let  j = index;">
          <li class="mdc-image-list__item" (mousedown)="assignSelectedProduct(product)" >
            <div class="mdc-image-list__image-aspect-container">
              <ng-container *ngIf="product.image == null; else productImage">
                <img src="" class="mdc-image-list__image imagenotfound">
              </ng-container>
              <ng-template #productImage>
                <img [src]="product.image" class="mdc-image-list__image">
              </ng-template>
            </div>
            <div class="mdc-image-list--with-text-protection">
                        <div class="mdc-image-list__supporting mdc-image-list__supporting">
                            <span class="mdc-image-list__label">{{product.name}}</span>
                        </div>
                    </div>
          </li>
        </ng-container>
    

    component.ts

    selectedProduct; 
    
    assignSelectedProduct(product){
      this.selectedproduct = product;
    }
    

    dnd directive

      // Drop listener
      @HostListener('drop', ['$event']) public ondrop(evt) {
      console.log(this.data, 'data');
      }