Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dragula within Dragula #868

Closed
tatsujb opened this issue Jun 29, 2018 · 28 comments
Closed

Dragula within Dragula #868

tatsujb opened this issue Jun 29, 2018 · 28 comments

Comments

@tatsujb
Copy link

tatsujb commented Jun 29, 2018

I've tried to stop click propagation but to no avail :

 <div class="flex allow-scroll-right">
        <div *ngFor="let groups of groups" [dragula]="'bag-two'">
          <div class="customer-group ff" >
            <div class="group-title ellipsis">Client</div>
            <div class="elem-list" (click)="$event.stopPropagation()">
              <div *ngFor="let elem of groupList" [dragula]="'bag-one'" [dragulaModel]="elem">
                <app-pane [titleI]="elem" [valueI]="elem"></app-pane>
              </div>
            </div>

          </div>
        </div>

I get :
image

when I want to be able to distinguish between if I'm clicking inside of the inner bag or on the outer with inner bag boolean substracted.

this is possible right?

I just can't figure out how to do it.

@cormacrelf
Copy link
Contributor

Search the existing issues for ‘nested’.

@tatsujb
Copy link
Author

tatsujb commented Jun 29, 2018

Thanks. that did bear some interesting results but nothing conclusive. I still am as far as can be from solving this.

are you sure you understood that I'm not trying to drag from one bag to another? I'm trying to drag from one bag to the same then be able to drag children (from that element i just dragged) in between themselves.

I have two bags a parent bag and a children bag and they should not mingle ('Client' is draggable but so are 'aadsd', 'zqds', and 'yghibv')

image

Here's my code :

<div class="root" [ngClass]="' ' + opened">
  <div class="customer-groups-view flex">
    <div class="sidebar">
      <div class="ellipsis">Nouveau Clients : </div>
      <div class="allow-scroll-bottom">
        <div *ngFor="let una of unassigned" [dragula]="'bag-one'" [dragulaModel]="una">
          <app-pane [titleI]="una" [valueI]="una"></app-pane>
        </div>
      </div>
    </div>


    <div class="customer-groups flex-1">
      <div class="flex allow-scroll-right">
        <div *ngFor="let group of groups" [dragula]="'bag-two'" [dragulaModel]="group"  [dragulaOptions]="options" class="bag-two flex">
          <div class="customer-group" >
            <div class="flex"><div class="handle">X</div><div class="group-title ellipsis">Client</div></div>
            <div class="elem-list">
              <div *ngFor="let elem of groupList" [dragula]="'bag-one'" [dragulaModel]="elem">
                <app-pane  [titleI]="elem" [valueI]="elem"></app-pane>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Typescript :

import {AfterViewInit, Component, ElementRef, OnInit} from '@angular/core';
import {conf} from '../common/services/variables';
import {InternationalizedNotifService} from '../common/services/i18n-ed.notif.service';
import {SnotifyService} from 'ng-snotify';
import {Apis} from '../common/api/apis';
import {StoreService} from '../common/services/store.service';
import {DragulaService} from 'ng2-dragula';
import dragula from 'dragula';
import autoScroll from 'dom-autoscroller';

@Component({
  selector: 'app-groups',
  templateUrl: './groups.component.html',
  styleUrls: ['./groups.component.scss']
})
export class Groups implements OnInit, AfterViewInit {

  options = {
    moves: function (el, container, handle) {
      return handle.className === 'handle';
    }
  };
  justCalledGetCustomersAPItimeout;
  resetCalled = false;
  opened = false;
  scrollAmount;
  data;
  scroll: any;

  groupList = [
    'aadsd',
    'zqds',
    'yghibv',
  ];
  unassigned = [
    'aaappdd',
    'a8d',
    'aaappdd',
    'aaappdd',
    'aaappdd',
    'aa1',
  ];
  groups = [
    'aaadzdaze',
    'aaadzdaze',
    'aaadzdaze',
    'adf',
    'aaadzdaze',
  ];


  constructor(
    private api: Apis,
    private store: StoreService,
    private element: ElementRef,
    private notif18nMessages: InternationalizedNotifService,
    private snotifyService: SnotifyService) {
  }

  ngOnInit() {
    this.doCallWithNotif('getCustomers');
    this.store.topBarOpened$.subscribe(bool => {
      if(bool === true || bool === false) this.opened = bool;
    }, (error) => console.log(error), () => {});

  }

