diff --git a/website/docs/Interaction_Guidelines/ux_controls_ui_patterns.md b/website/docs/Interaction_Guidelines/ux_controls_ui_patterns.md
index 7d0daaf6..ea0e3042 100644
--- a/website/docs/Interaction_Guidelines/ux_controls_ui_patterns.md
+++ b/website/docs/Interaction_Guidelines/ux_controls_ui_patterns.md
@@ -191,7 +191,7 @@ Dropdown controls allow multiple options to be expanded from a menu. Dropdowns h
| --- | --- |
| **Outline** | The outline style is the primary variation that should be used. It can be used by itself, on forms, or within dialogues. |
| **Line** (label optional) | Line style dropdowns are useful in areas that have cramped vertical space. This dropdown style can be stacked within panels to avoid a boxy wireframe feel. While the label is optional, we encourage using it to better inform users about the category of items. |
-| **Text** | This style allows the user to access options from a dropdown or flyout menu. This style works well in tool and start bars, as well as in dialogs and menus. |
+| **Text** | This style allows the user to access options from a dropdown or flyout menu. This style works well in tool and start bars, as well as in dialogs and menus. |
| **Icon** | The icon style works best in small regions such as tool bars, and is great for switches that have several options. |
diff --git a/website/docs/core/trex_configure.md b/website/docs/core/trex_configure.md
index 2a150033..e29b9c68 100644
--- a/website/docs/core/trex_configure.md
+++ b/website/docs/core/trex_configure.md
@@ -1,16 +1,21 @@
---
-title: Add a Configuration Popup Dialog
+title: Add a Configuration Popup Dialog Box
description: How to add a configuration dialog box to the extension
---
-If you want users to be able to configure settings for your extension, you can use an optional callback function when you initialize your dashboard or viz extension. The callback function creates a configuration option that can be used to open a popup window (a modal dialog box) for your extension. You can use this popup window to allow users to set and save settings for the extension.
+If you want users to be able to configure settings for your extension, you can use an optional callback function when you initialize your dashboard or viz extension. The callback function creates a configuration option that can be used to open a popup window (dialog box) for your extension. The Extensions API supports different dialog box styles: modal, modeless, or window. You can use the dialog box to allow users to set and save settings for the extension. Starting with Tableau 2026.1 (and the v1.16 library), you can create multiple dialog boxes and send messages between them.
+:::info
+
+By design, there can be only one context configuration popup window or dialog box. For information about creating and using multiple pop dialog boxes or window, see [Add a Multiple Popup Dialog Boxes](trex_multiple_dialogs.md).
+
+:::
## Add the context menu to the `.trex` file
-The first step is to add the `` option to the extension's manifest file (`.trex`). The `` element only contains one item: ``.
+The first step is to add the `` option to the extension's manifest file (`.trex`). The `` element only contains one item: ``.
-* The context menu option must follow the `` and `` elements in the manifest file in the `` or `` section:
+* The context menu option must follow the `` and `` elements in the manifest file in the `` or `` section:
```xml
+
+
+```
+
+JavaScript code (uiNamespace.js)
+
+```javascript
+
+// in uiNamespace.js, a button click calls openColorDialog
+
+ $('#openColorDialog').click(openColorDialog);
+
+```
+
+In the main extension file, `uiNamespace.js`, add code to set the default background color and then call the `displayDialogAsync()` method. To see the entire listing, see [Complete example source code](#complete-example-source-code) and select the **uiNamespace** tab.
+
+```javascript
+
+/**
+* uiNamespace.js (main extension file)
+* Sets the default background color
+* Passes the current color to the dialog as the initial payload
+*/
+
+const defaultBgColor = '#FFFFFF';
+let currentBgColor = defaultBgColor;
+
+
+```
+
+The `openColorDialog()` method calls `tableau.extensions.ui.displayDialogAsync()` method, and passes values for the popup window, including the URL, the initial payload, dimensions, and the `DialogStyle`. The `DialogStyle` determines how the popup window interacts with the extension and other elements.
+
+| `DialogStyle` value | Behavior |
+|---|---|
+| `tableau.DialogStyle.Modal` | Blocks all other windows; users must close this dialog before interacting with the extension. |
+| `tableau.DialogStyle.Modeless` | Doesn't block other windows; focus follows user interaction. |
+| `tableau.DialogStyle.Window` | Opens as a separate browser-style window; behavior depends on the browser. |
+
+In this code snippet, the dialog style is set to modeless. The complete example extends this to allow the user to choose the dialog style. See [Complete example source code](#complete-example-source-code) and select the **uiNamespace** tab
+
+```javascript
+
+/** uiNamespace.js
+* Defines and displays the dialog box
+* Opens the background color picker dialog ( in this case, modeless).
+* Passes the current background color as the initial payload so the dialog
+* can pre-select it. The closePayload returned is the chosen hex color,
+* which is then applied to the extension body.
+*
+*/
+
+function openColorDialog () {
+ const popupUrl = new URL('uiNamespaceColorDialog.html', window.location.href).href;
+
+ let dialogStyle = tableau.DialogStyle.Modeless;
+
+ tableau.extensions.ui
+ .displayDialogAsync(popupUrl, currentBgColor, { height: 500, width: 360, dialogStyle: dialogStyle})
+ .then((closePayload) => {
+ currentBgColor = closePayload;
+ $('body').css('background-color', currentBgColor);
+ })
+ .catch((error) => {
+ if (error.errorCode === tableau.ErrorCodes.DialogClosedByUser) {
+ console.log('Color dialog was closed by user');
+ } else {
+ console.error(error.message);
+ }
+ });
+}
+
+```
+
+JavaScript code (uiNameSpaceColorDialog.js)
+
+In the `uiNameSpaceColorDialog.js` file, add the `initializeDialogAsync()` method. The method processes the initial payload, in this case the current background color. If the user selects a color, that color is returned as the payload in the `closeDialog()` method. The `buildColorList()` and `updatePreview()` methods aren't shown here, but you can see the [Complete example source code](#complete-example-source-code). Those methods let users pick from the colors in a list and then see that color in a preview `div`.
+
+When the user clicks the **Save** button, the `sendToParent()` method is called. The `sendToParent()` method is defined in the `uiNameSpaceColorDialog.js` file, and is described under [Send the message to the parent extension or popup window](#send-the-message-to-the-parent-extension-or-popup-window). For information about messaging between windows, see [Send messages to and from the popup window or dialog box](#send-messages-to-and-from-the-popup-window-or-dialog-box).
+
+```javascript
+
+// uiNameSpaceColorDialog.js
+
+$(document).ready(function () {
+ tableau.extensions.initializeDialogAsync().then(function (openPayload) {
+ // openPayload is the current background color passed from the parent.
+ if (openPayload && openPayload.startsWith('#')) {
+ selectedColor = openPayload;
+ }
+
+ buildColorList();
+ updatePreview(selectedColor);
+
+ $('#saveButton').click(function () {
+ sendToParent('Hello from Dialog box! - Save button clicked');
+ tableau.extensions.ui.closeDialog(selectedColor);
+ });
+ });
+});
+
+
+```
+
+---
+
+## Send messages between popup dialog boxes and the extension
+
+Starting with Tableau 2026.1, the Extensions API provides two methods for sending messages between dialog boxes and between the dialog box and the calling extension or popup window. The messages provide a way of passing information between the popup windows. The messaging is in addition to the optional payload that is returned from the `displayDialogAsync()` method. When the popup window calls the `closeDialog()` method, the `displayDialogAsync()` method returns the payload. The `sendDialogMessageAsync()` and `sendDialogMessageToParentAsync()` methods provide another way to communicate between popup windows and the main extension window.
+
+### Add the message received event listener
+
+To enable messaging between the popup windows, you must add an event listener for the `DialogMessageReceived` event. For two-way communication between popup windows and the extension, add the event listener in the code for both the popup window and the extension.
+
+For example, the following code snippet shows how a popup window could add the event listener for messages sent from the extension. These are the messages that the extension sends using the `sendDialogMessageAsync()` method. This example logs the message to the console window, and is viewable if you use the debugging tools on the popup window.
+
+Popup window or dialog box code:
+
+```javascript
+
+ tableau.extensions.ui.addEventListener(tableau.TableauEventType.DialogMessageReceived, (event) =>{
+ console.log(`Message received: ${event.message}`);
+ });
+
+```
+
+Extension code:
+
+In the extension, add an event listener for messages that get sent from the popup window. In this case, the code snippet appends the message from the popup window to the `messageLog` text block in the extension interface.
+
+```javascript
+ // Listen for messages from dialogs sent by sendDialogMessageToParentAsync)
+ tableau.extensions.ui.addEventListener(tableau.TableauEventType.DialogMessageReceived, function (event) {
+ const p = $('').text(event.message);
+ $('#messageLog').append(p);
+ });
+
+```
+
+### Send the message to the parent extension or popup window
+
+The popup windows can use the `sendDialogMessageToParentAsync()` method to send a message to the extension or the popup window that opened it (that is, the "parent" of the popup dialog).
+
+The `sendDialogMessageToParentAsync()` method takes just one argument, the message to send (a string value). The method only works if it’s called from the popup window.
+
+For example, the following code snippets show how you might tie the send message method to a button in the popup window. In this case, there’s a **Save** button (`saveButton`). When the user clicks the **Save** button, a message gets sent to the extension. The `closeDialog()` method is also called when the user clicks the **Save** button, which closes the popup window and then returns the payload to the extension. We wrap the `sendDialogMessageToParentAsync()` method in another function with the `await` keyword, so that the message is guaranteed to be sent before the dialog box is closed.
+
+The parent extension's event handler function for the `DialogMessageReceived` event processes the message.
+
+```javascript
+
+ // ...
+
+ $('#saveButton').click(function () {
+ sendToParent('Hello from Dialog box! - Save button clicked');
+ tableau.extensions.ui.closeDialog(selectedColor);
+ });
+
+ // ...
+ // send message method is placed in a wrapper function to guarantee
+ // that the message is sent before the dialog is closed
+ async function sendToParent(message) {
+ await tableau.extensions.ui.sendDialogMessageToParentAsync(message);
+ }
+
+```
+
+### Send messages to and from the popup window or dialog box
+
+The extension can use the `sendDialogMessageAsync()` method to send a message to the popup window or dialog box. The method takes two arguments, the message (string) and the optional target URL (`targetDialogUrl`).
+
+The `sendDialogMessageAsync()` method can also be used to send messages to the extension from the popup window or dialog box. You might do this if the dialog box was opened by another dialog box (the "parent"), and not by the extension. However, in most cases, to send a message to the extension or to the dialog box that opened the dialog box sending the message (the "parent"), use the `sendDialogMessageToParentAsync()` method.
+
+If you are using the `sendDialogMessageAsync()` method to send a message to the extension from the popup window or dialog box, you can omit the target URL. When the target URL isn't specified, the message gets sent to the extension.
+
+For example, in the following code snippet, a button in the extension code is tied to a `sendToColorDialog` method. To be able to click the button to send a message, the colorDialog can't have the focus, so the popup dialog box must be modeless.
+
+```javascript
+
+
+ // Assumes the extension HTML code specifies a button
+ // with the id 'sendToColorDialog'
+ $('#sendToColorDialog').click(sendToColorDialog);
+
+ // ...
+
+ // sends message to the popup window
+ function sendToColorDialog() {
+ let colorDialogUrl = new URL('uiNamespaceColorDialog.html', window.location.href).href;
+ tableau.extensions.ui.sendDialogMessageAsync('Hello from extension!', colorDialogUrl);
+ }
+
+```
+
+---
+
+## Track the active popup dialog box
+
+Depending upon your implementation, and whether your dialog boxes are modal or not, if you have multiple popup dialog boxes you will likely need to track which popup is active. At a minimum, you'll want to prevent errors that result if a user tries to open a dialog box that is already open. This can be done with a simple mapping variable. In this case, we declare a set of objects called `openDialog`. The popup dialog boxes can then be added or deleted from the list, depending upon whether they are opened or closed.
+
+```javascript
+
+ // Track which dialogs are currently open
+ const openDialogs = new Set();
+
+```
+
+### Add the opened popup window to the list
+
+In your JavaScript code that calls the `displayDialogAsync()` method, check if the popup dialog box is currently open. If it is, return without calling the `displayDialogAsync()` method. If it is not open, add the URL to the list and continue.
+
+```javascript
+
+ // code excerpt from openColorDialog() method
+
+ const popupUrl = new URL('uiNamespaceColorDialog.html', window.location.href).href;
+
+ if (openDialogs.has(popupUrl)) {
+ return; // Dialog is already open; don't open a second instance
+ }
+
+ openDialogs.add(popupUrl);
+
+```
+
+### Remove the closed popup window from the list
+
+In your function that handles the promise returned from the `displayDialogAsync()` method, remove the popup URL from the set of open dialog boxes, using the `delete()` method (`openDialogs.delete(popupUrl)`). Be sure to delete the popup dialog method in your error handling code. In the case of errors, where the dialog box isn't closed properly, for example, the Extensions API `closeDialog()` method isn't called, the dialog box is no longer open and needs to be removed from the list.
+
+```javascript
+
+ tableau.extensions.ui
+ .displayDialogAsync(popupUrl, currentBgColor, { height: 500, width: 360, dialogStyle: dialogStyle })
+ .then((closePayload) => {
+ openDialogs.delete(popupUrl);
+ currentBgColor = closePayload;
+ $('body').css('background-color', currentBgColor);
+ })
+ .catch((error) => {
+ openDialogs.delete(popupUrl);
+ if (error.errorCode === tableau.ErrorCodes.DialogClosedByUser) {
+ console.log('Color dialog was closed by user');
+ } else {
+ console.error(error.message);
+ }
+ });
+
+
+```
+
+
+---
+
+## Complete example source code
+
+This example code adds a second dialog box to the uiNamespace sample. The second popup dialog lets users change the background color of the extension window. The sample also shows how you can use the messaging methods to communicate between the popup dialog boxes and the extension. A simple mapping object is used to track the state of the second popup dialog box.
+
+Click the name of the module to see the HTML and JavaScript code.
+
+---
+
+```mdx-code-block
+
+
+
+```
+
+* [HTML](#uinamespacehtml)
+* [JavaScript](#uinamespacejs)
+* [.trex](#uinamespacetrex)
+
+#### uiNamespace.html
+
+```html
+
+
+
+
+
+
+
+ Settings Sample
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Refreshing 0 datasource(s) every 5 minutes.
+
+
+ Configure extension to proceed.
+
+
+
+
Dialog Style
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Messages from dialogs
+
+
+
+
+
+
+
+
+```
+
+#### uiNamespace.js
+
+```javascript
+
+
+'use strict';
+
+/**
+ * UINamespace Sample Extension
+ *
+ * This sample extension demonstrates how to use the UI namespace
+ * to create a popup dialog with additional UI that the user can interact with.
+ * The content in this dialog is actually an extension as well (see the
+ * uiNamespaceDialog.js for details).
+ *
+ * This sample is an extension that auto refreshes datasources in the background of
+ * a dashboard. The extension has little need to take up much dashboard space, except
+ * when the user needs to adjust settings, so the UI namespace is used for that.
+ */
+
+// Wrap everything in an anonymous function to avoid polluting the global namespace
+(function () {
+ const defaultIntervalInMin = '5';
+ const defaultBgColor = '#FFFFFF';
+ let activeDatasourceIdList = [];
+ let currentBgColor = defaultBgColor;
+
+ // Track which dialogs are currently open
+ const openDialogs = new Set();
+
+ $(document).ready(function () {
+ // When initializing an extension, an optional object is passed that maps a special ID (which
+ // must be 'configure') to a function. This, in conjunction with adding the correct context menu
+ // item to the manifest, will add a new "Configure..." context menu item to the zone of extension
+ // inside a dashboard. When that context menu item is clicked by the user, the function passed
+ // here will be executed.
+ tableau.extensions.initializeAsync({ configure: configure }).then(function () {
+ // This event allows for the parent extension and popup extension to keep their
+ // settings in sync. This event will be triggered any time a setting is
+ // changed for this extension, in the parent or popup (i.e. when settings.saveAsync is called).
+ tableau.extensions.settings.addEventListener(tableau.TableauEventType.SettingsChanged, (settingsEvent) => {
+ updateExtensionBasedOnSettings(settingsEvent.newSettings);
+ });
+
+ // Listen for messages from dialogs (for example, the background color dialog box via sendDialogMessageToParentAsync)
+ tableau.extensions.ui.addEventListener(tableau.TableauEventType.DialogMessageReceived, function (event) {
+ const p = $('').text(event.message);
+ $('#messageLog').append(p);
+ });
+
+ $('#openColorDialog').click(openColorDialog);
+ $('#sendToColorDialog').click(sendToColorDialog);
+ $('#sendToColorDialog').prop('disabled', true);
+ });
+ });
+
+ function configure () {
+ // This uses the window.location.origin property to retrieve the scheme, hostname, and
+ // port where the parent extension is currently running, so this string doesn't have
+ // to be updated if the extension is deployed to a new location.
+ const popupUrl = `${window.location.origin}/uiNamespaceDialog.html`;
+
+
+ // This checks for the selected dialog style in the radio form.
+ let dialogStyle;
+ const dialogStyleOptions = document.getElementsByName('dialogStyleRadio');
+ if (dialogStyleOptions[0].checked) {
+ dialogStyle = tableau.DialogStyle.Modal;
+ } else if (dialogStyleOptions[1].checked) {
+ dialogStyle = tableau.DialogStyle.Modeless;
+ } else {
+ dialogStyle = tableau.DialogStyle.Window;
+ }
+
+ /**
+ * This is the API call that actually displays the popup extension to the user.
+ * The only required parameter is the URL of the popup,
+ * which must be the same domain, port, and scheme as the parent extension.
+ * The dialog style (modal, modeless, or window) is selected by the user.
+ *
+ * The developer can optionally control the initial size of the extension by passing in
+ * an object with height and width properties. The developer can also pass a string as the
+ * 'initial' payload to the popup extension. This payload is made available immediately to
+ * the popup extension. In this example, the value '5' is passed, which will serve as the
+ * default interval of refresh.
+ */
+ tableau.extensions.ui
+ .displayDialogAsync(popupUrl, defaultIntervalInMin, { height: 500, width: 500, dialogStyle })
+ .then((closePayload) => {
+ // The promise is resolved when the dialog has been expectedly closed, meaning that
+ // the popup extension has called tableau.extensions.ui.closeDialog.
+ $('#inactive').hide();
+ $('#active').show();
+
+ // The close payload is returned from the popup extension via the closeDialog method.
+ $('#interval').text(closePayload);
+ setupRefreshInterval(closePayload);
+ })
+ .catch((error) => {
+ // One expected error condition is when the popup is closed by the user (meaning the user
+ // clicks the 'X' in the top right of the dialog). This can be checked for like so:
+ switch (error.errorCode) {
+ case tableau.ErrorCodes.DialogClosedByUser:
+ console.log('Dialog was closed by user');
+ break;
+ default:
+ console.error(error.message);
+ }
+ });
+ }
+
+ /**
+ * This function sets up a JavaScript interval based on the time interval selected
+ * by the user. This interval will refresh all selected datasources.
+ */
+ function setupRefreshInterval (interval) {
+ setInterval(function () {
+ const dashboard = tableau.extensions.dashboardContent.dashboard;
+ dashboard.worksheets.forEach(function (worksheet) {
+ worksheet.getDataSourcesAsync().then(function (datasources) {
+ datasources.forEach(function (datasource) {
+ if (activeDatasourceIdList.indexOf(datasource.id) >= 0) {
+ datasource.refreshAsync();
+ }
+ });
+ });
+ });
+ }, interval * 60 * 1000);
+ }
+
+
+
+ /**
+ * Opens the background color picker dialog.
+ * Passes the current background color as the initial payload so the dialog
+ * can pre-select it. The closePayload returned is the chosen hex color,
+ * which is then applied to the extension body.
+ */
+ function openColorDialog () {
+
+ const popupUrl = new URL('uiNamespaceColorDialog.html', window.location.href).href;
+
+ if (openDialogs.has(popupUrl)) {
+ return; // Dialog is already open; don't open a second instance
+ }
+
+ openDialogs.add(popupUrl);
+
+ // This checks for the selected dialog style in the radio form.
+ // To send messages to the colorDialog, the colorDialog must be modeless.
+ let dialogStyle;
+ const dialogStyleOptions = document.getElementsByName('dialogStyleRadio');
+ if (dialogStyleOptions[0].checked) {
+ dialogStyle = tableau.DialogStyle.Modal;
+ } else if (dialogStyleOptions[1].checked) {
+ dialogStyle = tableau.DialogStyle.Modeless;
+ } else {
+ dialogStyle = tableau.DialogStyle.Window;
+ }
+
+ $('#sendToColorDialog').prop('disabled', false);
+
+ tableau.extensions.ui
+ .displayDialogAsync(popupUrl, currentBgColor, { height: 500, width: 360, dialogStyle: dialogStyle })
+ .then((closePayload) => {
+ openDialogs.delete(popupUrl);
+ $('#sendToColorDialog').prop('disabled', true);
+ currentBgColor = closePayload;
+ $('body').css('background-color', currentBgColor);
+ })
+ .catch((error) => {
+ openDialogs.delete(popupUrl);
+ $('#sendToColorDialog').prop('disabled', true);
+ if (error.errorCode === tableau.ErrorCodes.DialogClosedByUser) {
+ console.log('Color dialog was closed by user');
+ } else {
+ console.error(error.message);
+ }
+ });
+ }
+
+ async function sendToColorDialog() {
+ let colorDialogUrl = new URL('uiNamespaceColorDialog.html', window.location.href).href;
+ await tableau.extensions.ui.sendDialogMessageAsync(`Hello from the extension! ${new Date().toLocaleTimeString()}`, colorDialogUrl);
+ }
+
+
+
+ /**
+ * Helper that is called to set state anytime the settings are changed.
+ */
+ function updateExtensionBasedOnSettings (settings) {
+ if (settings.selectedDatasources) {
+ activeDatasourceIdList = JSON.parse(settings.selectedDatasources);
+ $('#datasourceCount').text(activeDatasourceIdList.length);
+ }
+ }
+})();
+
+
+```
+
+
+#### uiNamespace.trex
+
+This example and `.trex` is for a dashboard extension, however the same principals apply to viz extensions.
+If you use this code, replace the `` with the location of where you are hosting your extension.
+The `` is required for the configuration context menu or the Format Extension button (for viz extensions). For additional popup windows or dialog boxes, no other changes are required to the `.trex` file.
+
+```xml
+
+
+
+
+ en_US
+
+ UI Namespace Sample
+
+ 1.10
+
+ http://localhost:8765/uinamespace.html
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAlhJREFUOI2Nkt9vy1EYh5/3bbsvRSySCZbIxI+ZCKsN2TKtSFyIrV2WuRCJuBiJWxfuxCVXbvwFgiEtposgLFJElnbU1SxIZIIRJDKTrdu+53Uhra4mce7Oe57Pcz7JOULFisViwZ+29LAzOSjQYDgz1ZcCvWuXV11MJpN+OS/lm6179teqH0yDqxPTCyKSA8DcDsyOmOprnCaeP7459pdgy969i0LTC3IO/RQMyoHcQN+3cnljW3dNIFC47qDaK3g7BwdTkwBaBELT4ZPOUVWgKl4ZBnjxJPUlMDnTDrp0pmr6RHFeEjjcUUXPDGeSEwDN0Xg8sivxMhJNjGzbHd8PkM3eHRfkrBM5NkcQaY2vUnTlrDIA0NoaX+KLXFFlowr14tvVpqb2MICzmQcKqxvbumv+NAhZGCCIPwEw6QWXKYRL/VUXO0+rAUJiPwAk5MIlgVfwPjjHLCL1APmHN94ZdqeYN+NW/mn6I4BvwQYchcLnwFhJMDiYmlRxAzjpKWZkYkUCcZ2I61wi37tLbYyjiN0fHk5Oz3nGSLSzBbNHCF35R7f6K1/hN9PRhek11FrymfQQQKB4+Gl05P2qNRtmETlXW7e+b2z01dfycGNbfFMAbqNyKp9Jp4rzOT8RYFs0njJkc2iqsCObvTsOsDWWqA5C1uFy+Uz/oXJeKwVT4h0RmPUXhi79vuC0Ku6yOffTK3g9lfxfDQAisY516sg5kfOCiJk7HoLt2cf9b/9LANAc7dznm98PagG1fUOZ9IP5uMB8Q4CPoyNvausapkTt3rNMuvdf3C/o6+czhtdwmwAAAABJRU5ErkJggg==
+
+
+
+
+
+
+ UI Namespace Sample
+
+
+
+
+
+
+```
+
+
+
+
+
+```mdx-code-block
+
+
+```
+
+* [HTML](#uinamespacecolordialoghtml)
+* [JavaScript](#uinamespacecolordialogjs)
+
+
+#### uiNamespaceColorDialog.html
+
+```html
+
+
+
+
+
+
+
+
+ Background Color
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Background Color
+
Select a background color for the extension window.
+
+
+
Preview:
+
+
+
Tableau 10 Colors + Neutrals:
+
+
+
+
+
+
+
Messages from the extension
+
+
+
+
+
+
+
+
+
+```
+
+#### uiNamespaceColorDialog.js
+
+
+```javascript
+
+'use strict';
+
+/**
+ * Background Color Picker Dialog
+ *
+ * This dialog lets the user pick a background color for the parent extension
+ * window from the Tableau 10 color palette plus two neutrals (12 total).
+ *
+ * Flow:
+ * - initializeDialogAsync receives the current background color as openPayload.
+ * - The matching color is pre-selected in the dropdown.
+ * - Clicking Save calls closeDialog with the chosen hex value as the closePayload.
+ * - The parent extension applies the color to its body background.
+ */
+
+(function () {
+ // The 10 canonical Tableau 10 colors plus White and Light Gray (12 total).
+ const TABLEAU_COLORS = [
+ { name: 'Blue', hex: '#4E79A7' },
+ { name: 'Orange', hex: '#F28E2B' },
+ { name: 'Red', hex: '#E15759' },
+ { name: 'Teal', hex: '#76B7B2' },
+ { name: 'Green', hex: '#59A14F' },
+ { name: 'Yellow', hex: '#EDC948' },
+ { name: 'Purple', hex: '#B07AA1' },
+ { name: 'Pink', hex: '#FF9DA7' },
+ { name: 'Brown', hex: '#9C755F' },
+ { name: 'Gray', hex: '#BAB0AC' },
+ { name: 'White', hex: '#FFFFFF' },
+ { name: 'Light Gray', hex: '#F0F0F0' },
+ ];
+
+ let selectedColor = TABLEAU_COLORS[10].hex; // default: White
+
+ $(document).ready(function () {
+
+
+
+ tableau.extensions.initializeDialogAsync().then(function (openPayload) {
+ // openPayload is the current background color passed from the parent.
+ if (openPayload && openPayload.startsWith('#')) {
+ selectedColor = openPayload;
+ }
+
+ buildColorDropdown();
+ updatePreview(selectedColor);
+
+ tableau.extensions.ui.addEventListener(tableau.TableauEventType.DialogMessageReceived, (event) =>{
+ console.log(`Message received: ${event.message}`);
+ const p = $('').text(event.message);
+ $('#messageLog').append(p);
+ });
+
+ $('#saveButton').click(function () {
+ sendToParent(`Message From the Color Dialog at ${new Date().toLocaleTimeString()}`);
+ tableau.extensions.ui.closeDialog(selectedColor);
+ });
+ });
+ });
+
+ /**
+ * Builds swatch + name + hex for one color (shared by trigger label and menu items).
+ */
+ function buildColorRowContent ($container, color) {
+ $('', {
+ class: 'color-swatch',
+ css: { backgroundColor: color.hex }
+ }).appendTo($container);
+ $('', { class: 'color-name', text: color.name }).appendTo($container);
+ $('', { class: 'color-hex', text: color.hex }).appendTo($container);
+ }
+
+ /**
+ * Updates the dropdown button to show the current selection.
+ */
+ function updateDropdownLabel (color) {
+ const $label = $('#colorDropdownLabel');
+ $label.empty();
+ buildColorRowContent($label, color);
+ }
+
+ /**
+ * Builds the Bootstrap dropdown menu and attaches selection handlers.
+ */
+ function buildColorDropdown () {
+ const $menu = $('#colorDropdownMenu');
+ $menu.empty();
+
+ let selectedMeta = TABLEAU_COLORS.find(function (c) {
+ return c.hex.toUpperCase() === selectedColor.toUpperCase();
+ });
+ if (!selectedMeta) {
+ selectedMeta = { name: 'Custom', hex: selectedColor };
+ }
+ updateDropdownLabel(selectedMeta);
+
+ TABLEAU_COLORS.forEach(function (color) {
+ const isSelected = color.hex.toUpperCase() === selectedColor.toUpperCase();
+
+ const $li = $('', { role: 'presentation', class: isSelected ? 'active' : '' });
+ const $a = $('', {
+ href: '#',
+ class: 'color-dropdown-item',
+ role: 'menuitem',
+ tabindex: '-1'
+ });
+
+ buildColorRowContent($a, color);
+
+ $a.on('click', function (e) {
+ e.preventDefault();
+ selectedColor = color.hex;
+ $menu.find('li').removeClass('active');
+ $li.addClass('active');
+ updateDropdownLabel(color);
+ updatePreview(selectedColor);
+ $('#colorDropdownToggle').dropdown('toggle');
+ });
+
+ $li.append($a);
+ $menu.append($li);
+ });
+ }
+
+ /**
+ * Updates the preview box to reflect the currently selected color.
+ */
+ function updatePreview (hex) {
+ $('#colorPreview').css('background-color', hex);
+ }
+
+ async function sendToParent(message) {
+ await tableau.extensions.ui.sendDialogMessageToParentAsync(message);
+ }
+
+
+})();
+
+
+```
+
+```mdx-code-block
+
+
+```
+
+
+* [HTML](#uinamespacedialoghtml)
+* [JavaScript](#uinamespacedialogjs)
+
+
+
+#### uiNamespaceDialog.html
+
+
+
+```html
+
+
+
+
+
+
+
+ Settings Sample
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Auto Data Source Refresh Extension
+
+ This Extension refreshes the selected datasources at the selected interval.
+
+
+
+
Apply to these datasources:
+
+
+
Refresh interval in minutes:
+
+
+
+
+
+
+
+
+
+
+
+```
+
+#### uiNamespaceDialog.js
+
+
+```javascript
+
+'use strict';
+
+/**
+ * UINamespace Sample Extension
+ *
+ * This is the popup extension portion of the UINamespace sample, please see
+ * uiNamespace.js in addition to this for context. This extension is
+ * responsible for collecting configuration settings from the user and communicating
+ * that info back to the parent extension.
+ *
+ * This sample demonstrates two ways to do that:
+ * 1) The suggested and most common method is to store the information
+ * via the settings namespace. The parent can subscribe to notifications when
+ * the settings are updated, and collect the new info accordingly.
+ * 2) The popup extension can receive and send a string payload via the open
+ * and close payloads of initializeDialogAsync and closeDialog methods. This is useful
+ * for information that does not need to be persisted into settings.
+ */
+
+// Wrap everything in an anonymous function to avoid polluting the global namespace
+(function () {
+ /**
+ * This extension collects the IDs of each datasource the user is interested in
+ * and stores this information in settings when the popup is closed.
+ */
+ const datasourcesSettingsKey = 'selectedDatasources';
+ let selectedDatasources = [];
+
+ $(document).ready(function () {
+ // The only difference between an extension in a dashboard and an extension
+ // running in a popup is that the popup extension must use the method
+ // initializeDialogAsync instead of initializeAsync for initialization.
+ // This has no affect on the development of the extension but is used internally.
+ tableau.extensions.initializeDialogAsync().then(function (openPayload) {
+ // The openPayload sent from the parent extension in this sample is the
+ // default time interval for the refreshes. This could alternatively be stored
+ // in settings, but is used in this sample to demonstrate open and close payloads.
+ $('#interval').val(openPayload);
+ $('#closeButton').click(closeDialog);
+
+ const dashboard = tableau.extensions.dashboardContent.dashboard;
+ const visibleDatasources = [];
+ selectedDatasources = parseSettingsForActiveDataSources();
+
+ // Loop through datasources in this sheet and create a checkbox UI
+ // element for each one. The existing settings are used to
+ // determine whether a datasource is checked by default or not.
+ dashboard.worksheets.forEach(function (worksheet) {
+ worksheet.getDataSourcesAsync().then(function (datasources) {
+ datasources.forEach(function (datasource) {
+ const isActive = selectedDatasources.indexOf(datasource.id) >= 0;
+
+ if (visibleDatasources.indexOf(datasource.id) < 0) {
+ addDataSourceItemToUI(datasource, isActive);
+ visibleDatasources.push(datasource.id);
+ }
+ });
+ });
+ });
+ });
+ });
+
+ /**
+ * Helper that parses the settings from the settings namespace and
+ * returns a list of IDs of the datasources that were previously
+ * selected by the user.
+ */
+ function parseSettingsForActiveDataSources () {
+ let activeDatasourceIdList = [];
+ const settings = tableau.extensions.settings.getAll();
+ if (settings.selectedDatasources) {
+ activeDatasourceIdList = JSON.parse(settings.selectedDatasources);
+ }
+
+ return activeDatasourceIdList;
+ }
+
+ /**
+ * Helper that updates the internal storage of datasource IDs
+ * any time a datasource checkbox item is toggled.
+ */
+ function updateDatasourceList (id) {
+ const idIndex = selectedDatasources.indexOf(id);
+ if (idIndex < 0) {
+ selectedDatasources.push(id);
+ } else {
+ selectedDatasources.splice(idIndex, 1);
+ }
+ }
+
+ /**
+ * UI helper that adds a checkbox item to the UI for a datasource.
+ */
+ function addDataSourceItemToUI (datasource, isActive) {
+ const containerDiv = $('');
+
+ $('', {
+ type: 'checkbox',
+ id: datasource.id,
+ value: datasource.name,
+ checked: isActive,
+ click: function () {
+ updateDatasourceList(datasource.id);
+ }
+ }).appendTo(containerDiv);
+
+ $('', {
+ for: datasource.id,
+ text: datasource.name
+ }).appendTo(containerDiv);
+
+ $('#datasources').append(containerDiv);
+ }
+
+ /**
+ * Stores the selected datasource IDs in the extension settings,
+ * closes the dialog, and sends a payload back to the parent.
+ */
+ function closeDialog () {
+ tableau.extensions.settings.set(datasourcesSettingsKey, JSON.stringify(selectedDatasources));
+
+ tableau.extensions.settings.saveAsync().then((newSavedSettings) => {
+ tableau.extensions.ui.closeDialog($('#interval').val());
+ });
+ }
+})();
+
+
+
+```
+
+```mdx-code-block
+
+
+```
\ No newline at end of file
diff --git a/website/docs/dashext/trex_create.md b/website/docs/dashext/trex_create.md
index a0585e93..39469cd3 100644
--- a/website/docs/dashext/trex_create.md
+++ b/website/docs/dashext/trex_create.md
@@ -17,7 +17,7 @@ To create a Tableau extension you need the following components.
### What you need to get started
-These instructions assume that you already have cloned or download the Extensions API SDK. For information about setting up your environment and the Tableau requirements, see [Installation](../installation.md) and [Get Started with Dashboard Extensions](trex_getstarted.md).
+These instructions assume that you already have cloned or downloaded the Extensions API SDK. For information about setting up your environment and the Tableau requirements, see [Installation](../installation.md) and [Get Started with Dashboard Extensions](trex_getstarted.md).
For convenience, you might want to create a folder for your "Hello World" dashboard extension in the same location where you installed or cloned the GitHub repository (for example, `HelloDemo` under `/extensions-api`). That way, you can use the same web server (`http-server`) that is used for the samples.
diff --git a/website/docs/trex_release-notes.md b/website/docs/trex_release-notes.md
index b6431add..6a3004f6 100644
--- a/website/docs/trex_release-notes.md
+++ b/website/docs/trex_release-notes.md
@@ -20,9 +20,9 @@ What's new in this release:
* Added ISO values to `PeriodType` for parameters with `Range` domain type.
-* Added support for multiple dialogs. Use the [sendDialogMessageAsync](pathname:///api/interfaces/ui.html#senddialogmessageasync) method can send messages between any two dialog boxes or between any dialog box and the extension.
+* Added support for multiple dialogs. In addition to the configuration popup window, you can add other dialog boxes or popup windows that can interact with the extension. See [Add Multiple Dialog Boxes](./core/trex_multiple_dialogs.md).
-* Added the [sendDialogMessageToParentAsync](pathname:///api/interfaces/ui.html#senddialogmessagetoparentasync) method to the UI namespace. Sends a message from the dialog box to the extension or to the dialog box (the parent) that opened it.
+* Added the [sendDialogMessageAsync](pathname:///api/interfaces/ui.html#senddialogmessageasync) and the [sendDialogMessageToParentAsync](pathname:///api/interfaces/ui.html#senddialogmessagetoparentasync) methods to the UI namespace. Use the `sendDialogMessageAsync` method to send messages between any two dialog boxes, or between any dialog box and the extension. Use the `sendDialogMessageToParentAsync` method to send a message from the dialog box to the extension or to the dialog box (the parent) that opened it. See [Send messages between popup dialog boxes and the extension](core/trex_multiple_dialogs#send-messages-between-popup-dialog-boxes-and-the-extension).
@@ -99,11 +99,11 @@ What's new in this release:
*May 2024*
-* Tableau Dashboard Extensions API library: `tableau.extensions.1.12.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api)..)
+* Tableau Dashboard Extensions API library: `tableau.extensions.1.12.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api).)
* Certain features in this release are only available in Tableau 2024.2 or later. Download [Tableau Desktop](https://www.tableau.com/support/releases) or [Tableau Server](https://www.tableau.com/support/releases/server).
-* To preview new features and test your extension with the latest version of Tableau in the Developer Sandbox, join the [Tableau Developer Program](http://www.tableau.com/developer). and request your own Tableau Cloud developer site.
+* To preview new features and test your extension with the latest version of Tableau in the Developer Sandbox, join the [Tableau Developer Program](http://www.tableau.com/developer) and request your own Tableau Cloud developer site.
What's new in this release:
@@ -150,11 +150,11 @@ Also in this release:
*April 2024*
-* Tableau Dashboard Extensions API library: `tableau.extensions.1.11.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api)..)
+* Tableau Dashboard Extensions API library: `tableau.extensions.1.11.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api).)
-* Certain features in this release are only available in Tableau 2024.1 or later. Download [Tableau Desktop](https://www.tableau.com/support/releases). or [Tableau Server](https://www.tableau.com/support/releases/server).
+* Certain features in this release are only available in Tableau 2024.1 or later. Download [Tableau Desktop](https://www.tableau.com/support/releases) or [Tableau Server](https://www.tableau.com/support/releases/server).
-* To preview new features and test your extension with the latest version of Tableau in the Developer Sandbox, join the [Tableau Developer Program](http://www.tableau.com/developer). and request your own Tableau Cloud developer site.
+* To preview new features and test your extension with the latest version of Tableau in the Developer Sandbox, join the [Tableau Developer Program](http://www.tableau.com/developer) and request your own Tableau Cloud developer site.
About this release:
@@ -170,7 +170,7 @@ About this release:
The Viz Extensions API is currently under development. Tableau is working to offer the feature in general availability later in 2024.
- We encourage anyone interested in developing viz extensions to contact Wilson Po at [wpo@salesforce.com](mailto:wpo@salesforce.com). We’re running a program by invitation that focuses on the developer experience for those interested in exploring those tools. An active NDA must be in place to requests access to the preview at this time.
+ We encourage anyone interested in developing viz extensions to contact Wilson Po at [wpo@salesforce.com](mailto:wpo@salesforce.com). We’re running a program by invitation that focuses on the developer experience for those interested in exploring those tools. An active NDA must be in place to request access to the preview at this time.
Sign up to test Tableau Viz Extensions in the [Tableau Beta Preview](https://prerelease.tableau.com/welcome/), as part of the web authoring experience when you register for a Tableau Cloud Beta Site.
@@ -180,15 +180,15 @@ About this release:
*December 2022*
-* Tableau Dashboard Extensions API library: `tableau.extensions.1.10.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api)..)
+* Tableau Dashboard Extensions API library: `tableau.extensions.1.10.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api).)
-* Certain features in this release are only available in Tableau 2022.4 or later. Download [Tableau Desktop](https://www.tableau.com/support/releases). or [Tableau Server](https://www.tableau.com/support/releases/server).
+* Certain features in this release are only available in Tableau 2022.4 or later. Download [Tableau Desktop](https://www.tableau.com/support/releases) or [Tableau Server](https://www.tableau.com/support/releases/server).
-* To preview new features and test your extension with the latest version of Tableau in the Developer Sandbox, join the [Tableau Developer Program](http://www.tableau.com/developer). and request your own Tableau Cloud developer site.
+* To preview new features and test your extension with the latest version of Tableau in the Developer Sandbox, join the [Tableau Developer Program](http://www.tableau.com/developer) and request your own Tableau Cloud developer site.
About this release:
-* Updates for Tableau Viz, an easy way for you to add visualizations to your dashboard extensions using a declarative description. This release includes support for combination charts, charts with multiple mark types in the same visualization. Tableau Viz has a new input specification that support these new visualizations, see the [Tableau Viz v2 inputSpec](./trex_tableau_viz_ref_v2.md). For information about using Tableau Viz in your extensions, see [Add Tableau Viz to your Dashboard Extensions](./core/trex_tableau_viz.md).
+* Updates for Tableau Viz, an easy way for you to add visualizations to your dashboard extensions using a declarative description. This release includes support for combination charts, charts with multiple mark types in the same visualization. Tableau Viz has a new input specification that supports these new visualizations, see the [Tableau Viz v2 inputSpec](./trex_tableau_viz_ref_v2.md). For information about using Tableau Viz in your extensions, see [Add Tableau Viz to your Dashboard Extensions](./core/trex_tableau_viz.md).

@@ -210,7 +210,7 @@ For more information, see [Get Data from the View](./core/trex_getdata.md).
*June 2022*
-* Tableau Dashboard Extensions API library: `tableau.extensions.1.9.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api)..)
+* Tableau Dashboard Extensions API library: `tableau.extensions.1.9.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api).)
* Download [Tableau Desktop](https://www.tableau.com/support/releases) or [Tableau Server](https://www.tableau.com/support/releases/server).
@@ -239,11 +239,11 @@ About this release:
*February 2022*
-* Tableau Dashboard Extensions API library: `tableau.extensions.1.8.1.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api)..)
+* Tableau Dashboard Extensions API library: `tableau.extensions.1.8.1.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api).)
-* Download [Tableau Desktop 2021.4](https://www.tableau.com/support/releases). or [Tableau Server 2021.4](https://www.tableau.com/support/releases/server)..
+* Download [Tableau Desktop 2021.4](https://www.tableau.com/support/releases) or [Tableau Server 2021.4](https://www.tableau.com/support/releases/server).
-* To preview new features and test your extension with the latest version of Tableau in the Developer Sandbox, join the [Tableau Developer Program](http://www.tableau.com/developer). and request your own Tableau Cloud developer site.
+* To preview new features and test your extension with the latest version of Tableau in the Developer Sandbox, join the [Tableau Developer Program](http://www.tableau.com/developer) and request your own Tableau Cloud developer site.
About this release:
@@ -260,9 +260,9 @@ About this release:
*November 2021*
-* Tableau Dashboard Extensions API library: `tableau.extensions.1.8.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api)..)
+* Tableau Dashboard Extensions API library: `tableau.extensions.1.8.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api).)
-* Certain features in this release are only available in Tableau 2021.4 or later. Preview the features and test your extension with the latest version of Tableau in the Developer Sandbox. To gain access to the Developer Sandbox, join the [Tableau Developer Program](http://www.tableau.com/developer). and request your own Tableau Cloud developer site.
+* Certain features in this release are only available in Tableau 2021.4 or later. Preview the features and test your extension with the latest version of Tableau in the Developer Sandbox. To gain access to the Developer Sandbox, join the [Tableau Developer Program](http://www.tableau.com/developer) and request your own Tableau Cloud developer site.
About this release:
@@ -308,17 +308,17 @@ For more information, see [Tableau Viz Reference](./trex_tableau_viz_ref.md).
*October 2021*
-* Tableau Dashboard Extensions API library: `tableau.extensions.1.7.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api)..)
+* Tableau Dashboard Extensions API library: `tableau.extensions.1.7.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api).)
-* Certain features in this release are only available in Tableau 2021.4 or later. Preview the features and test your extension with the latest version of Tableau in the Developer Sandbox. To gain access to the Developer Sandbox, join the [Tableau Developer Program](http://www.tableau.com/developer). and request your own Tableau Cloud developer site.
+* Certain features in this release are only available in Tableau 2021.4 or later. Preview the features and test your extension with the latest version of Tableau in the Developer Sandbox. To gain access to the Developer Sandbox, join the [Tableau Developer Program](http://www.tableau.com/developer) and request your own Tableau Cloud developer site.
About this release:
* Added a new method, [`moveAndResizeDashboardObjectsAsync`](pathname:///api/interfaces/dashboard.html#dashboard.html#moveandresizedashboardobjectsasync). you can use to set the position and size of one or more floating dashboard objects. This can be useful for creating overlays, annotations, popups, or dynamic layouts.
-* Added a new method that can replay an animation in a dashboard. You can control the replay speed (`tableau.ReplaySpeedType.Slow`, `tableau.ReplaySpeedType.Normal`, or `tableau.ReplaySpeedType.Fast`). For more information see the [`replayAnimationAsync`](pathname:///api/interfaces/dashboard.html#replayanimationasync). method.
+* Added a new method that can replay an animation in a dashboard. You can control the replay speed (`tableau.ReplaySpeedType.Slow`, `tableau.ReplaySpeedType.Normal`, or `tableau.ReplaySpeedType.Fast`). For more information, see the [`replayAnimationAsync`](pathname:///api/interfaces/dashboard.html#replayanimationasync) method.
-* Dashboard extensions can now use workbook formatting by setting the appropriate class on the HTML elements. The specific Tableau classes to use are defined in the [`ClassNameKey`](pathname:///api/enums/tableau.classnamekey.html). enum. To apply the formatting in the body of your HTML page, use the string literal `tableau-*` for the enum. For example, to apply the worksheet title formatting you set the `class` for the HTML element in your extension (`div`, `h2`, etc.) to `"tableau-worksheet-title"`.
+* Dashboard extensions can now use workbook formatting by setting the appropriate class on the HTML elements. The specific Tableau classes to use are defined in the [`ClassNameKey`](pathname:///api/enums/tableau.classnamekey.html) enum. To apply the formatting in the body of your HTML page, use the string literal `tableau-*` for the enum. For example, to apply the worksheet title formatting you set the `class` for the HTML element in your extension (`div`, `h2`, etc.) to `"tableau-worksheet-title"`.
```html
Subheader, using tableau-worksheet-title class
@@ -335,7 +335,7 @@ About this release:
```
- You can access the formatting in the Tableau workbook from `tableau.extensions.environment.workbookFormatting`. The property `formattingSheets` contains the array of CSS properties for the workbook, organized by `ClassNameKey`. For more information about using workbook formatting, see the [Formatting](https://github.com/tableau/extensions-api/tree/main/Samples/Dashboard/Formatting). sample in the Samples folder. Also see [Add Tableau Workbook Formatting](./core/trex_format.md).
+ You can access the formatting in the Tableau workbook from `tableau.extensions.environment.workbookFormatting`. The property `formattingSheets` contains the array of CSS properties for the workbook, organized by `ClassNameKey`. For more information about using workbook formatting, see the [Formatting](https://github.com/tableau/extensions-api/tree/main/Samples/Dashboard/Formatting) sample in the Samples folder. Also see [Add Tableau Workbook Formatting](./core/trex_format.md).
* You can now set an event listener on changes to the dashboard layout and to the dashboard formatting. The new event types are `DashboardLayoutChanged` and `WorkbookFormattingChanged`.
@@ -345,7 +345,7 @@ About this release:
* Transparency - Tableau now supports dashboard extension transparency for Sandboxed extensions. To take advantage of extension transparency, set your background style to a transparent or partially transparent color.
-* Added a new method (`setClickThroughAsync`) that allows clicks to pass through the dashboard extension window. You can use this method in conjunction with transparency. See the [setClickThroughAsync](pathname:///api/interfaces/extensions.html#setclickthroughasync). method.
+* Added a new method (`setClickThroughAsync`) that allows clicks to pass through the dashboard extension window. You can use this method in conjunction with transparency. See the [setClickThroughAsync](pathname:///api/interfaces/extensions.html#setclickthroughasync) method.
@@ -357,9 +357,9 @@ About this release:
*September 2021*
-* Tableau Dashboard Extensions API library: `tableau.extensions.1.6.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api)..)
+* Tableau Dashboard Extensions API library: `tableau.extensions.1.6.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api).)
-* Download [Tableau Desktop 2021.3](https://www.tableau.com/support/releases). or [Tableau Server 2021.3](https://www.tableau.com/support/releases/server)..
+* Download [Tableau Desktop 2021.3](https://www.tableau.com/support/releases) or [Tableau Server 2021.3](https://www.tableau.com/support/releases/server).
About this release:
@@ -367,7 +367,7 @@ About this release:

-Starting with version 1.6 of the Dashboard Extensions API library and Tableau 2021.3, you can now add Tableau visualizations to your dashboard extensions. Tableau Viz takes a declarative description of your visualization and renders it as an SVG image that you can embed in your extension. Version 1.6 of the Dashboard Extensions library adds the [`tableau.extensions.createVizImageAsync`](pathname:///api/interfaces/extensions.html#createvizimageasync). method, which takes a JavaScript object describing the image as an input.
+Starting with version 1.6 of the Dashboard Extensions API library and Tableau 2021.3, you can now add Tableau visualizations to your dashboard extensions. Tableau Viz takes a declarative description of your visualization and renders it as an SVG image that you can embed in your extension. Version 1.6 of the Dashboard Extensions library adds the [`tableau.extensions.createVizImageAsync`](pathname:///api/interfaces/extensions.html#createvizimageasync) method, which takes a JavaScript object describing the image as an input.
For more information about using Tableau Viz, see:
- [Add Tableau Viz to Your Dashboard Extensions](./core/trex_tableau_viz.md)
- [Tableau Viz Reference](./trex_tableau_viz_ref.md)
@@ -384,7 +384,7 @@ New Dashboard Extension API methods in this release:
*June 2021*
-* Tableau Dashboard Extensions API library: `tableau.extensions.1.5.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api)..)
+* Tableau Dashboard Extensions API library: `tableau.extensions.1.5.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api).)
About this release:
@@ -394,7 +394,7 @@ About this release:
* The `selectMarksByValueAsync` method now supports combined selection criteria types (bug fixed).
-* The following are all improvements to the [`getSummaryDataAsync`](pathname:///api/interfaces/worksheet.html#getsummarydataasync). method:
+* The following are all improvements to the [`getSummaryDataAsync`](pathname:///api/interfaces/worksheet.html#getsummarydataasync) method:
* `getSummaryDataAsync` now has a smaller and faster payload.
@@ -408,7 +408,7 @@ About this release:
* The column information now includes the `fieldId` as well as the field name.
-For more information about changes in this release, see [Tableau Extensions v1.5.0](https://github.com/tableau/extensions-api/releases/tag/v1.5.0)..
+For more information about changes in this release, see [Tableau Extensions v1.5.0](https://github.com/tableau/extensions-api/releases/tag/v1.5.0).
@@ -506,9 +506,10 @@ About this release:
About this release:
-* The Extensions API library version 1.2 (`tableau.extensions.1.2.0.js`) is backward compatible with previous releases of the library. You can use the Extensions API library version 1.2 for extensions on Tableau 2018.2 and later. The library contains logic to handle any necessary conversions for the supported version of Tableau the extension is running in. For the best experience, you should always use the latest version of the library with the extensions you create.
+* The Extensions API library version 1.2 (`tableau.extensions.1.2.0.js`) is backward compatible with previous releases of the library. You can use the Extensions API library version 1.2 for extensions on Tableau 2018.2 and later. The library contains logic to handle any necessary conversions for the supported version of Tableau the extension is running in. For the best experience, you should always use the latest version of the library with the extensions you create.
+
+* The names of the Extension API library files have changed. The hyphens (-) have been removed from the file name (was `tableau-extensions-*`, now `tableau.extensions.*`). Starting with the 1.2 library, the names of the library files are as follows:
-* The names of the Extension API library files have changed. The hypens (-) have been removed from the file name (was `tableau-extensions-*`, now `tableau.extensions.*`). Starting with the 1.2 library, the names of the library files are as follows:
```
tableau.extensions.1.2.0.js
tableau.extensions.1.2.0.min.js
@@ -535,7 +536,7 @@ Bugs fixed in this release:
* Tableau Extensions API library: `tableau-extensions-1.1.0.js` (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api).)
-* Download [Tableau Desktop 2019.1](https://www.tableau.com/support/releases). or [Tableau Server 2019.1](https://www.tableau.com/support/releases/server).
+* Download [Tableau Desktop 2019.1](https://www.tableau.com/support/releases) or [Tableau Server 2019.1](https://www.tableau.com/support/releases/server).
Changes in this release:
@@ -545,8 +546,6 @@ Changes in this release:
-
-
Bugs fixed in this release:
* Select dropdown fixed on Macintosh. (TFSID 758234)
@@ -576,7 +575,7 @@ Bugs fixed in this release:
- Tableau Extensions API library: `tableau-extensions-1.0.0.js` *No change for this release* (download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api).)
-- Download [Tableau Desktop 2018.3](https://www.tableau.com/support/releases). or [Tableau Server 2018.3](https://www.tableau.com/support/releases/server).
+- Download [Tableau Desktop 2018.3](https://www.tableau.com/support/releases) or [Tableau Server 2018.3](https://www.tableau.com/support/releases/server).
@@ -596,17 +595,17 @@ New in this release:
New in this release:
-- Use the [Design Guidelines for Dashboard Extensions](./ux_design.md). as a roadmap for designing great dashboard extensions.
+- Use the [Design Guidelines for Dashboard Extensions](./ux_design.md) as a roadmap for designing great dashboard extensions.
-- Create extensions with the look-and-feel of Tableau, using the [Tableau UI](https://tableau.github.io/tableau-ui/.md)., a React component library.
+- Create extensions with the look-and-feel of Tableau, using the [Tableau UI](https://tableau.github.io/tableau-ui/.md), a React component library.
- New and updated documentation. See [Publishing a Dashboard Extension](./publish/trex_publish.md).
For information about developing and running an extension locally on `http://localhost` and testing it on Tableau Cloud or Tableau Server (over HTTPS), see [Load and view localhost content on sites that use secure connections](./security/trex_security.md#load-and-view-localhost-content-on-sites-that-use-secure-connections).
Bugs fixed in this release:
-- Extensions are now fully supported in Internet Explorer (IE 11).
+- Extensions are now fully supported in Internet Explorer (IE 11).
---
@@ -617,7 +616,7 @@ Release of the Tableau Extensions API
- Tableau Extensions API library: `tableau-extensions-1.0.0.js`
(download or clone the Extensions API repository on [GitHub](https://github.com/tableau/extensions-api).)
-- Download [Tableau Desktop 2018.2](https://www.tableau.com/support/releases). or [Tableau Server 2018.2](https://www.tableau.com/support/releases/server).
+- Download [Tableau Desktop 2018.2](https://www.tableau.com/support/releases) or [Tableau Server 2018.2](https://www.tableau.com/support/releases/server).
Bugs fixed in this release:
@@ -961,13 +960,13 @@ For information about debugging extensions, see [Remote Debugging of JavaScript
**Breaking change**
- Schema change - Updated XSD file for the dashboard extensions manifest file (`.trex`).
- If you have an existing extension, you must update the `.trex` file to follow the new schema. There is a script you can run that converts the manifest file for you. Or you can manually make the changes. For more information about the manifest, see [Tableau Extension Manifest File](./dashext/trex_manifest.md). You can download the manifest conversion script from the **Extensions API Developer Preview** on [https://prerelease.tableau.com](https://prerelease.tableau.com)..
+ If you have an existing extension, you must update the `.trex` file to follow the new schema. There is a script you can run that converts the manifest file for you. Or you can manually make the changes. For more information about the manifest, see [Tableau Extension Manifest File](./dashext/trex_manifest.md). You can download the manifest conversion script from the **Extensions API Developer Preview** on [https://prerelease.tableau.com](https://prerelease.tableau.com).
- Existing workbooks - if you have an existing workbook that uses a dashboard extension, you will not be able to open it with this (`0.7.0`) release. To get around this issue, update the manifest file (`.trex`), update your extension to use `tableau-extensions-0.7.0.js`, and then open a new workbook and re-create the dashboard.
**New features**
-- Tableau Server. You can publish dashboards containing extensions and run them on Tableau Server. You can download a version of Tableau Server 10.5 that supports dashboard extensions from the **Extensions API Developer Preview** on [https://prerelease.tableau.com](https://prerelease.tableau.com)..
+- Tableau Server. You can publish dashboards containing extensions and run them on Tableau Server. You can download a version of Tableau Server 10.5 that supports dashboard extensions from the **Extensions API Developer Preview** on [https://prerelease.tableau.com](https://prerelease.tableau.com).
- Security - Your dashboard extension must use an HTTPS connection. If you are using `localhost` for development, you can still use HTTP.
- Sharing dashboards - the dashboard extension now gets saved with the workbook, so you can share your workbooks that use the extension with others.
- New method `DataSource.getConnectionSummariesAsync` gets a summary object for each underlying connection in a data source.
diff --git a/website/docs/vizext/trex_viz_create.md b/website/docs/vizext/trex_viz_create.md
index 93b34bf0..bcd67a36 100644
--- a/website/docs/vizext/trex_viz_create.md
+++ b/website/docs/vizext/trex_viz_create.md
@@ -15,11 +15,9 @@ To create a Tableau viz extension you need the following components.
---
-
-
### What you need to get started
-These instructions assume that you have already cloned or download the Extensions API SDK. For information about setting up your environment and the Tableau requirements, see [Get Started](./trex_viz_getstarted.md).
+These instructions assume that you have already cloned or downloaded the Extensions API SDK. For information about setting up your environment and the Tableau requirements, see [Get Started](./trex_viz_getstarted.md).
For convenience, you might want to create a folder for your "Hello World" viz extension in the same location where you installed or cloned the GitHub repository. Create your folder, for example, **HelloVizExtension** in the Samples folder, under `/extensions-api/Samples`. That way, you can use the same web server (`http-server`) that is used for the samples.
diff --git a/website/sidebars.js b/website/sidebars.js
index 67bdc46e..60755481 100644
--- a/website/sidebars.js
+++ b/website/sidebars.js
@@ -48,6 +48,7 @@ const sidebars = {
items: [
'core/trex_getdata',
'core/trex_configure',
+ 'core/trex_multiple_dialogs',
'core/trex_tableau_viz',
'core/trex_format',
'core/trex_show_hide',