Unable to implement multiple draggable inner objects using Angular 5 and dragula library

After struggling for the past few days, I can't seem to get it to work...

Here is a brief explanation of my issue:

In this example, I have an array of objects structured like this:

public containers: Array<object> = [
  {
    "name": "container 1",
    "items": ["1", "2", "3"]
  },
  {
    "name": "container 2",
    "items": ["4", "5"]
  }
];

Each object contains an array of strings.

I am trying to create div elements to allow these objects to be moved around (Containers AND Items).

Currently, I am seeing something like this:

https://i.sstatic.net/y2n9R.png

The red box represents the main div, black boxes symbolize containers, and blue boxes represent items.

The corresponding HTML looks like this:

<div class="feuille-drag" [dragula]='"containers"' [dragulaModel]='containers'>
  <div *ngFor="let container of containers" class="drag-container" [dragula]='"blocks"' [dragulaModel]='container.items'>
    <span class="handle">O</span>
    <div *ngFor="let item of container.items" class="drag-bloc">
      <span class="handleF">X</span>
      {{item}}
    </div>
  </div>

Additionally, in my TypeScript code, I have set some options:

dragulaService.setOptions('containers', {
  revertOnSpill: true,
  copy: false,
  moves: function (el, container, cHandle) {
    return cHandle.className === 'handle';
  }
});

dragulaService.setOptions('blocks', {
  revertOnSpill: true,
  copy: false,
  moves: function (el, container, bHandle) {
    return bHandle.className == 'handleF';
  }
});

Upon close inspection, you'll notice that there is an empty blue box in the screenshot. This was created when I dropped one blue box into another, resulting in an undefined element being added to my Containers object.

Another issue is that when moving a blue box to a different black box (container), the original blue box disappears and a new one appears instead.

For instance, moving blue box 1 into container 2 causes blue box 1 to vanish and blue box 2 to take its place within container 2.

However, the original blue box is not removed from the Containers object:

https://i.sstatic.net/5r5LR.png

Lastly, the handle elements from the containers (O) are being treated as draggable objects by dragula. This might be a CSS-related issue, but I'm unsure.

I am utilizing Angular CLI, Angular 5, Dragula, and I am relatively new to Angular (previously worked with AngularJS)

I hope this explanation makes sense and that someone can assist me. Apologies if this issue has already been addressed, I couldn't find a solution!

Have a wonderful day!

UPDATE

Please check out this StackBlitz

Answer №1

There appears to be a problematic html element in your structure:

<span class="handle">O</span>

The ng2-dragula plugin is returning an incorrect index during the drop event.

