Issue with horizontal elements not functioning properly while using cdkDragPreview and cdkDragPlaceholder

My goal is to have my elements laid out horizontally instead of vertically, so I'm using display-inline. However, I've encountered some unusual behavior with the CSS that's causing two specific issues.

  1. When I click and drag an element, it grows in size temporarily before reverting back to its regular size once dropped. I've tried various solutions including adding a cdkDragPreview element with matchSize, as recommended by Angular, but nothing has worked. I found a bug report that seems similar to my issue (https://github.com/angular/components/issues/19060), but it's unclear if the bug has been fixed since it was closed.
  2. Dragging an element from the bottom drop list causes the other items to move erratically until the dragged item leaves the list. I attempted to use a hide style for cdkDragPlaceholder to control this behavior, but it only seemed to work for the top drop lists and had no effect on the bottom.

You can see both issues illustrated on StackBlitz through this link: https://stackblitz.com/edit/spuzzler. I suspect that these problems can be resolved with CSS, but I haven't been able to find a solution yet.

Answer №1

To implement a cdkDropList for each word, my approach involves using an outer div and an inner div as the draggable element. Additionally, I have set the size of the outer div to remain fixed so that when dragging occurs, there is no re-ordering of the words; instead, it leaves an empty space where the word was dragged from.

You can view the outcome in this StackBlitz project

<div #contenedor class="categories" cdkDropListGroup> 
    <ng-container *ngFor="let item of items; let i=index">
        <div class="categories-item" cdkDropList 
            cdkDropListOrientation="horizontal"
            [cdkDropListData]="{item:item, index:i}"
            (cdkDropListDropped)="drop($event)">
            <div class="inner"  cdkDrag>
                <div *cdkDragPlaceholder></div>
                <div class="categories-item-drag" *cdkDragPreview matchSize="true">
                    <div class="inner">{{item}}</div>
                </div>
                {{item}}
            </div>
        </div>
    </ng-container>
</div>

I am utilizing an observable that returns an array of words. In the `subscribe` method, I assign each word to the item variable and then use a `setTimeout()` function to add the size to the outer div.

export class AppComponent implements OnInit {
  @ViewChildren(CdkDropList, { read: ElementRef }) pills: QueryList<ElementRef>;
  constructor(private renderer: Renderer2) {}
  items: any[];
  positions: any[];
  ngOnInit() {
    this.getParragraf().subscribe(res => {
      this.items = res;
      setTimeout(() => {
        this.pills.forEach(x => {
          this.renderer.setStyle(
            x.nativeElement,
            "width",
            x.nativeElement.getBoundingClientRect().width + "px"
          );
        });
      });
    });
  }

  drop(event: CdkDragDrop<any>) {
    this.items.splice(event.previousContainer.data.index, 1);
    this.items.splice(event.container.data.index,0,event.previousContainer.data.item)
  }

  getParragraf() {
    return of(
      "Let him who walks in the dark, who has no light, trust in the name of the Lord and rely on his God.".split(
        " "
      )
    );
  }
}

Updated: You do not necessarily need to create a cdkDropListGroup, as you can utilize [cdkDropListConnectedTo] property. To achieve this, make use of two arrays: words and items

If 'res' is an array of strings, you can do the following:

this.items = res.map((x, index) => ({ value: x, ok: false, id: 'id' + index }));
this.words = res.map(x => ({ o: Math.random(), value: x }))
              .sort((a, b) => a.o - b.o)
              .map(x => (
                  {
                      value: x.value,
                      connected: this.items.filter(w => x.value == w.value).map(x => x.id)
                  }))

Then, use 'item.value', 'item.id', 'word.value', and 'word.connected'

Check out the updated StackBlitz example

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The creation of fsm.WriteStream is invalid as it is not a recognized constructor

Can you help me with this issue? I am attempting to install @ng-idle/keepalive using the command npm install --save @ng-idle/core, but I encountered the following error: npm ERR! fsm.WriteStream is not a constructor npm ERR! Log files were not written due ...

The Angular Material tab component fails to display on the webpage

