Open a native <dialog> declaratively with the Invoker Commands API
(command="show-modal" + commandfor) or a plain #id hash link — no inline
JavaScript. A valid submit closes the dialog and shows a success flash; an invalid
submit keeps it open with field errors rendered inside, because the form posts
through LiveTemplate and re-renders the same region.
Modal Dialog
Native <dialog> opened via the Invoker Commands API (command="show-modal" + commandfor) or directly via a hash link (<a href="#edit-dialog">, client v0.8.30+). Submitting the form with valid input closes the dialog and shows a success flash; invalid input keeps it open with field errors rendered inside (client v0.8.33+).
Profile
Ada Lovelace · ada@analytical.engine
Template
The trigger button carries command/commandfor; the Cancel button closes via
command="close". BindAndValidate populates AriaInvalid and ErrorTag so a
failed save renders errors next to each field without closing the dialog.
{{define "content"}}
<article>
<h3>Modal Dialog</h3>
<p><small>Native <code><dialog></code> opened via the Invoker Commands API (<code>command="show-modal"</code> + <code>commandfor</code>) or directly via a hash link (<code><a href="#edit-dialog"></code>, client v0.8.30+). Submitting the form with valid input closes the dialog and shows a success flash; invalid input keeps it open with field errors rendered inside (client v0.8.33+).</small></p>
<dl>
<dt><strong>Profile</strong></dt>
<dd>{{.Name}} · <small>{{.Email}}</small>{{if .SavedAt}} · <small>Saved at {{.SavedAt}}</small>{{end}}</dd>
</dl>
<fieldset role="group">
<button command="show-modal" commandfor="edit-dialog">Edit profile</button>
<a href="#edit-dialog" role="button" class="secondary outline">Open via URL hash</a>
</fieldset>
{{.lvt.FlashTag "success"}}
<dialog id="edit-dialog">
<article>
<header>
<h4>Edit profile</h4>
</header>
<form method="POST">
<label>
Name
<input name="name" value="{{.Name}}" required minlength="3" {{.lvt.AriaInvalid "name"}}>
{{.lvt.ErrorTag "name"}}
</label>
<label>
Email
<input type="email" name="email" value="{{.Email}}" required {{.lvt.AriaInvalid "email"}}>
{{.lvt.ErrorTag "email"}}
</label>
<footer>
<fieldset role="group">
<button name="save" type="submit">Save</button>
<button type="button" command="close" commandfor="edit-dialog" class="secondary">Cancel</button>
</fieldset>
</footer>
</form>
</article>
</dialog>
</article>
{{end}}