Enhancement to the Show Confirmation JavaScript Action: Web Title Support and Custom CSS Class - Mendix Forum

Enhancement to the Show Confirmation JavaScript Action: Web Title Support and Custom CSS Class

3

While working with the standard Show Confirmation JavaScript Action generated by Mendix, I noticed a limitation in the Web runtime that may affect projects requiring a more customized user experience.

Original Behavior

The original implementation exposes a titleCaption parameter:

@param {string} titleCaption - Set to empty to use default text 'Confirmation'. (Only for native)

However, this parameter is only used when the application is running in a Native environment:

Alert.alert(title, question, ...)

For Web applications, the implementation relies on:

mx.ui.confirmation(...)

which displays the standard Mendix confirmation dialog but ignores the titleCaption parameter entirely. As a result, developers cannot dynamically define the dialog title from a Nanoflow when running on the Web.

Enhancement 1: Dynamic Title Support for Web

The first enhancement adds support for custom dialog titles in Web applications.

Instead of injecting global CSS to replace the title, the solution uses a MutationObserver to detect the creation of the confirmation dialog and directly update the dialog header in the generated DOM.

Benefits

From a developer perspective, the same parameter that already works in Native can now be used transparently in Web.

Enhancement 2: Optional Custom CSS Class

A second enhancement introduces an optional input parameter:

dialogClassName

When provided, the JavaScript Action adds the specified class to the generated dialog container:

<div class="modal-dialog mx-dialog my-custom-class">

Benefits

Projects that do not provide a class continue to behave exactly as before.

Result

With these two small changes, the action becomes significantly more flexible:

✅ Dynamic titles work in both Native and Web environments.

✅ Developers can optionally assign custom CSS classes to individual confirmation dialogs.

✅ No changes are required for existing implementations.

✅ The solution remains fully backward compatible.

I believe these improvements could make the standard Show Confirmation action more consistent across platforms and provide additional customization possibilities for Web applications without breaking existing projects.


/----------- Javascript action result ---------------/

// This file was generated by Mendix Studio Pro.

//

// WARNING: Only the following code will be retained when actions are regenerated:

// - the import list

// - the code between BEGIN USER CODE and END USER CODE

// - the code between BEGIN EXTRA CODE and END EXTRA CODE

// Other code you write will be lost the next time you deploy the project.

import "mx-global";

import { Big } from "big.js";

// BEGIN EXTRA CODE

// END EXTRA CODE

/**

* Shows a confirmation dialog during the execution of a nanoflow, to make perform actions based on the user input.

* @param {string} titleCaption - Set to empty to use default text 'Confirmation'. (Only for native)

* @param {string} question - This field is required.

* @param {string} cancelButtonCaption - Set to empty to use default text 'Cancel'.

* @param {string} proceedButtonCaption - Set to empty to use default text 'OK'.

* @param {string} [dialogClassName]

* @returns {Promise.<boolean>}

*/

export async function ShowConfirmationClassName(titleCaption, question, cancelButtonCaption, proceedButtonCaption, dialogClassName) {

// BEGIN USER CODE

if (!question) {

return Promise.reject(new Error("Input parameter 'Question' is required"));

}

const cancel = cancelButtonCaption || "Cancel";

const proceed = proceedButtonCaption || "OK";

const title = titleCaption || "Confirmation";

// Native platform

if (navigator && navigator.product === "ReactNative") {

const Alert = require("react-native").Alert;

return new Promise(resolve => {

Alert.alert(title, question, [

{ text: cancel, onPress: () => resolve(false), style: "cancel" },

{ text: proceed, onPress: () => resolve(true) }

]);

});

}

// Web

return new Promise(resolve => {

mx.ui.confirmation({

content: question,

proceed,

cancel,

handler: () => resolve(true),

onCancel: () => resolve(false)

});

const observer = new MutationObserver(() => {

const dialog = document.querySelector(

'[id^="mxui_widget_DialogMessage_"]'

);

if (!dialog) {

return;

}

if (dialogClassName) {

dialog.classList.add(dialogClassName);

}

const titleElement = dialog.querySelector(".modal-header h4");

if (titleElement && title) {

titleElement.textContent = title;

}

observer.disconnect();

});

observer.observe(document.body, {

childList: true,

subtree: true

});

});

// END USER CODE

}


asked
0 answers