I am encountering an issue with the Angular Material Tabs Module where only text is being displayed instead of the actual tabs. I am using Angular 6 along with Angular Material version 6.4.7. After following the setup procedure outlined on (npm installat ...

Switching Over to Burger Menu

I created a burger menu using HTML, CSS, and jQuery that switches from a full-width menu to a burger menu. However, I'm facing an issue with toggling the dropdown when the menu collapses. Here's my code: <!DOCTYPE html> <html> < ...

Filter an array of objects in Angular2 based on properties that are not included in the specified values

I'm encountering some difficulties while filtering an array of objects based on a specific set of values: Here is the array that needs to be filtered: const items: Product[] = ... values Next, I have created an array containing the products that I w ...

Can anyone help me get my carousel to work properly?

I am facing a carousel problem in my personal exercise project. I have gathered HTML, CSS, and JavaScript from the internet and am attempting to integrate them all together. //Sidebar script start $(document).ready(function () { var trigger = $(&apo ...

Is there a way to position two forms next to each other in alignment?

I would like to display two forms side by side. Currently, I have one form shown here: http://gyazo.com/093efe95337ace40fe633adb88b76c2d. I want the same form to be displayed on the right-hand side as well. .comments-section .comment-form { padding: 20p ...

Refresh Angular Component upon query parameter modification

Within my application, there is a search form that can be accessed by adding query parameters to the URL. This will prefill the form with specific information. My goal is to clear this prefilled state when the search icon in the navigation is clicked. Whi ...

how to assign a default value for a drop-down menu in Angular 6

How can I set a default value in my dropdown in Angular? <div class="form-group"> <select id="interfaceType" (ngModelChange)="onChange($event)" [(ngModel)]="interfacengmodel" #interfaceType="ngModel" name="interfaceType" class="form-cont ...

Reveal Visual Content upon Hovering

Is there a way to show an image only when the mouse hovers over it? Additionally, can we underline the adjacent text at the same time? If the mouse moves away from the image, I'd like it to hide again and revert the text back to its original state. T ...

Adjusting the size of elements and the dimensions of the browser window

My challenge involves a container with multiple buttons that are absolutely positioned. I would like these buttons to dynamically resize based on the width of the browser window. Essentially, I want both the size and position of the buttons to adjust accor ...

Issue: Unable to initialize (typescript) as an error appears. It is not possible to retrieve the property 'getExecutingFilePath' as it

After setting up a new Angular2 project using npm, I was able to successfully run it via the node command prompt with ng serve. However, when attempting to run it from the console in IntelliJ IDEA (version 2016.3.4), I encountered an error message: Erro ...

Using Angular 10 to make an HTTP POST request, with the goal of appending a string

Whenever I try to send a post request to an api endpoint, I keep encountering an error with status code 500. name: "HttpErrorResponse" ok: false status: 500 statusText: "Internal Server Error" Below is the code I am using: var selected ...

Error handling: Encountered unexpected issues while parsing templates in Angular 2

I'm a beginner with Angular 2 and I'm attempting to create a simple module, but encountering an error. app.component.html import { Component } from '@angular/core'; import { Timer } from '../app/modules/timer'; @Component({ ...

Struggling with VSTS crashing during NPM Install?

My VSTS Batch Script looks like this: cd (my UI dir) echo npm install... npm install echo ng build --output-path %1\ui ng build --output-path %1\ui echo npm run ng build --output-path %1\ui npm run ng build --output-path %1\ui echo All ...

Struggling to eliminate the padding beneath the menu items in Bootstrap?

I'm having trouble adjusting the padding inside my menu. I want to make it less chunky and large, but so far I've only been successful in removing the top padding. The bottom padding just won't budge. Here's the code that helped fix th ...

Executing a PHP function within a Laravel controller using Ajax

In my Laravel project, I have a Controller named Clientecontroller that is working perfectly. It contains a method called listar() which retrieves client information. public function listar(Cliente $cliente) { $clientes = DB::table('clientes' ...

Align both vertically and horizontally in the center of the body

I have two images aligned vertically inside a wrapper. How do I center the wrapper within the body? What is the best way to center my wrapper inside the body? <!DOCTYPE html> <html lang="en-US"> <head> <meta charset="utf-8"> ...

Issue with Angular 8: Undefined value for ngModuleType.ngModuleDef.id when trying to import NguCarousel module

After attempting to import the NguCarousel module, my application encounters an issue due to ngModuleType.ngModuleDef being undefined. Interestingly, if I disable the import of the NguCarousel module, the app functions properly. I have experimented with di ...

Mobile Device Centering Problem with Bootstrap Cards

Despite my thorough research efforts, I have been unable to find a solution. The code snippet below is meant to display the image provided, but it seems to shift to the left when viewed on a mobile device. If anyone can assist me with this issue, I would ...

The page fails to load when redirected, however, it briefly displays the page upon clicking the back button before navigating back to the previous page

Currently, I am working with Angular 2 and encountering an issue when attempting to click on a link. The loading bar continues to progress without displaying the data or HTML content on the page. Furthermore, if I try to go back to the previous page, the i ...