Dragging element position updated

After implementing a ngFor loop in my component to render multiple CdkDrag elements from an array, I encountered the issue of their positions updating when deleting one element and splicing the array. Is there a way to prevent this unwanted position update?

I attempted to retrieve the freeDragPosition of each draggable element before deletion and reset their positions, but unfortunately, it did not work.

Shown below is my app.component.html code snippet:

<div class="container" id="container">
  <div *ngFor="let f of fields; let i = index;" 
    class="textField"
    [attr.data-guid]="f.guid"  
    (mouseenter)="onFieldHover($event)" 
    cdkDrag 
    cdkDragBoundary="#container"
    (cdkDragEnded)="onDragEnded($event)"
    [cdkDragFreeDragPosition]="f.position">
    <div class="textField-inner">
      <span style="color: hotpink; font-weight: bold">{{f.guid}}</span>
    </div>
    <div class="textField-options">
      <div class="textField-move" cdkDragHandle>
        <svg width="24px" fill="currentColor" viewBox="0 0 24 24">
          <path d="M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"></path>
          <path d="M0 0h24v24H0z" fill="none"></path>
        </svg>
      </div>
      <div class="textField-remove">
        <i class="fas fa-trash-alt" (click)="onRemoveTextField(i)"></i>
      </div>
    </div>
  </div>
</div>
<button type="button" (click)="onTextFieldAdded()">Add a field</button>

The corresponding app.component.ts file looks like this:

import { Component } from '@angular/core';
import {CdkDrag, CdkDragEnd} from '@angular/cdk/drag-drop';

// Component definition goes here

export class Field{
    // Field class properties defined here
}

To resolve this issue, I aim to keep the elements in their current positions even after deleting one of them.

You can view a GIF demonstration of the problem here.

A working example on StackBlitz can be accessed here.

Answer №1

By conducting tests on your stackblitz, I was able to replicate the desired behavior. It seems that when a cdkDrag is placed within an ngFor loop, it binds to the same list. Consequently, removing one cdkDrag item from the list triggers a re-rendering of the template with new positions to match the order of the ngFor list. To prevent this issue, you can customize the css style position of the cdkDrag element.

To address this in your case, simply include position: absolute; in the .textField css class.

Answer №2

The problem lies in the fact that you haven't specified a trackBy function within your *ngFor. This oversight will result in the objects being re-rendered every time the array undergoes a change:

To rectify this issue, modify your *ngFor as follows:

*ngFor="let f of fields; let i = index; trackBy: trackByField"

Additionally, ensure to include a trackByField method within your component:

 trackByField = (i: number, field: Field) => field.guid;

Implementing these changes will preserve the positions of items that have already been moved, while allowing non-moved items to still be reordered.

Visit stack for more information.

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

Having trouble retrieving certain header values in Angular 4

