Rask
Rask
v0.23.1-alpha.0.642

Components

Confirm leave

The dialog a form's ConfirmLeave("…") asks in before the reader walks away from what they typed, in place of the browser's own confirm. Place Ui.ConfirmLeave in the layout once and every guarded form asks through it. Not one of Flux UI's components: the kit's own, a Ui.Modal drawn as Flux's confirmation.

Ask before leaving

Type a note, then follow any link in the sidebar or press Back: the form's message is the dialog's title. Stay keeps the page exactly as it was; Save ends the guard until the next edit.

ConfirmLeaveExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

// This tab's layout places Ui.ConfirmLeave once. From the first thing typed, every way out of the page asks in it
// with the form's message, until a save that passed validation.
public sealed partial class ConfirmLeaveExample : Component
{
    private readonly Note _note = new();
    private string? _saved;

    protected override Component? Render() =>
        Div.Class("space-y-3")[
            Form.Model(_note).OnSubmit(Save).Id("ucl-form").Class("flex flex-wrap items-end gap-4")
                .ConfirmLeave("Leave without saving your note?")[
                Ui.Input.Bind(() => _note.Text).Label("Note").Id("ucl-input").Class("max-w-xs"),
                Ui.Button.Primary.Submit.Id("ucl-save")["Save"]
            ],
            Ui.Text.Id("ucl-saved")[_saved is null ? "Nothing saved yet." : "Saved: " + _saved]
        ];

    private void Save(Note note) => _saved = note.Text;

    public sealed class Note
    {
        public string Text { get; set; } = "";
    }
}
Live result

Nothing saved yet.

Your own words

Stay and Leave name the two buttons, and Heading puts a short title over the form's question, the shape Ui.Confirm always has. A layout of its own, framed, because a page holds one dialog: type, then follow Tovább.

ConfirmLeaveWordsExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

// A layout of your own places the dialog once, in your words: a short title over the form's question, and the
// two buttons.
public sealed partial class ConfirmLeaveWordsExample : Component
{
    private readonly Note _note = new();

    protected override Component? Render() =>
    [
        Ui.Main.Class("flex min-h-dvh items-center justify-center")[
            Form.Model(_note).OnSubmit(_ => { }).Id("ucl-words-form").Class("flex flex-wrap items-end gap-4")
                .ConfirmLeave("A jegyzet még nincs mentve. Elhagyja az oldalt?")[
                Ui.Input.Bind(() => _note.Text).Label("Jegyzet").Id("ucl-words-input").Class("max-w-xs"),
                Ui.Button.Primary.Submit["Mentés"],
                Ui.Link.Href(PageMeta.LinkTo(Routes.ConfirmWordsDemoPage())).Id("ucl-words-away")["Tovább"]
            ]
        ],
        Ui.ConfirmLeave.Heading("Nem mentett változások").Stay("Nem").Leave("Igen")
    ];

    public sealed class Note
    {
        public string Text { get; set; } = "";
    }
}
Live result

Behaviour

Placed once

Ui.ConfirmLeave goes in the layout, and every form with ConfirmLeave("…") under it asks in that dialog. The forms do not change. Without it a guarded form asks in the browser's own window.confirm.

When a form is unsaved

From the first thing typed or changed in it, decided in the browser, so it holds for a value the server has not seen yet. It is no comparison with the first values: typing a value and typing it back still counts.

A submit that passed validation and whose handler returned makes it clean again, until the next edit. A navigation your own handler makes never asks, so "save, then go to the list" needs nothing more. With several guarded forms on a page, the first unsaved one asks, in its own words.

What asks

Every way out of the page asks first, while the form is unsaved:

The reader
What happens
follows a link inside the appThis dialog, with the form's message.
is navigated by front-end code (__raskHost.navigate(…))This dialog.
presses Back or ForwardThis dialog; staying puts the address and the history back.
closes the Ui.Modal the form is inThis dialog; staying keeps the modal open with what was typed.
closes the tab, reloads, or follows a link out of the appThe browser's own prompt, whose text no page can set.

Staying, and leaving

Stay, the close button, Escape and a press outside all keep the reader on the page exactly as it was, typed values included, and send nothing. Leave carries on with the navigation that was asked for: the same link, the same history entry Back was going to.

The dialog is rendered closed and opened in the browser, never lazily, because what it guards is what the server has not seen. Unset, Heading leaves the form's question as the title, with room kept for the close button; Stay and Leave default from the string catalog (ConfirmLeaveStay, ConfirmLeaveLeave).

Reference

Ui.ConfirmLeave

not in Flux UI

The dialog a form's ConfirmLeave("…") asks in before the reader leaves it unsaved, in place of the browser's confirm. One per page.

Step
Takes
What it does
.Heading(…)stringA short title above the form's question. Unset, the question itself is the title.
.Stay(…)stringThe label of the button that keeps the reader on the page. "Stay" when unset.
.Leave(…)stringThe label of the button that leaves, dropping what was typed. "Leave" when unset.

Confirm