Open deepender87 opened 6 years ago
you should be able to achieve this by simply setting a larger z-index on the notification. It's set to ViewEncapsulation.None
so you should have no problem overriding it.
@flauc Setting a larger z-index does not work, because as #304 states, the modal layer is a direct child of the body element, whereas the notification is nested in a different child of the body element (namely, the app component), which has a lower z-index than the modal layer. Since the notification is nested, its higher z-index has no bearing on the display of the modal layer.
This still doesn't work in 2019. Any updates?
This is indeed a most horrid conundrum. For anyone desperate for a hack to fix it, here's what I did: I created a service to inject components as children of body, then I used it in my App component. Credit to @caroso1222's post at https://hackernoon.com/angular-pro-tip-how-to-dynamically-create-components-in-body-ba200cc289e6 for saving me from a potentially long fight with Angular to try to get a component injected into the body effectively.
1) Create a service like this:
import { ApplicationRef, ComponentFactoryResolver, ComponentRef, EmbeddedViewRef, Injectable, Injector } from '@angular/core';
@Injectable()
export class BodyAdderService {
constructor(
private componentFactoryResolver: ComponentFactoryResolver,
private appRef: ApplicationRef,
private injector: Injector
) {
}
addToBody(component: any, instanceManipulations: any = null, domManipulations: any = null) {
//grab component reference & attach it to the application
const componentRef = this.componentFactoryResolver.resolveComponentFactory(component).create(this.injector);
if(instanceManipulations)
instanceManipulations(componentRef.instance);
this.appRef.attachView(componentRef.hostView);
//throw that dom boi into the body
const domElem = (componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
if(domManipulations)
domManipulations(domElem);
document.body.appendChild(domElem);
//to remove it again:
//this.appRef.detachView(componentRef.hostView);
//componentRef.destroy();
}
}
2) In app.module.ts, do import { SimpleNotificationsComponent } from 'angular2-notifications';
and add entryComponents: [ SimpleNotificationsComponent ]
to @NgModule
. Obviously, import the service and add it to your providers as well.
3) In app.component.ts, again import SimpleNotificationsComponent and your service. Add your BodyAdderService to the constructor, e.g. construtor(..., private bodyAdder: BodyAdderService)
. In the constructor's body, add something like this (the example uses my BodyAdderService so it passes arrow functions to manipulate the component & the dom element, and passes in this.notificationOptions which is simply an angular2-notifications options hash, e.g. { timeOut: 3000, showProgressBar: true, ... }
):
this.bodyAdder.addToBody(SimpleNotificationsComponent, instance => {
instance.options = this.notificationOptions;
}, element => {
element.style = "z-index:1200;"
});
4) Take <simple-notifications></simple-notifications>
out of your app's html template.
NOTES: You may not need the "options" bit, since in theory you can configure that globally in @NgModel
. You may need to modify your z-index to fit your app: AFAIK modal dialogues are set to 1000 so 1200 is high enough, but I'm not sure. There's undoubtedly a better way to get that CSS in there, but CSS is the bane of my existence and after several attempts to get something working in app.component.scss I gave up and injected it inline into the DOM element. Anyone with a better solution for the CSS bit feel free to let me know.
@flauc It might be possible to roll some kind of dynamic injection like this into the repo without too much trouble, so that users can add something to their component's constructor, rather than adding the <simple-notifications>
tag to their html template, to get body injection. I have too many uncertainties about how to do that well to try to add it to a fork right now; I'll take a look if I get time, and in the meantime there's an idea at least.
Hopefully this post will be helpful to someone who is suddenly blindsided by this issue like I was this morning! No idea how I've never come across this problem in the last 2 years.
Thank you for taking time for writing the answer @sapphous . The whole reason that I chose adding a new library i.e. angular2-notification
over Angular Material Snackbar
was that it is simple to use and call. If it is going to cause so much of an issues for just visibility then I have no reason to use it. So, I think the library should natively support this.
a simpler solution is to not only add the
@JanvanCasteren Not getting your point. please elaborate it
I have <simple-notifications [options]="notificationOptions"> included in my appComponents html.
Like @deepender87 states, when using a popup dialog, the notification popups appear behind the dialog.
My solution was to simple add a second simple-notifications element inside the dialogs content section.
In my case (I use primeng dialogs):
<p-dialog ....>
<!-- all html between <p-dialog ....> and </p-dialog> will be shown as dialog content -->
<div>this is dialog content</div>
<simple-notifications [options]="notificationOptions"></simple-notifications><!-- this notification will show render above the dialog -->
</p-dialog>
At First: I tried use solution [which suggested by @flauc -> Here ] for change z-index
style, It works with me, I must override z-index
of modal background overlay with values less than notification layout plus use ViewEncapsulation.None
under Component like this:
Style file:
ngb-modal-backdrop.modal-backdrop {
z-index: 9000 !important;
}
.my-modal {
z-index: 9100 !important;
}
div.simple-notification-wrapper {
z-index: 9999 !important;
}
Component class:
@Component({
selector: 'app-my-modal',
templateUrl: './my-modal.component.html',
styleUrls: ['./my-modal.component.css'],
encapsulation: ViewEncapsulation.None
})
export class MyModalComponent implements OnInit {}
But This solution may be bug in case there two pop-up modal into same page (one which override it's z-index and another with default Bootstrap Modal style), Scenario for Bug: when open First The override Modal style then Open The modal with default Style Will display Background overlay above model view as we use ViewEncapsulation.None
into Component class.
Then: I tried use another solution [which suggested by @JanvanCasteren -> Here ] of put <simple-notification>
tag with-in Modal view without any style override, it work with me Even this solution was settings duplicate <simple-notification>
tag as the main one setting under app.Component
class's view.(There no duplicate notifications will display)
Finally: I hope this issue will be solved using Library's Options without need to try any workaround before 2021
@JanvanCasteren you saved me a few hours :) So simple
As per the steps mentioned in the notification example, I had set up it in my app component
<simple-notifications [options]="notificationOptions" (onCreate)="onNotificationsCreate($event)" (onDestroy)="onNotificationsDestroy($event)" class="mm-alerts-popup"></simple-notifications>
Now it is showing the notification all over the places wherever it is required. Issue is I have specific page which has a form filling popup (modal) If i want to validate the data i am calling the notification service and showing the message. But as the "simple-notifications" component is at app level, it is showing below the popup/Modal. How i can achieve this? so that at this point i can show this over popup not at below of it.