ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51.02k stars 13.51k forks source link

bug: disabling and sorting not working well with nested ion-reorder-group #23022

Open digaus opened 3 years ago

digaus commented 3 years ago

Bug Report

Ionic version:

[ ] 4.x [x] 5.x

Current behavior:

Nested ion-reorder-group is not working. I have a list of cards and in the list of cards I have a list of items. Now the user has the option to reorder the cards and the elements.

Naturally I created two reorder groups. One in the for the cards and one inside for the items.

However there now are a few problems:

  1. Reorder elements from the item gets added to the cards reorder group. SO the cards reorder group gets triggered by the items
  2. Disabled cards reorder group still gets its event triggered by the items (items reorder group is enabled)
  3. Disabling item reorder group does not work when cards reorder group is enabled

Expected behavior:

Correctly add the ion-reorder elements only to its closest parent ion-reorder-group

Steps to reproduce:

Related code:

https://stackblitz.com/edit/ionic-5-angular-10-start-template-5jby2n?file=src%2Fapp%2Ftab1%2Ftab1.page.ts

liamdebeasi commented 3 years ago

Thanks for the issue. Can you give this a try using the built-in re-order functionality that the complete method provides? For example:

public doReorderItems(ev: CustomEvent<any>, card: number): void {
  this.items[card] = ev.detail.complete(this.items[card]);
}

public doReorderCards(ev: CustomEvent<any>): void {
  this.cards = ev.detail.complete(this.cards);
}
digaus commented 3 years ago

@liamdebeasi Yes this kinda works. However, the showcase here is pretty simplified.

In my use case I sort the list by a sort property. This means when the user reorders the elements I update this field after he reordered.

Now since the parent reorder event is also called by the childs reordering my parent sort order is also updated.

I can "fix" this by checking the target element of the reorder event (added an id to the reorder-group) and only call my logic when the ids match.

The problem which still persist is that I cannot just disable the child ion-reorder-group. Since the parent ion-reorder-group is still enabled the ion-reorder handles do not get hidden (as seen in the stackblitz example).

This could also be "fixed" by me with an *ngIf.

Nevertheless I still think this is a bug. ion-reorder elements should only belong to its closest parent ion-reorder-group

digaus commented 3 years ago

@liamdebeasi

I think the issue lies in this method (at least for the event):

https://github.com/ionic-team/ionic-framework/blob/de58238333d55334621445cdba4b67b8ba4958a1/core/src/components/reorder-group/reorder-group.tsx#L316

We should stop the while when we find a reorder-group which is not this reorder group. This should do the trick:

const findReorderItem = (node: HTMLElement | null, container: HTMLElement): HTMLElement | undefined => {
  let parent: HTMLElement | null;
  while (node) {
    parent = node.parentElement;
    if (parent === container) {
      return node;
    } else if (parent.tagName === 'ION-REORDER-GROUP' ) {
      return undefined;
    }
    node = parent;
  }
  return undefined;
};

Regarding the disabled state. I guess this is a matter of setting correct css attributes. Just need to add this to the ion-reorder css

.reorder-enabled ion-reorder-group:not(.reorder-enabled) ion-reorder {
  display: none;
}

See: https://stackblitz.com/edit/ionic-5-angular-10-start-template-woqd8q?file=src%2Fapp%2Ftab1%2Ftab1.page.scss

ludufre commented 1 year ago

@digaus have you found a proper solution for this?

digaus commented 1 year ago

@ludufre I now use Angular CDK Drag and Drop ^^

reslear commented 1 year ago

how to implement https://support.apple.com/en-in/guide/reminders/remn32a9622b/mac like this ?

accordion + list + reorder-group + drag-drop?