drake.on('drop', (dropElm: any, target: any, source: any) => {
   if (!drake.models || !target) {
     return;
   }
   dropIndex = this.domIndexOf(dropElm, target);

Check out this link for more information.

In this case, the target refers to the div.drag-container, which contains container.items.length + 1 elements.

When a new undefined element is added to your container.items,

To resolve this issue, it is recommended to organize dragging elements within their own container like so:

...
<span class="handle">O</span>

<div [dragula]='"blocks"' [dragulaModel]='container.items'>
    <div *ngFor="let item of container.items;" class="drag-bloc">
        <span class="handleF">X</span> {{item}}
    </div>
</div>

Visit this forked stackblitz example for reference.

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

Dealing with Overwhelmingly Large Angular 5 Components

I'm currently developing a project in Angular 5 and one of our component files is becoming quite large, reaching nearly a thousand lines and continuing to grow. This will eventually make it difficult to manage and understand. We are seeking advice on ...

Using TypeScript's `extend` keyword triggers an ESLint error when attempting to extend a generic type

I am dealing with numerous models that include additional meta data, which led me to create a generic type for appending them to the models when necessary: type WithMeta<T> = T extends Meta; However, I encountered an error stating: Parsing error: &a ...

Can HTML5-AppCache Manifest files be automatically generated?

Currently, I'm developing a web application utilizing Angular 4 along with Angular CLI. My goal is to incorporate App-cache for IE browsers since they do not support service workers. However, I've encountered an obstacle where the static files pr ...

Customize Material-UI FAB Hover Color

While working on my project, I encountered an issue with a floating action button that contains an SVG icon nested underneath it. Even though the SVG icon is not in the children prop of the FAB, hovering over the FAB or the SVG icon causes the FAB to chang ...

Exploring Custom Scrolling Effects in Angular 2

Have you ever heard of react-router-scroll in React? It allows React app pages to scroll smoothly like a regular website. The feature scrolls to the top of each new page (route), while remembering the scroll position of previous pages. This means that when ...

Using null or undefined for ternary operator formatting in React applications

When styling a component, what should be used if a specific condition is not fulfilled: null, undefined, or something else? For example: errorStyle: { right: locale === Locales.ARABIC ? 0 : null, left: locale !== Locales.ARABIC ? 0 : null, .. ...

Extracting the month and year from a datetime string: A simple guide

I am working with a JSON object that includes a field called Month with a string datetime value- { Month : "31-Jan-2022 12:00 AM (EST)" .... .... } Is there a way to extract the Month Name and Year from this string using JavaScript's dat ...

The custom created THREE.Curve is not rendering correctly

Following advice from this solution, I have implemented a linearly interpolated curve in the code below: THREE.Linear3 = THREE.Curve.create( function ( points, label /* array of Vector3 */) { this.points = (points == undefined) ? [] : points; ...

Change the icon switch from fas fa-lock-open to fas fa-lock by adding an event listener for a click action

let lockIcon = document.createElement("i"); lockIcon.setAttribute("class", "fas fa-lock-open"); lockIcon.setAttribute("id", color + "lock"); Is there a way to toggle between the icons fas fa-lock-open and fas fa-lock when clicking using a ...

Enhance User Experience by Implementing Event Listeners for Changing Link Visibility Using mouseover and getElementsBy

I am new to JavaScript and struggling to find a solution. Despite searching online for fixes, none of the solutions I've found seem to work for me. I have spent hours troubleshooting the issue but I must be missing something crucial. Can someone plea ...

Creating personalized columns in a BootstrapVue table

I'm having an issue with the b-table component in bootstrap-vue. The array containing my items is structured like this: [{ id: 1, name: "Test", phone: 555-111-666, address: "Some Address", //etc... }] I have a couple of question ...

Create a CSV document using information from a JSON dataset

My main goal is to create a CSV file from the JSON object retrieved through an Ajax request, The JSON data I receive represents all the entries from a form : https://i.sstatic.net/4fwh2.png I already have a working solution for extracting one field valu ...

Guide on creating a custom type for an object utilizing an enum framework

Enumerating my shortcuts: export enum Hotkey { MARK_IN = 'markIn', MARK_OUT = 'markOut', GO_TO_MARK_IN = 'goToMarkIn', GO_TO_MARK_OUT = 'goToMarkOut' } I am now looking to define a type for a JSON ob ...

Undefined Children Component

I am currently working on creating Auth routes and I am facing an issue where the children are undefined, resulting in a blank page. In my App.js file, I have implemented a PrivateRoute component as shown below. Interestingly, when I replace PrivateRoute w ...

Is it necessary to match GET and POST routes only if a static file does not match?

I am encountering an issue with my routes and static definitions in Express. Here is my route setup: app.get('/:a/:b/:c', routes.get); Along with this static definition: app.use('/test', express.static(__dirname + '/test')); ...

Caution: The attribute name `data-*` is not recognized as valid

I am attempting to import an SVG file in my NEXT.js project using the babel-plugin-inline-react-svg. I have followed all the instructions and everything is functioning perfectly. // .babelrc { "presets": ["next/babel"], "plugin ...

Explanation on subtracting the row value from a textbox

Click here to view the image For instance: If I enter a value in the "USED(kl)" textbox, it should subtract that value from the corresponding row where "KILOGRAM/S" is located; Upon clicking the update button, only the specific row should be affected wh ...

How is it possible that the SetTimeout code continues to run even after calling clearTimeout

I have this code snippet within my react component: //some code var timeout = null; //global variable //some more code useEffect(() => { if(...some condition) { console.log('test1'); timeout = setTimeout(() => { ...

Customize buttons in Material UI using the styled component API provided by MUI

I am intrigued by the Material UI Styled Component API, not to be confused with the styled-component library. However, I am facing difficulty in converting my simple button component into a linked button. Can anyone advise me on how to incorporate a react ...

Displaying a dynamic progress bar across all elements in fullscreen mode

I am looking to implement a full-screen indeterminate progress bar that overlays all screen elements. Here is my specific use case: When a user fills out a form, including an email field, the email id is checked against a database via ajax. While waiting ...