igniteui-angular icon indicating copy to clipboard operation
igniteui-angular copied to clipboard

stopPropagation on click in the igx-dialog component

Open georgianastasov opened this issue 2 years ago • 2 comments

Description

Currently the dialog is defined like this: <div tabindex="0" #dialog class="igx-dialog" igxToggle [igxFocusTrap]="focusTrap" (click)="onDialogSelected($event)"></div>

When clicked in the dialog stopPropagation is called: public onDialogSelected(event) { event.stopPropagation(); //... }

With this implementation, event propagation is always stopped at the moment. This implementation is made in relation to scenarios with nested igx-dialog components. This is because when we have nested igx-dialog components and a click is made outside the inner igx-dialog, only it should close, and the parent dialog should remain open as this is related to this issue.

However, this implementation leads to the impossibility of closing some components inside the dialog, such as context menus, because after opening a context menu in the igx-dialog component, when clicking outside the context menu but inside the igx-dialog component, it cannot close because stopPropagation is called.

  • igniteui-angular version: any
  • browser: any

Steps to reproduce

  1. Create igx-dialog with context menu in in.
  2. Handle @HostListener('document:click', ['$event']) to close the context menu.
  3. Click in the igx-dialog component.

Result

The context menu does not close.

Expected result

The context menu should close.

Attachments

The issue is discussed in this discussions.

georgianastasov avatar Jan 30 '24 12:01 georgianastasov

There has been no recent activity and this issue has been marked inactive.

github-actions[bot] avatar Apr 07 '24 00:04 github-actions[bot]

@Lipata Hi, is there any plan to address this issue?

Timmeeeey avatar Apr 08 '24 08:04 Timmeeeey

There has been no recent activity and this issue has been marked inactive.

github-actions[bot] avatar Jun 08 '24 00:06 github-actions[bot]

Hi @Timmeeeey

After thorough discussions with the development team, we have come to an agreement regarding this issue. It has been decided that we will not be fixing this issue within the current implementation.

As a proposed solution, we recommend using another overlay to show the context menu within the igx-dialog component. By using the IgxOverlayService, you can create and attach an overlay to display your context menu. This approach will avoid the described behavior and allow you to close the overlay by clicking anywhere in the document, including on top of the igx-dialog component.

For more information on how to use the IgxOverlayService, please refer to the documentation here: IgxOverlayService Documentation.

georgianastasov avatar Jun 20 '24 08:06 georgianastasov

Hi @georgianastasov Since I use a third-party context menu (PerfectMemory/ngx-contextmenu), I don't know how I could use the IgxOverlayService.

Timmeeeey avatar Jun 20 '24 08:06 Timmeeeey

Hi @Timmeeeey,

All this information and detailed steps on how to do it can be found in the official documentation here: IgxOverlayService Documentation.

However, the IgxOverlayService can be used to dynamically display an HTMLNode or even an Angular Component by attaching it to the overlay DOM.

After a reference to the Overlay service is established, it can be used to dynamically show/hide content. For example, we can pass an Angular Component in the attach method. This will generate a unique ID, which we can pass to the show method to display the component. When displaying an Angular Component, a second mandatory parameter ViewContainerRef should be passed in the attach method.

Here's a basic example of how to achieve this:

import { NgxContextmenuComponent } from '../ngx-contextmenu.component.ts';
import { Component, ViewContainerRef, Inject } from '@angular/core';
import { IgxOverlayService } from 'igniteui-angular';

@Component({...})
export class MyOverlayComponent {
    private _overlayId = ''; // The unique identifier assigned to the component by the Overlay service

    constructor(
        @Inject(IgxOverlayService) private overlayService: IgxOverlayService,
        private viewContainerRef: ViewContainerRef
    ) {}

    public showInOverlay() {
        if (!this._overlayId) {
            this._overlayId = this.overlayService.attach(NgxContextmenuComponent, this.viewContainerRef);
        }
        this.overlayService.show(this._overlayId);
    }
}
<igx-dialog>
    <div igxDialogActions>
         <button (click)="showInOverlay()">Show Context Menu</button>
    </div>
</igx-dialog>

This example demonstrates how to use the IgxOverlayService to dynamically display an Angular component. You can adapt this approach to integrate with the ngx-contextmenu by wrapping the context menu in a component and attaching it to the overlay.

georgianastasov avatar Jun 20 '24 08:06 georgianastasov

Ok, I think I have to use the attach(element: ElementRef, settings?: OverlaySettings) because the component has inputs. This seems to work but when opening the context menu, the background darkens. Can this be prevented?

Timmeeeey avatar Jun 20 '24 09:06 Timmeeeey

Hello @Timmeeeey

Yes, this can be prevented to avoid dimming the screen behind. The screen darkens because, by default, when a new overlay is attached, it is modal. You can handle this by using OverlaySettings and setting the modal property to false so that the attached overlay is not modal. Additionally, you can manage other properties such as the position of the attached overlay, specifying exactly where it should appear in relation to the button that deploys it, and more.

Here's an example of how to do this:

this._overlayId = this.overlayService.attach(element, {
    target: this.buttonElement.nativeElement,
    positionStrategy,
    modal: false,
    closeOnOutsideClick: true
});

In this example, modal: false ensures that the overlay is not modal, preventing the background from darkening. You can also specify the target and positionStrategy to control where the overlay appears.

For more detailed information on how to customize the overlay settings, especially the "Attaching Settings" section, please refer to the IgxOverlayService Documentation.

georgianastasov avatar Jun 20 '24 09:06 georgianastasov

@georgianastasov It didn't work without modal true, but I figured out another solution with a custom backdrop.

Timmeeeey avatar Jun 20 '24 10:06 Timmeeeey

Hello @Timmeeeey

Thank you for the update. I'm glad to hear that you found a solution using a custom backdrop. If you need any further assistance or have any other questions, please feel free to reach out.

georgianastasov avatar Jun 20 '24 10:06 georgianastasov