Popover in draggable and modeless dialog

I have encountered a issue and I’m not sure whether I have not set something correctly or if it’s an error or something unexpected.

I want to display different pieces of information simultaneously and have them remain visible. This isn’t possible with a tooltip, so I’m using popovers instead.

That worked very well. Now, the idea is to display this element in a dialog to better access the information.

It also works without any issues, but it should be modeless and draggable. The issue is related to the modeless of the dialog. When the dialog is moved, the popover goes to the background.

This is the code for the example:

public class TestView extends HorizontalLayout {

    public TestView() {
        final Button open = new Button("Open");
        open.addClickListener(e -> {
            final var dialog = new Dialog();
            dialog.setModal(false);
            dialog.setDraggable(true);

            final var icon = VaadinIcon.INFO_CIRCLE.create();
            dialog.add(icon);
            final var popover = new Popover(VaadinIcon.INFO_CIRCLE.create(), new Text("This is a info text with icon."));
            popover.setTarget(icon);

            dialog.open();
        });
        add(open);
    }
}

With the following code, I’ve found a way to close the popover before moving the dialog.

popover.setModal(true, false);

That’s not my goal, as I want to keep the information open and have multiple pieces visible simultaneously.

During testing, I also noticed issues when using hover:

popover.setOpenOnHover(true);

For example, when I use it as a tooltip with an icon. It also briefly jumps to the back, which doesn’t look good in my opinion:

I haven’t found a solution for this yet, so I’m assuming I might have done something wrong. I would appreciate any help.

The example was created with the Vaadin starter for version 24.7 (pre) to ensure the issue still exists. It also doesn’t work with version 24.6.

The problem here is, that Flow manages overlays to allow users bringing a focused overlay to the “front”. This is done by increasing the z-index of the respective overlays.

Try to set a very high z-index on the popover, e.g. in Java

popover.getStyle().set("z-index", "9999");

or via css stylesheets if you have a general tooltip class.

Yeah, so there’s a feature in the overlay mechanism that brings a modeless Dialog to the top when it’s clicked (or “mouse-downed” to be precise). That makes sense for when you have multiple modeless Dialogs open simultaneously.

I don’t think that should happen with a Popover whose anchoring target is in the Dialog in question, however, since the Popover should then be considered a child of the Dialog.

I would go as far as calling it a bug, so I would propose that you make a bug ticket about it.

Thank you for the quick response. That wasn’t what I expected, as it seems more like a workaround. I’m already using it in several places and have encountered issues, especially when I want a dialog that should truly be on top.

I hoped that I might have overlooked some way to manage the hierarchy, to specify that this would automatically move to the top.

Thank you. I’ll look into it further and open a ticket.

As for a css workaround, you could try setting a higher z-index on the vaadin-popover-overlay element (but I don’t recall the details of how z-index is managed, so not sure if it’ll work).

I have to do that in CSS too, because I get the following error with the suggestion of @Stefan.27

java.lang.UnsupportedOperationException: Popover does not support adding styles to overlay
	at com.vaadin.flow.component.popover.Popover.getStyle(Popover.java:916) ~[vaadin-popover-flow-24.7.0.alpha4.jar:na]
	at com.example.application.views.test.TestView.lambda$new$9b1b5227$1(TestView.java:27) ~[classes/:na]
	at com.vaadin.flow.component.ComponentEventBus.fireEventForListener(ComponentEventBus.java:239) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at com.vaadin.flow.component.ComponentEventBus.handleDomEvent(ComponentEventBus.java:488) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at com.vaadin.flow.component.ComponentEventBus.lambda$addDomTrigger$dd1b7957$1(ComponentEventBus.java:298) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at com.vaadin.flow.internal.nodefeature.ElementListenerMap.lambda$fireEvent$2(ElementListenerMap.java:475) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) ~[na:na]
	at com.vaadin.flow.internal.nodefeature.ElementListenerMap.fireEvent(ElementListenerMap.java:475) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at com.vaadin.flow.server.communication.rpc.EventRpcHandler.handleNode(EventRpcHandler.java:62) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at com.vaadin.flow.server.communication.rpc.AbstractRpcInvocationHandler.handle(AbstractRpcInvocationHandler.java:73) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocationData(ServerRpcHandler.java:565) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at com.vaadin.flow.server.communication.ServerRpcHandler.lambda$handleInvocations$6(ServerRpcHandler.java:546) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) ~[na:na]
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:546) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:373) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:138) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:63) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1664) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:398) ~[flow-server-24.7.0.alpha5.jar:24.7.0.alpha5]
	at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:106) ~[vaadin-spring-24.7.0.alpha5.jar:na]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.34.jar:6.0]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:633) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:409) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:304) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:268) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:142) ~[spring-webmvc-6.2.1.jar:6.2.1]
	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:178) ~[spring-webmvc-6.2.1.jar:6.2.1]
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:51) ~[spring-webmvc-6.2.1.jar:6.2.1]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088) ~[spring-webmvc-6.2.1.jar:6.2.1]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:978) ~[spring-webmvc-6.2.1.jar:6.2.1]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.2.1.jar:6.2.1]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.2.1.jar:6.2.1]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) ~[tomcat-embed-core-10.1.34.jar:6.0]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.2.1.jar:6.2.1]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.34.jar:6.0]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.2.1.jar:6.2.1]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.1.jar:6.2.1]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.2.1.jar:6.2.1]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.1.jar:6.2.1]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.2.1.jar:6.2.1]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.1.jar:6.2.1]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
	at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na]

vaadin-popover-overlay.popover-style::part(content) {
   //add here
}

// styles.css
vaadin-popover-overlay.popover-style::part(overlay) {
    z-index: 9999; /* test this*/
}

popOver.addClassName("popover-style")


I have tried this and several combinations, the PopOver always remains behind the dialog once the dialog is moved.

Yay -_-

Sorry, just tried the theory via dom tools.

2 Likes

I have opened a ticket regarding this issue and will get back to you if I hear anything. I will close the issue as soon as it is resolved: