Modals
Modals display information and accept input from the user. To create a modal, create a class that extends Modal
:
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();
}
}
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.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 open()
on it:
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.
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:
new ExampleModal(this.app, (result) => {
new Notice(`Hello, ${result}!`);
}).open();
Select from list of suggestions​
SuggestModal
is a special modal that lets you display a list of suggestions to the user.
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
. While it doesn't give you the same control of how each item is rendered, you get fuzzy string search out-of-the-box.
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}`);
}
}