-
Notifications
You must be signed in to change notification settings - Fork 23k
Revise: Web APIs / HTMLDialogElement Docs #42127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
ceff1d9
9e0a4da
3cbedd6
934a7de
2700086
a91d0ed
f1e0188
8f63119
d330ecc
c712c96
aa808be
f492cc0
2c5c894
8d54106
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -8,11 +8,15 @@ browser-compat: api.HTMLDialogElement.cancel_event | |||||
|
|
||||||
| {{APIRef("HTML DOM")}} | ||||||
|
|
||||||
| The **`cancel`** event fires on a {{HTMLElement("dialog")}} element when the user instructs the browser that they wish to dismiss the current open dialog. The browser fires this event when the user presses the <kbd>Esc</kbd> key. | ||||||
| The **`cancel`** event fires on a {{HTMLElement("dialog")}} element when the user sends a [close request](https://html.spec.whatwg.org/multipage/interaction.html#close-request) to the user agent. | ||||||
|
|
||||||
| This event is cancelable but can not bubble. | ||||||
| Examples of close requests are: | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| - Pressing the <kbd>Esc</kbd> key on desktop platforms | ||||||
| - Calling the {{domxref("HTMLDialogElement.requestClose()", "requestClose()")}} method. | ||||||
| - The back button on mobile platforms | ||||||
|
|
||||||
| When a `<dialog>` is dismissed with the <kbd>Esc</kbd> key, both the `cancel` and {{domxref("HTMLDialogElement/close_event", "close")}} events are fired. | ||||||
| This event is cancelable but can not bubble. | ||||||
|
|
||||||
| ## Syntax | ||||||
|
|
||||||
|
|
@@ -32,55 +36,80 @@ A generic {{domxref("Event")}}. | |||||
|
|
||||||
| ### Canceling a dialog | ||||||
|
|
||||||
| The following example shows a button that, when clicked, opens a {{htmlelement("dialog")}} via the {{domxref("HTMLDialogElement.showModal()", "showModal()")}} method. | ||||||
|
|
||||||
| From there you can trigger the `cancel` event by either clicking _Request Close_ button to close the dialog (via the {{domxref("HTMLDialogElement.requestClose()", "requestClose()")}} method), or press the <kbd>Esc</kbd> key. | ||||||
|
|
||||||
| Preventing the dialog from closing is demonstrated with a checkbox. | ||||||
|
Comment on lines
+39
to
+43
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is obviously a lot better than no explanation! If I am doing a method-specific document, I tend to structure like " However in this case we have a number of examples that seem to be the same - such as requestClose. In that case I might keep your current structure, but in Thoughts? |
||||||
|
|
||||||
| #### HTML | ||||||
|
|
||||||
| ```html | ||||||
| <dialog class="example-dialog"> | ||||||
| <button class="close">Close</button> | ||||||
| <dialog id="dialog"> | ||||||
| <div> | ||||||
| <label><input type="checkbox" id="prevent-close" /> prevent close</label> | ||||||
| </div> | ||||||
| <button type="button" id="request-close">Request Close</button> | ||||||
| </dialog> | ||||||
|
|
||||||
| <button class="open-dialog">Open dialog</button> | ||||||
| <button id="open">Open dialog</button> | ||||||
| ``` | ||||||
|
|
||||||
| <div class="result"></div> | ||||||
| ```html hidden | ||||||
| <pre id="status-text"></pre> | ||||||
| ``` | ||||||
|
|
||||||
| ```css hidden | ||||||
| button, | ||||||
| div { | ||||||
| margin: 0.5rem; | ||||||
| #status-text { | ||||||
| height: 120px; | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider doubling this as well |
||||||
| overflow: scroll; | ||||||
| padding: 0.5rem; | ||||||
| border: 1px solid black; | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| #### JavaScript | ||||||
| ```js hidden | ||||||
| const statusText = document.getElementById("status-text"); | ||||||
| function log(text) { | ||||||
| statusText.innerText = `${statusText.innerText}${text}\n`; | ||||||
| statusText.scrollTop = statusText.scrollHeight; | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| ```js | ||||||
| const result = document.querySelector(".result"); | ||||||
|
|
||||||
| const dialog = document.querySelector(".example-dialog"); | ||||||
| const dialog = document.getElementById("dialog"); | ||||||
| const openButton = document.getElementById("open"); | ||||||
| const requestCloseButton = document.getElementById("request-close"); | ||||||
| const preventCloseInput = document.getElementById("prevent-close"); | ||||||
|
|
||||||
| // Update button opens a modal dialog | ||||||
| openButton.addEventListener("click", () => { | ||||||
| dialog.showModal(); | ||||||
| }); | ||||||
|
|
||||||
| dialog.addEventListener("cancel", (event) => { | ||||||
| result.textContent = "dialog was canceled"; | ||||||
| // Request close | ||||||
| requestCloseButton.addEventListener("click", () => { | ||||||
| // Triggers the cancel event | ||||||
| dialog.requestClose(); | ||||||
| }); | ||||||
|
|
||||||
| const openDialog = document.querySelector(".open-dialog"); | ||||||
| openDialog.addEventListener("click", () => { | ||||||
| if (typeof dialog.showModal === "function") { | ||||||
| dialog.showModal(); | ||||||
| result.textContent = ""; | ||||||
| } else { | ||||||
| result.textContent = "The dialog API is not supported by this browser"; | ||||||
| // Fired when requestClose() is called | ||||||
| // Prevent the dialog from closing by calling event.preventDefault() | ||||||
| dialog.addEventListener("cancel", (event) => { | ||||||
| if (preventCloseInput.checked) { | ||||||
| log("Dialog close cancelled"); | ||||||
| event.preventDefault(); | ||||||
| } | ||||||
| }); | ||||||
|
|
||||||
| const closeButton = document.querySelector(".close"); | ||||||
| closeButton.addEventListener("click", () => { | ||||||
| dialog.close(); | ||||||
| dialog.addEventListener("close", (event) => { | ||||||
| log("Dialog closed"); | ||||||
| }); | ||||||
| ``` | ||||||
|
|
||||||
| #### Result | ||||||
|
|
||||||
| {{ EmbedLiveSample('Canceling a dialog', '100%', '100px') }} | ||||||
| {{ EmbedLiveSample('Canceling a dialog', '100%', '250px') }} | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interestingly, I'm showing Chrome sending a |
||||||
|
|
||||||
| ## Specifications | ||||||
|
|
||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,7 +9,7 @@ browser-compat: api.HTMLDialogElement.close | |||||||||||||||||||||||||
| {{ APIRef("HTML DOM") }} | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| The **`close()`** method of the {{domxref("HTMLDialogElement")}} interface closes the {{htmlelement("dialog")}}. | ||||||||||||||||||||||||||
| An optional string may be passed as an argument, updating the `returnValue` of the dialog. | ||||||||||||||||||||||||||
| An optional string may be passed as an argument, updating the {{domxref("HTMLDialogElement.returnValue", "returnValue")}} of the dialog. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth noting what event(s) is/are fired? Can closing be prevented?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... and adding those relevant events as See also section at end. |
||||||||||||||||||||||||||
| ## Syntax | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
@@ -29,68 +29,74 @@ None ({{jsxref("undefined")}}). | |||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Examples | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| The following example shows a simple button that, when clicked, opens a {{htmlelement("dialog")}} containing a form via the `showModal()` method. | ||||||||||||||||||||||||||
| From there you can click the _X_ button to close the dialog (via the `HTMLDialogElement.close()` method), or submit the form via the submit button. | ||||||||||||||||||||||||||
| The following example shows a button that, when clicked, opens a {{htmlelement("dialog")}} via the {{domxref("HTMLDialogElement.showModal()", "showModal()")}} method. | ||||||||||||||||||||||||||
| From there you can click the either _Close_ button to close the dialog (via the `close()` method). | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| The _Close_ button closes the dialog without a {{domxref("HTMLDialogElement.returnValue", "returnValue")}}, while the _Close w/ return value_ button closes the dialog with a {{domxref("HTMLDialogElement.returnValue", "returnValue")}}. | ||||||||||||||||||||||||||
|
Comment on lines
+32
to
+35
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The template likes a level 3 heading for Web API examples, or it should :-)
Suggested change
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```html | ||||||||||||||||||||||||||
| <!-- Simple pop-up dialog box, containing a form --> | ||||||||||||||||||||||||||
| <dialog id="favDialog"> | ||||||||||||||||||||||||||
| <form method="dialog"> | ||||||||||||||||||||||||||
| <button type="button" id="close" aria-label="close">X</button> | ||||||||||||||||||||||||||
| <section> | ||||||||||||||||||||||||||
| <p> | ||||||||||||||||||||||||||
| <label for="favAnimal">Favorite animal:</label> | ||||||||||||||||||||||||||
| <select id="favAnimal" name="favAnimal"> | ||||||||||||||||||||||||||
| <option></option> | ||||||||||||||||||||||||||
| <option>Brine shrimp</option> | ||||||||||||||||||||||||||
| <option>Red panda</option> | ||||||||||||||||||||||||||
| <option>Spider monkey</option> | ||||||||||||||||||||||||||
| </select> | ||||||||||||||||||||||||||
| </p> | ||||||||||||||||||||||||||
| </section> | ||||||||||||||||||||||||||
| <menu> | ||||||||||||||||||||||||||
| <li> | ||||||||||||||||||||||||||
| <button type="reset">Reset</button> | ||||||||||||||||||||||||||
| </li> | ||||||||||||||||||||||||||
| <li> | ||||||||||||||||||||||||||
| <button type="submit">Confirm</button> | ||||||||||||||||||||||||||
| </li> | ||||||||||||||||||||||||||
| </menu> | ||||||||||||||||||||||||||
| </form> | ||||||||||||||||||||||||||
| <dialog id="dialog"> | ||||||||||||||||||||||||||
| <button type="button" id="close">Close</button> | ||||||||||||||||||||||||||
| <button type="button" id="close-w-value">Close w/ return value</button> | ||||||||||||||||||||||||||
| </dialog> | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| <button id="updateDetails">Update details</button> | ||||||||||||||||||||||||||
| <button id="open">Open dialog</button> | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```html hidden | ||||||||||||||||||||||||||
| <pre id="status-text"></pre> | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```css hidden | ||||||||||||||||||||||||||
| #status-text { | ||||||||||||||||||||||||||
| height: 120px; | ||||||||||||||||||||||||||
| overflow: scroll; | ||||||||||||||||||||||||||
| padding: 0.5rem; | ||||||||||||||||||||||||||
| border: 1px solid black; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```js hidden | ||||||||||||||||||||||||||
| const statusText = document.getElementById("status-text"); | ||||||||||||||||||||||||||
| function log(text) { | ||||||||||||||||||||||||||
| statusText.innerText = `${statusText.innerText}${text}\n`; | ||||||||||||||||||||||||||
| statusText.scrollTop = statusText.scrollHeight; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```js | ||||||||||||||||||||||||||
| const updateButton = document.getElementById("updateDetails"); | ||||||||||||||||||||||||||
| const dialog = document.getElementById("dialog"); | ||||||||||||||||||||||||||
| const openButton = document.getElementById("open"); | ||||||||||||||||||||||||||
| const closeButton = document.getElementById("close"); | ||||||||||||||||||||||||||
| const dialog = document.getElementById("favDialog"); | ||||||||||||||||||||||||||
| dialog.returnValue = "favAnimal"; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| function openCheck(dialog) { | ||||||||||||||||||||||||||
| if (dialog.open) { | ||||||||||||||||||||||||||
| console.log("Dialog open"); | ||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||
| console.log("Dialog closed"); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| const closeWithValueButton = document.getElementById("close-w-value"); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Update button opens a modal dialog | ||||||||||||||||||||||||||
| updateButton.addEventListener("click", () => { | ||||||||||||||||||||||||||
| openButton.addEventListener("click", () => { | ||||||||||||||||||||||||||
| // Reset the return value | ||||||||||||||||||||||||||
| dialog.returnValue = ""; | ||||||||||||||||||||||||||
| // Rhow the dialog | ||||||||||||||||||||||||||
| dialog.showModal(); | ||||||||||||||||||||||||||
| openCheck(dialog); | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Form close button closes the dialog box | ||||||||||||||||||||||||||
| // Close button closes the dialog box | ||||||||||||||||||||||||||
| closeButton.addEventListener("click", () => { | ||||||||||||||||||||||||||
| dialog.close("animalNotChosen"); | ||||||||||||||||||||||||||
| openCheck(dialog); | ||||||||||||||||||||||||||
| dialog.close(); | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Close button closes the dialog box with a return value | ||||||||||||||||||||||||||
| closeWithValueButton.addEventListener("click", () => { | ||||||||||||||||||||||||||
| dialog.close("some value"); | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Form close button closes the dialog box | ||||||||||||||||||||||||||
| dialog.addEventListener("close", () => { | ||||||||||||||||||||||||||
| log(`Dialog closed. Return value: "${dialog.returnValue}"`); | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| If the "X" button was of `type="submit"`, the dialog would have closed without requiring JavaScript. | ||||||||||||||||||||||||||
| A form submission closes the `<dialog>` it is nested within if the [form's method is `dialog`](/en-US/docs/Web/HTML/Reference/Elements/form#method), so no "close" button is required. | ||||||||||||||||||||||||||
| > [!NOTE] | ||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||
| > You know you can also automatically close a `<dialog>` by submitting a {{htmlelement("form")}} element with a [`method="dialog"`](/en-US/docs/Web/HTML/Reference/Elements/form#method) attribute. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### Result | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,46 +33,57 @@ A generic {{domxref("Event")}}. | |
| #### HTML | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's change
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you want to explain it? In particular perhaps link to information on |
||
|
|
||
| ```html | ||
| <dialog class="example-dialog"> | ||
| <dialog id="dialog"> | ||
| <form method="dialog"> | ||
| <button>Close via method="dialog"</button> | ||
| <button type="submit">Close via method="dialog"</button> | ||
| </form> | ||
| <button class="close">Close via .close() method</button> | ||
| <button id="close">Close via .close() method</button> | ||
| <p>Or hit the <kbd>Esc</kbd> key</p> | ||
| </dialog> | ||
|
|
||
| <button class="open-dialog">Open dialog</button> | ||
| <button id="open">Open dialog</button> | ||
| ``` | ||
|
|
||
| <div class="result"></div> | ||
| ```html hidden | ||
| <pre id="status-text"></pre> | ||
| ``` | ||
|
|
||
| ```css hidden | ||
| button, | ||
| div { | ||
| margin: 0.5rem; | ||
| #status-text { | ||
| height: 120px; | ||
| overflow: scroll; | ||
| padding: 0.5rem; | ||
| border: 1px solid black; | ||
| } | ||
| ``` | ||
|
|
||
| ```js hidden | ||
| const statusText = document.getElementById("status-text"); | ||
| function log(text) { | ||
| statusText.innerText = `${statusText.innerText}${text}\n`; | ||
| statusText.scrollTop = statusText.scrollHeight; | ||
| } | ||
| ``` | ||
|
|
||
| #### JavaScript | ||
|
|
||
| ```js | ||
| const result = document.querySelector(".result"); | ||
|
|
||
| const dialog = document.querySelector(".example-dialog"); | ||
| dialog.addEventListener("close", (event) => { | ||
| result.textContent = "dialog was closed"; | ||
| }); | ||
| const dialog = document.getElementById("dialog"); | ||
| const openButton = document.getElementById("open"); | ||
| const closeButton = document.getElementById("close"); | ||
|
|
||
| const openDialog = document.querySelector(".open-dialog"); | ||
| openDialog.addEventListener("click", () => { | ||
| openButton.addEventListener("click", () => { | ||
| dialog.showModal(); | ||
| result.textContent = ""; | ||
| log("dialog: opened"); | ||
| }); | ||
|
|
||
| const closeButton = document.querySelector(".close"); | ||
| closeButton.addEventListener("click", () => { | ||
| dialog.close(); | ||
| }); | ||
|
|
||
| dialog.addEventListener("close", (event) => { | ||
| log("dialog: closed"); | ||
| }); | ||
| ``` | ||
|
|
||
| #### Result | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -16,11 +16,18 @@ The **`closedBy`** property of the | |||||
| A string; possible values are: | ||||||
|
|
||||||
| - `any` | ||||||
| - : The dialog can be dismissed with a light dismiss user action, a platform-specific user action, or a developer-specified mechanism. | ||||||
| - : The dialog can be dismissed by a [close request](https://html.spec.whatwg.org/multipage/interaction.html#close-request) or clicks outside the dialog. | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No spec links
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, I would not purge the term "light dismiss" - its in the spec and other docs. You could define it if you want. I'd be tempted to revert this. If you want the pattern then maybe define earlier what the different close options are, such as close request and light dismiss and platform-specific user action.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto below |
||||||
| - `closerequest` | ||||||
| - : The dialog can be dismissed with a platform-specific user action or a developer-specified mechanism. | ||||||
| - : The dialog can only be dismissed by a [close request](https://html.spec.whatwg.org/multipage/interaction.html#close-request). | ||||||
| - `none` | ||||||
| - : The dialog can only be dismissed with a developer-specified mechanism. | ||||||
| - : No user actions automatically close the dialog. The dialog can only be dismissed with a developer-specified mechanism. | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An improvement, but perhaps be even more specific - such as
Suggested change
|
||||||
|
|
||||||
| ### Default behaviour | ||||||
|
|
||||||
| If the `closedby` attribute is absent or invalid, it falls back to the **Auto** state. In the **Auto** state: | ||||||
|
|
||||||
| - when the `<dialog>` is opened with `showModal()`, it behaves as if: `closedby="closerequest"` | ||||||
| - when the `<dialog>` is opened by any other means, it behaves as if: `closedby="none"` | ||||||
|
|
||||||
| ## Examples | ||||||
|
|
||||||
|
|
@@ -30,14 +37,14 @@ A string; possible values are: | |||||
| <dialog open closedby="any"> | ||||||
| <h2>My dialog</h2> | ||||||
| <p> | ||||||
| Closable using the Esc key, or by clicking outside the dialog. "Light | ||||||
| dismiss" behavior. | ||||||
| Closable using the <kbd>Esc</kbd> key, or by clicking outside the dialog | ||||||
| ("light dismiss"). | ||||||
| </p> | ||||||
| </dialog> | ||||||
| ``` | ||||||
|
|
||||||
| ```js | ||||||
| const dialogElem = document.querySelector("dialog"); | ||||||
| const dialog = document.querySelector("dialog"); | ||||||
|
|
||||||
| // Logs "any" to the console | ||||||
| console.log(dialogElem.closedBy); | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Propose