flow
flow copied to clipboard
Browser back should restore body like it was before
Description of the bug
When a dialog is shown (added to the body and set opened true), it does not get cleaned up when using browser back. Same goes with vcf tooltip. This leads to unexpected behaviour, if for example the dialog is confirmed afterwards.
Expected behavior
The dialog should be closed and removed from the body, even if it has no close or cancel action, as browser back is a "hard action"
Minimal reproducible example
Use the following two routes:
@Route("view")
public class View extends Div {
public View() {
add(new Button("go to dialog", e -> UI.getCurrent().navigate("dialog")));
}
}
@Route("dialog")
public class DialogView extends Div {
public DialogView() {
add(new Button("open dialog", e -> {
Dialog dialog = new Dialog(new Span("Do you really want to send?"));
dialog.getFooter().add(new Button("confirm", ev -> {
Span result = new Span("An error occured in the backend");
result.getStyle().set("color", "red");
add(result);
dialog.setOpened(false);
}), new Button("cancel", ev -> dialog.setOpened(false)));
dialog.setOpened(true);
}));
}
}
- Go to "view" and click "go to dialog". Click "open dialog". A dialog opens. Click "confirm" and the backend error is displayed.
- Do that again, but before hitting confirm on the dialog, click browser back button. The dialog is still there. Now try to confirm the dialog. The error is not shown this time.
Versions
- Vaadin / Flow version: 23.1.2
- Java version: 11
If you wanna make sure your dialog is closed on navigation, you can implement BeforeLeaveObserver
on your Dialog sub-class and close it there.
Yes, this is how I did the workaround now. But isn't this a general problem, which others also might notice? I mean, this is not only a problem of the dialog itself, but of every component added to the body including the login overlay or other vcf components. And I also think that it already worked in vaadin 14.
I would argue it's intended, because a dialog can be shown on multiple views / routes and the developer can choose what they want with the tools available. But I'm not working for vaadin, just wanted to give you a quick workaround ;)
I would disagree on this one. A dialog should notify about something or even block the user from working further on the current view. Thus the user would have to close it first and could then interact further to navigate to another view etc. I really don't see a usecase, where the dialog should stay open but the underlying view should change. Not even talking about the login dialog here or tooltips on certain input fields.
There are two different use-cases - a modal dialog, where I'm 100% on your side and non-modal dialogs that can be shown over multiple views, for example a little overlay on the bottom with a chat or contact / support information that a user can open and it stays open while using the app.
The dialog sounds like not the right component for a chat/support overlay. Also this would be something, that has to be added to a router layout, which is there to share components over different views.
@timbo86 I can say this is not a bug since it works as intended. However, there can be some arguments about the default behavior of the dialog while navigating via menu or by manually entering the URL in the address bar or using the back and forward button in different circumstances e.g. being modal or not. Also, I can confirm this is working the same in V14 (dialog remains open when navigating with back and forward buttons).
I found that I have to replace all my Dialog/ConfirmDialog. I think the default behavior should be that all dialogs was closed on navigation.
open class XDialog : Dialog, AfterNavigationObserver {
private var closeAfterNavigation = true
constructor() : super()
constructor(vararg components: Component) : super(*components)
fun setCloseAfterNavigation(b: Boolean) {
closeAfterNavigation = b
}
override fun afterNavigation(event: AfterNavigationEvent) {
if (closeAfterNavigation) this.close()
}