  ngAfterViewInit(){
    const th = this;
    this.scrollAmount = this.element.nativeElement.querySelector('.allow-scroll-right');
    this.scrollAmount.addEventListener('wheel', e => {
      th.scrollAmount.scrollLeft -= (e.wheelDelta)/1.5
    }, false);
  }

the only solution I've found for now is to use drag handles and remove all [dragulaModel]s as they cause this issue.

@cormacrelf
Copy link
Contributor

You’re doing a lot of things wrong. At minimum, without rewriting your code for you:

  1. You are using dragulaModel with STRINGS. You can’t do that. Pass arrays.

  2. You cannot just set ‘options’ on a component class and hope that the library will magically read it and set options on a Drake. You aren’t even injecting DragulaService.

Maybe don’t leap to the conclusion there is a bug just yet.

@cormacrelf
Copy link
Contributor

And yes, as I have mentioned in other related threads, I understand you cannot drag from one bag to another. That is actually the definition of a bag in this library: a grouping of Dragula-enabled containers, between which items may be dragged.

@tatsujb
Copy link
Author

tatsujb commented Jun 29, 2018

okay.

So it would work if I used arrays of arrays instead of arrays of strings?

@cormacrelf
Copy link
Contributor

Oh, and you’ve done another classic blunder, which is putting the [dragula] and [dragulaModel] on every item enumerated by *ngFor. Put them on the parent. I would say that’s a documentation problem since so many people report their misuse as an issue, but I don’t know how the extremely simple example code could be more clear, and as a percentage of total users, it’s a small population.

@cormacrelf
Copy link
Contributor

Well yes... at some point you’re going to have to have a data structure with an array of arrays, or at least an optimised approximation with dictionaries and IDs. You are building a Trello clone — how far are you really going to get with two arrays of strings called groupList and groups?

Maybe try building something simpler and working up to more complicated arrangements. I know that this library is actually very difficult to use for anything except the basic demos. I am working on a replacement for the whole thing over at https://cormacrelf.github.io/angular-skyhook/ - but the ‘kanban board’ is not production ready.

Or if you’re really early in your project, switch to react-beautiful-dnd. It does everything you’re trying to do already, and you could focus on the data model.

@tatsujb
Copy link
Author

tatsujb commented Jun 29, 2018

about react-beautiful-dnd yeah took a look and wow. I ❤️ react on top of that but I'm just a lowly dev I don't get to choose the technologies.

by moving the [dragula] and [dragulaModel] on every item enumerated by *ngFor to the parent fixed all bugs.

I don't think the docs are at fault here rather ts-lint which screams at you for an unknown ref, and you're like "oh of course, what a dumbass I am, I put them on the parent, how will dragula even be able to know what I'm referencing? I'll just move it down at least to the same line and yep... syntax error gone"

but indeed if I instead turn a blind eye to that error and follow what you said it works. I don't understand how or why ...well the why makes sense (you don't want to be checking the array on every single entry of the array, just where the whole array is).

...however the how is more mysterious. but ok, that's how it should be.

@cormacrelf
Copy link
Contributor

What? Why would tslint complain about that? The things you’re referring to exist and are in context.

@tatsujb
Copy link
Author

tatsujb commented Jun 29, 2018

I dunno :

image
to me it made sense because of the sequential nature of html/xml

@cormacrelf
Copy link
Contributor

Also Dragula works exclusively with parent elements. The upstream Dragula is used by telling it to work on a container div, and make all its direct children draggable. This is a barebones Angular wrapper.

@cormacrelf
Copy link
Contributor

cormacrelf commented Jun 29, 2018

Also dragulaModel is not meant to refer to each element of an array. Like Dragula itself, you pass it the whole array that it will be manipulating. It is terrible. It is the source of like 90% of bug reports and misuse here. When I used ng2-dragula, I did not use dragulaModel.

I said my alternative library’s kanban board example wasn’t production ready because of some display glitches in that specific example code... but it’s not dragulaModel bad.

@tatsujb
Copy link
Author

tatsujb commented Jun 29, 2018

Today I Learned.

