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.JSopen in new window and only the latter is handled by the framework, reason being much like Embedsopen in new window, 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!')
  },
})