Spaces:
Sleeping
Sleeping
| Modals display information and accept input from the user. To create a modal, create a class that extends [[Reference/TypeScript API/Modal/Modal|Modal]]: | |
| ```ts | |
| import { App, Modal } from "obsidian"; | |
| export class ExampleModal extends Modal { | |
| constructor(app: App) { | |
| super(app); | |
| } | |
| onOpen() { | |
| let { contentEl } = this; | |
| contentEl.setText("Look at me, I'm a modal! 👀"); | |
| } | |
| onClose() { | |
| let { contentEl } = this; | |
| contentEl.empty(); | |
| } | |
| } | |
| ``` | |
| - [[Reference/TypeScript API/View/onOpen|onOpen()]] is called when the modal is opened and is responsible for building the content of your modal. For more information, refer to [HTML elements](HTML%20elements.md). | |
| - [[Reference/TypeScript API/Modal/onClose|onClose()]] is called when the modal is closed and is responsible for cleaning up any resources used by the modal. | |
| To open a modal, create a new instance of `ExampleModal` and call [[Reference/TypeScript API/Modal/open|open()]] on it: | |
| ```ts | |
| import { Plugin } from "obsidian"; | |
| import { ExampleModal } from "./modal"; | |
| export default class ExamplePlugin extends Plugin { | |
| async onload() { | |
| this.addCommand({ | |
| id: "display-modal", | |
| name: "Display modal", | |
| callback: () => { | |
| new ExampleModal(this.app).open(); | |
| }, | |
| }); | |
| } | |
| } | |
| ``` | |
| ## Accept user input | |
| The modal in the previous example only displayed some text. Let's look at a little more complex example that handles input from the user. | |
| ![[modal-input.png]] | |
| ```ts | |
| import { App, Modal, Setting } from "obsidian"; | |
| export class ExampleModal extends Modal { | |
| result: string; | |
| onSubmit: (result: string) => void; | |
| constructor(app: App, onSubmit: (result: string) => void) { | |
| super(app); | |
| this.onSubmit = onSubmit; | |
| } | |
| onOpen() { | |
| const { contentEl } = this; | |
| contentEl.createEl("h1", { text: "What's your name?" }); | |
| new Setting(contentEl) | |
| .setName("Name") | |
| .addText((text) => | |
| text.onChange((value) => { | |
| this.result = value | |
| })); | |
| new Setting(contentEl) | |
| .addButton((btn) => | |
| btn | |
| .setButtonText("Submit") | |
| .setCta() | |
| .onClick(() => { | |
| this.close(); | |
| this.onSubmit(this.result); | |
| })); | |
| } | |
| onClose() { | |
| let { contentEl } = this; | |
| contentEl.empty(); | |
| } | |
| } | |
| ``` | |
| The result is stored in `this.result` and returned in the `onSubmit` callback when the user clicks **Submit**: | |
| ```ts | |
| new ExampleModal(this.app, (result) => { | |
| new Notice(`Hello, ${result}!`); | |
| }).open(); | |
| ``` | |
| ## Select from list of suggestions | |
| [[SuggestModal|SuggestModal]] is a special modal that lets you display a list of suggestions to the user. | |
| ![[suggest-modal.gif]] | |
| ```ts | |
| import { App, Notice, SuggestModal } from "obsidian"; | |
| interface Book { | |
| title: string; | |
| author: string; | |
| } | |
| const ALL_BOOKS = [ | |
| { | |
| title: "How to Take Smart Notes", | |
| author: "Sönke Ahrens", | |
| }, | |
| { | |
| title: "Thinking, Fast and Slow", | |
| author: "Daniel Kahneman", | |
| }, | |
| { | |
| title: "Deep Work", | |
| author: "Cal Newport", | |
| }, | |
| ]; | |
| export class ExampleModal extends SuggestModal<Book> { | |
| // Returns all available suggestions. | |
| getSuggestions(query: string): Book[] { | |
| return ALL_BOOKS.filter((book) => | |
| book.title.toLowerCase().includes(query.toLowerCase()) | |
| ); | |
| } | |
| // Renders each suggestion item. | |
| renderSuggestion(book: Book, el: HTMLElement) { | |
| el.createEl("div", { text: book.title }); | |
| el.createEl("small", { text: book.author }); | |
| } | |
| // Perform action on the selected suggestion. | |
| onChooseSuggestion(book: Book, evt: MouseEvent | KeyboardEvent) { | |
| new Notice(`Selected ${book.title}`); | |
| } | |
| } | |
| ``` | |
| In addition to `SuggestModal`, the Obsidian API provides an even more specialized type of modal for suggestions: the [[FuzzySuggestModal|FuzzySuggestModal]]. While it doesn't give you the same control of how each item is rendered, you get [fuzzy string search](https://en.wikipedia.org/wiki/Approximate_string_matching) out-of-the-box. | |
| ![[fuzzy-suggestion-modal.png]] | |
| ```ts | |
| export class ExampleModal extends FuzzySuggestModal<Book> { | |
| getItems(): Book[] { | |
| return ALL_BOOKS; | |
| } | |
| getItemText(book: Book): string { | |
| return book.title; | |
| } | |
| onChooseItem(book: Book, evt: MouseEvent | KeyboardEvent) { | |
| new Notice(`Selected ${book.title}`); | |
| } | |
| } | |
| ``` | |