but that still doesn't explain how the parent div can reference a name that hasn't been declared yet (at least to me, maybe I'm looking at this wrong

@cormacrelf
Copy link
Contributor

You’re still looking at it wrong. You shouldn’t be passing elem to dragulaModel at all. You should pass exactly the same array that ngFor enumerated over. That is in scope.

@tatsujb
Copy link
Author

tatsujb commented Jun 29, 2018

Ooohhh

you pass it the whole array that it will be manipulating. It is terrible

aren't my hands bound in this? the array that i'll have will be of n groups (dynamic)

I can't preemptively declare them.

this is just mockup data so far.

@cormacrelf
Copy link
Contributor

Do yourself a favour and don’t use dragulaModel. Find another way. Use events from the DragulaService, and pull data-attributes off the elements it gives you, and do your own array splicing.

Or, do yourself another favour and don’t use ng2-dragula.

@cormacrelf
Copy link
Contributor

Be free, my friend. Run away from this ridiculous library. It will only hurt you.

@tatsujb
Copy link
Author

tatsujb commented Jun 29, 2018

okay. the thing is time is of the essence. I'm on my bosses leash and he keeps screaming "faster!"

So for now I'll do re-impl of the multiple callbacks of this lib + my own data splicing (which I have experience with so that doesn't phase me).

had I had more time I would have done the whole thing from scratch. I've used draggable in angular before.

I just needed to use a lib to gain time.

thanks you've been an excellent aid and great counsel

@cormacrelf
Copy link
Contributor

cormacrelf commented Jun 29, 2018

Well, dragulaModel is fine for a fast mock-up. Please just follow some existing examples and model your solution on that.

But — you could just steal the entire kanban board example verbatim right off https://cormacrelf.github.io/angular-skyhook/examples/index.html#/kanban . There’s so much documentation you could probably have it running in an hour if you copied that unreleased angular-skyhook-card-list package into your code.

@cormacrelf
Copy link
Contributor

And no worries mate. Best of luck.

@tatsujb
Copy link
Author

tatsujb commented Jul 2, 2018

hey thanks again

There’s so much documentation you could probably have it running in an hour if you copied that unreleased angular-skyhook-card-list package into your code.

so far it's proving much more difficult than that. there's a lot of non-package code being referenced :

image

I don't get what I'm supposed to do here. gonna go read some impl doc, see where I get

@tatsujb
Copy link
Author

tatsujb commented Jul 2, 2018

Ok, this library is definitely as Angular 6 as it gets and I love that but I'm over 1h, I can't afford to delve deeper. maybe in a later sprint when I have more time.

@cormacrelf
Copy link
Contributor

cormacrelf commented Jul 2, 2018

@tatsujb I mentioned that:

if you copied that unreleased angular-skyhook-card-list package into your code.

You'd have to change to a ./ relative path to reference it. Anyway.

(Also: I'm rewriting the guts of it not to use flex ordering, and instead use a kind of double-buffered data update pattern. Like react-sortable-tree.)

@tatsujb
Copy link
Author

tatsujb commented Jul 5, 2018

@cormacrelf btw I never updated you on this but I dropped ng-dragula following your advice right after your last comment. I didn't go the angular-skyhook route either, (though I plan to in future personal projects) but I went the native manual angular route, which turned out much easier then I'd anticipated.

thanks again and happy coding!

@jeff1978
Copy link

jeff1978 commented Oct 9, 2018

Be free, my friend. Run away from this ridiculous library. It will only hurt you.

Hi @cormacrelf,
I have found this thread after spending significant time trying (but failing) to extend my dragula app (http://www.plod.co.nz) from using an array, to using a node tree with dragula.
I have spent all evening reading the Skyhook docs and i really like it. The chess board example is written perfectly for my level of programming, so thank you.

@cormacrelf, do you think Skyhook could support my following use case?

A user should be able to drag and drop objects into dnd containers. Each tree node nests one dnd container. Particular objects when dropped, may create new nodes (a branch) each new node having their own container. Dragging and dropping an object with children nodes, should 'move' the branch.

Apologies if this is not the correct place to seek such advice, I don't usually post questions so i wasn't sure. Let me know if i should create a separate request>? Thank you.

@cormacrelf
Copy link
Contributor

Yep. You could do that. It's always going to be hard though. I can't help you.

@jeff1978
Copy link

jeff1978 commented Oct 9, 2018

Cool @cormacrelf I will crack on with Skyhook today. Your comment above is help enough. I wasn't sure what direction to go after 2 weeks of trying everything else. Thanks.

@jeff1978
Copy link

      Yep. You could do that. It's always going to be hard though. I can't help you.

I finally did it! Yes, you were right, it was very difficult. Managed to get it working in Dragula, but will update to Skyhook sometime in the new year. Thanks again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants