---
title: "Interactive examples of custom dialogs"
description: "Interactive examples of custom dialogs for TinyMCE."
canonical_url: "https://www.tiny.cloud/docs/tinymce/latest/dialog-examples/"
md_url: "https://www.tiny.cloud/docs/tinymce/6/dialog-examples/index.md"
version: "6"
last_updated: "2022-03-31T00:32:33Z"
tokens: 2045
---
Important This page documents TinyMCE 6. For new projects, Tiny recommends using the latest, most up-to-date version. [See TinyMCE 8 documentation](../../latest/dialog-examples/).
# Interactive examples of custom dialogs

## Basic interactive dialog

The following example demonstrates how data flows through the dialog and how buttons are configured. This is an interactive dialog that inserts the name of a cat into the editor content on submit.

**Example**

```js
/* example dialog that inserts the name of a Pet into the editor content */
const dialogConfig =  {
  title: 'Pet Name Machine',
  body: {
    type: 'panel',
    items: [
      {
        type: 'input',
        name: 'catdata',
        label: 'enter the name of a cat'
      },
      {
        type: 'checkbox',
        name: 'isdog',
        label: 'tick if cat is actually a dog'
      }
    ]
  },
  buttons: [
    {
      type: 'cancel',
      name: 'closeButton',
      text: 'Cancel'
    },
    {
      type: 'submit',
      name: 'submitButton',
      text: 'Do Cat Thing',
      buttonType: 'primary'
    }
  ],
  initialData: {
    catdata: 'initial Cat',
    isdog: false
  },
  onSubmit: (api) => {
    const data = api.getData();
    const pet = data.isdog ? 'dog' : 'cat';

    tinymce.activeEditor.execCommand('mceInsertContent', false, `<p>My ${pet}'s name is: <strong>${data.catdata}</strong></p>`);
    api.close();
  }
};

tinymce.init({
  selector: 'textarea#dialog-pet-machine',
  toolbar: 'dialog-example-btn',
  setup: (editor) => {
    editor.ui.registry.addButton('dialog-example-btn', {
      icon: 'code-sample',
      onAction: () => editor.windowManager.open(dialogConfig)
    })
  },
  content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
});
```
The dialog in this example contains two interactive components - an input component named `catdata` and a checkbox component named `isdog`. These names are used in the `initialdata` configuration property to set the initial values for these components. In this case, when the dialog loads the input will contain the text *initial Cat* and the checkbox will not be checked.

The dialog also contains two footer buttons - a **submit** type button and a **cancel** type button. Since the dialog’s configuration does not contain an `onCancel` callback, clicking the cancel type button will just close the dialog. However, the configuration does contain an `onSubmit` callback that will be fired when the submit type button is clicked.

In the `onSubmit` callback, the dialog instance API that is passed into the callback is used to call `getData()`. This function returns the dialog’s data store, from which we are able to get the state of the `isdog` checkbox and the value of the `catadata` input. This information is used to construct a sentence which is then inserted into the editor. Finally, `close()` is called to manually close the dialog.

## Interactive example using Redial

Redial can be used to change information that is displayed in the dialog, create a multipage form where the next button loads a new form page, or to re-create the dialog with different components or options.

The following example demonstrates one way of implementing a multipage form dialog using the `redial()` method. Custom buttons are used to switch between the two pages of the form by calling `redial()` with the appropriate dialog configuration.

To see the output of the code, click on the TinyMCE tab on the fiddle below.

**Example**

```js
const page1Config = {
  title: 'Redial Demo',
  body: {
    type: 'panel',
    items: [{
      type: 'htmlpanel',
      html: '<p>Redial allows for the contents of a dialog to be replaced with new contents. This can be used to create multipage form dialogs.</p><br/><p>The Next button is initially disabled. When the <strong>checkbox</strong> is checked, the Next button should be enabled.</p>'
    }, {
      type: 'checkbox',
      name: 'anyterms',
      label: 'I agree to disagree'
    }, {
      type: 'htmlpanel',
      html: '<p>Pressing the Next button will call redial() to reload the dialog with the next page of the form.</p><br><p>Press Next to continue.</p>'
    }]
  },
  initialData: {
    anyterms: false
  },
  buttons: [
    {
      type: 'custom',
      name: 'doesnothing',
      text: 'Previous',
      enabled: false
    },
    {
      type: 'custom',
      name: 'uniquename',
      text: 'Next',
      enabled: false
    }
  ],
  onChange: (dialogApi, details) => {
    const data = dialogApi.getData();
    /* Example of enabling and disabling a button, based on the checkbox state. */
    dialogApi.setEnabled('uniquename', data.anyterms);
  },
  onAction: (dialogApi, details) => {
    if (details.name === 'uniquename') {
      dialogApi.redial(page2Config);
    } else if (details.name === 'doesnothing') {
      /* this case should never be met as the button is never enabled. */
    }
  }
};

const page2Config = {
  title: 'Redial Demo - Page 2',
  body: {
    type: 'panel',
    items: [
      {
        type: 'selectbox',
        name: 'choosydata',
        label: 'Choose a pet',
        items: [
          { value: 'meow', text: 'Cat' },
          { value: 'woof', text: 'Dog' },
          { value: 'thunk', text: 'Rock' }
        ]
      },
      {
        type: 'htmlpanel',
        html: '<p>Click done and the dialog will log a message to the console, insert a sentence into the editor and close.</p>'
      }
    ]
  },
  buttons: [
    {
      type: 'custom',
      name: 'lastpage',
      text: 'Done',
      enabled: true
    }
  ],
  initialData: {
    choosydata: ''
  },
  onAction: (dialogApi, details) => {
    const data = dialogApi.getData();

    const result = 'You chose wisely: ' + data.choosydata;
    console.log(result);
    tinymce.activeEditor.execCommand('mceInsertContent', false, `<p>${result}</p>`);

    dialogApi.close();
  }
};

tinymce.init({
  selector: 'textarea#redial-demo',
  toolbar: 'wizardExample',
  height: '900px',
  setup: (editor) => {
    editor.ui.registry.addButton('wizardExample', {
      icon: 'code-sample',
      onAction: () => editor.windowManager.open(page1Config)
    })
  },
  content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
});
```
The example JavaScript code contains two dialog configurations - `page1Config` and `page2Config`. The TinyMCE initialization code adds a button to the editor that when clicked calls `editor.windowManager.open(page1Config)` to open a dialog using the first configuration.

The configuration for the first page of the multipage form contains a description of the form and a checkbox. The checkbox, via the dialog’s `onChange()` callback function, toggles whether the `next` button is disabled or enabled. The `next` button when clicked fires the `onAction()` callback function, which in turn triggers `redial()` which will replace the `page1Config` dialog with the `page2Config` dialog.

More specifically:

The `onChange()` callback in `page1Config` is fired when the checkbox is toggled. It uses `setEnabled` from the dialog instance API to disable and enable the **Next** button. The code uses `getData()` from the dialog instance API to get the state of the checkbox called `anyterms` (which is `true` if checked and `false` if unchecked) and then calls the `setEnabled` function with the component name `uniquename` and checkbox value to set the enabled state of the **Next** button.

The `onAction()` callback in `page1Config` is fired when either of the footer buttons are clicked, since they are both custom type footer buttons. `onAction()` is passed the dialog instance API and an object containing some data about the change event, including the `name` of the component that triggered it. This is important since the same `onAction()` handler is shared across all compatible dialog components. The code checks the `name` of the component that triggered `onAction()` and if it is `uniquename` (the name of the **Next** button) `redial(page2Config)` is called. If the component’s `name` is `donothing` then the code does nothing.

In `page2Config` the `onAction()` callback uses `getData()` to get the value of the `selectbox` component, and specifically whether the user has chosen *Cat*, *Dog* or *Rock*. It then constructs a sentence using this value, inserts it into the editor content and calls `close()` to manually close the dialog.
