flow icon indicating copy to clipboard operation
flow copied to clipboard

Browser back should restore body like it was before

Open timbo86 opened this issue 1 year ago • 7 comments

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

timbo86 avatar Jul 27 '22 08:07 timbo86

If you wanna make sure your dialog is closed on navigation, you can implement BeforeLeaveObserver on your Dialog sub-class and close it there.

knoobie avatar Jul 27 '22 10:07 knoobie

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.

timbo86 avatar Jul 27 '22 11:07 timbo86

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 ;)

knoobie avatar Jul 27 '22 11:07 knoobie

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.

timbo86 avatar Jul 27 '22 11:07 timbo86

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.

knoobie avatar Jul 27 '22 11:07 knoobie

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 avatar Jul 27 '22 11:07 timbo86

@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).

taefi avatar Aug 02 '22 12:08 taefi

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()
    }

sveine avatar Jan 02 '23 14:01 sveine