Using Angular 4, I am making a back-end query like this: this.classzService.query({ page: this.page, size: this.itemsPerPage, sort: this.sort(), url: url }).subscribe( (res: Response) => this.onQuerySuccess(res.jso ...

Create an alternate name for a specific type of key within a nested record

There are three simple types available: const structureTypes = z.enum(["atom","molecule"]) const atomTypes = z.enum(["oxygen","hydrogen"]) const moleculeTypes = z.enum(["water","ammonia"]) The goal is to define a type for a cache where the keys correspond ...

Difficulty loading images in Angular 2 after deploying the dist folder (renamed to "myapp") to the tomcat webapp directory

When I pass the relative path and use the command below to build, I encounter a problem! ng build --prod --aot --base-href /myapp/ The issue arises with a 404 Resource not found error. bkgraph.jpeg:1 GET http://localhost:8081/assets/bkgraph.jpeg 404 () ...

Utilizing the useSelect hook in Typescript to create custom types for WordPress Gutenberg, specifically targeting the core/editor

As I delve into development with WordPress and the Gutenberg editor, my goal is to incorporate TypeScript into the mix. However, I encounter a type error when trying to utilize the useSelect() hook in conjunction with an associated function from the core/e ...

Tips on incorporating esbuild extensions in the template.yaml file of AWS SAM

Currently, my TypeScript Lambda functions are managed using the AWS Serverless Application Model (SAM), and I rely on esbuild for the build process. I'm interested in incorporating esbuild plugins into my build process to enable support for TypeScrip ...

Guide to preserving canvas state in React?

I am currently working on a drawing application that allows users to draw lines on a canvas. The functionality is such that the line starts drawing on the first click, continues as the mouse moves, and stops on the second click. However, each time a user ...

The attribute 'limitTags' is not present in the type 'IntrinsicAttributes & AutocompleteProps'

The Versions of Material UI and Lab I am Utilizing "@material-ui/core": "^4.8.3", "@material-ui/lab": "^4.0.0-alpha.44", Visit the component here Snippet of My Code <Autocomplete multiple limitTags={2} id="multiple-limit-tags" ...

Unexpected error arises in Typescript despite code functioning properly

As part of a practice project where I'm focusing on using webpack, ES6, npm and Typescript implementation, I have successfully set up loaders for 'awesome-typescript-loader' and 'babel-loader', which are bundling the code properly. ...

Issue: The creation of ComponentClass is restricted due to its absence from the testing module import

The test base for my Angular Cli 6.0.1 app is set up as follows. I am using Jasmine V2.8.0 and Karma V2.0.0 Encountering an error on line 13 that says: Error: Cannot create the component AddressLookUpDirective as it was not imported into the testing mod ...

Attempting to map an object, however it is showing an error stating that the property 'title' does not exist on type 'never'

While attempting to retrieve data from the Bloomberg API, I encountered an issue when trying to extract the title from the response object. The error message received was: Property 'title' does not exist on type 'never'. Below is the co ...

AngularJS drag-and-drop functionality for creating and rearranging lists

I am in need of a drag and drop list feature using angular, but the $scope.list must also be updated as I have to save the new order in my database. I came across this helpful answer and utilized it to create this http://jsfiddle.net/aras7/9sueU/1/ var m ...

developed a website utilizing ASP MVC in combination with Angular 2 framework

When it comes to developing the front end, I prefer using Angular 2. For the back end, I stick with Asp MVC (not ASP CORE)... In a typical Asp MVC application, these are the steps usually taken to publish the app: Begin by right-clicking on the project ...

Steps to troubleshoot and resolve the @ionic/angular member Event error in Ionic 5

Recently I made the switch from Ionic 4 to Ionic 5, and now I am encountering this error: ERROR in src/app/app.component.ts(4,10): error TS2305: Module '"/node_modules/@ionic/angular/ionic-angular"' has no exported member 'Events'. ...

The issue with the antd Input component's onChange event not updating state correctly when using a list fetched from an axios get request in a React

Recently delving into React, I've dedicated the past week to honing my skills. My current project involves creating a straightforward application featuring a 'product create' form alongside a product list equipped with a search bar (utilizin ...

Issue with Cypress TypeScript: Unable to locate @angular/core module in my React application

I am currently in the process of updating my Cypress version from 9.70 to 10.7.0. Although I have fixed almost all the bugs, I have encountered a strange message stating that @angular/core or its corresponding type declarations cannot be found. My applica ...

Troubleshooting with matTootip on Safari: Tips for avoiding input-text blockage

I am currently using the matTooltip feature from Angular Material for an input field. However, on Safari, the input field appears to be overlapping, making it impossible to type in. Despite my attempts to change the position of the toolTip, the issue pers ...

Subscribe to a new Observable once the previous one completes

I need assistance in getting the current user after logging in. When I use this.router.navigate([this.returnUrl]); it does not work. Can someone please help me identify what is wrong here and how I can fix it? onSubmit(): void { this.authService.logi ...

The Angular single-page application fails to refresh when being executed via Visual Studio 2017 Community

I have encountered a problem with my angular 6 app not refreshing when running through Visual Studio 2017. The project consists of multiple projects, including a .NET Core 2 WebAPI and the angular app in question. Even after setting the startup to only be ...

Dividing the text by its position value and adding it to a fresh object

I needed to divide the paragraph into sections based on its entityRanges. Here is what the original paragraph looks like: { type: 'paragraph', depth: 1, text: 'Do you have questions or comments and do you wish to contact ABC? P ...

how to use all parameters except the first one in TypeScript

Is there a way to reference one function's parameter types in another function, but only use a subset of them without repeating the entire list of parameters? //params of bar should be same as foo, except p1 should be a different type function foo(p1 ...