Modals
Modals allows your users to use an interface to easily fill out forms, useful for filling out complex inputs or very large texts.
Modals are handled in two parts: Creating the form and Handling submissions. The first part is provided by Discord.JS and only the latter is handled by the framework, reason being much like Embeds, forms can be dynamically created, allowing you to freely handle and create modals while easily handling submissions in a single location.
Creating Modals
TIP
Modals can be attached to any command interaction, meaning you can reuse the same handler across multiple commands.
import { defineMessageCommand } from 'chooksie'
import type { ModalActionRowComponent } from 'discord.js'
import { MessageActionRow, Modal, TextInputComponent } from 'discord.js'
export default defineMessageCommand({
name: 'Tag Image',
async execute(ctx) {
const modal = new Modal()
// IMPORTANT: this must match the handler's customId
.setCustomId('tag-image')
.setTitle('Create a new Tag')
const tagList = new TextInputComponent()
.setCustomId('tag-list')
.setLabel('Tags')
.setPlaceholder('Separate tags with spaces.')
.setStyle('PARAGRAPH')
.setRequired()
modal.addComponents(
new MessageActionRow<ModalActionRowComponent>()
.addComponents(tagList),
)
await ctx.interaction.showModal(modal)
},
})
import { defineMessageCommand } from 'chooksie'
import { MessageActionRow, Modal, TextInputComponent } from 'discord.js'
export default defineMessageCommand({
name: 'Tag Image',
async execute(ctx) {
const modal = new Modal()
// IMPORTANT: this must match the handler's customId
.setCustomId('tag-image')
.setTitle('Create a new Tag')
const tagList = new TextInputComponent()
.setCustomId('tag-list')
.setLabel('Tags')
.setPlaceholder('Separate tags with spaces.')
.setStyle('PARAGRAPH')
.setRequired()
modal.addComponents(
new MessageActionRow()
.addComponents(tagList),
)
await ctx.interaction.showModal(modal)
},
})
const { defineMessageCommand } = require('chooksie')
const { MessageActionRow, Modal, TextInputComponent } = require('discord.js')
module.exports = defineMessageCommand({
name: 'Tag Image',
async execute(ctx) {
const modal = new Modal()
// IMPORTANT: this must match the handler's customId
.setCustomId('tag-image')
.setTitle('Create a new Tag')
const tagList = new TextInputComponent()
.setCustomId('tag-list')
.setLabel('Tags')
.setPlaceholder('Separate tags with spaces.')
.setStyle('PARAGRAPH')
.setRequired()
modal.addComponents(
new MessageActionRow()
.addComponents(tagList),
)
await ctx.interaction.showModal(modal)
},
})
Handling Modal Submits
import { defineModalHandler } from 'chooksie'
export default defineModalHandler({
customId: 'tag-image',
setup: () => import('../db'),
async execute(ctx) {
const messageId = ctx.interaction.message.id
// IMPORTANT: this must match the text input's customId
const tagList = ctx.interaction.fields.getTextInputValue('tag-list')
await ctx.interaction.deferReply({
ephemeral: true,
})
await this.db.tags.save({
id: messageId,
tags: tagList.split(/ +/g),
})
await ctx.interaction.editReply('Image tagged!')
},
})
import { defineModalHandler } from 'chooksie'
export default defineModalHandler({
customId: 'tag-image',
setup: () => import('../db'),
async execute(ctx) {
const messageId = ctx.interaction.message.id
// IMPORTANT: this must match the text input's customId
const tagList = ctx.interaction.fields.getTextInputValue('tag-list')
await ctx.interaction.deferReply({
ephemeral: true,
})
await this.db.tags.save({
id: messageId,
tags: tagList.split(/ +/g),
})
await ctx.interaction.editReply('Image tagged!')
},
})
const { defineModalHandler } = require('chooksie')
module.exports = defineModalHandler({
customId: 'tag-image',
setup: () => import('../db'),
async execute(ctx) {
const messageId = ctx.interaction.message.id
// IMPORTANT: this must match the text input's customId
const tagList = ctx.interaction.fields.getTextInputValue('tag-list')
await ctx.interaction.deferReply({
ephemeral: true,
})
await this.db.tags.save({
id: messageId,
tags: tagList.split(/ +/g),
})
await ctx.interaction.editReply('Image tagged!')
},
})