3 ways to use ChatGPT for Mendix UX

Coding can seem like a daunting enterprise to low-coders. However, over the years, I have found that using the JavaScript API in Mendix significantly increases the power of the platform, while also increasing maintainability in Mendix. Luckily, nowadays we have resources like ChatGPT to help us write and debug code.

Wouter Penris
Mendix Community
Published in
9 min readMar 30, 2023

--

Generated by Midjourney Bot: “a stunning illustration in 4k of a coder about to step through the door into a mysterious magical place of super code”

In this article, I will share 3 examples in which I used ChatGPT and JavaScript to speed up Mendix development and to create some essential UX improvements.

Example 1: Snackbars

Snackbars, also called toasts, can be problematic to create and maintain in Mendix using standard tools such as pages or containers, as they require a complex setup that is difficult to maintain (I challenge you to try it yourself). For those who do not know what Snackbars are, these are little pop-up messages to indicate a user’s action is complete. Here is an example of a snackbar I created.

A snack bar appears and disappears from the top center of the screen

In essence, this is nothing more than a <div> element with a <p> inside; some fancy CSS makes it fly in and out.

Here are some key options to think of when implementing a snackbar: if we click the message, should it disappear? How long should we see it? What if we move to another page, should we still see the snackbar? Do we want to add an image? Do we want to start a Nanoflow on click?

Nanoflow Action triggering the Snackbar

For a recent project at Ordina Digital Services, we had to show snackbars so often, that managing them became too complex. We decided creating a single JavaScript Action that could be called in any Nanoflow would be handier. The resulting action has 7 parameters:

Parameters of the JsA_Snackbar_CreateAndShow

Once you create a new JavaScript action, you are presented with this screen in which you need to replace line 19 with your own code block:

An example of a Mendix JavaScript action, clean out of the box

This is where ChatGPT can come in handy for some basics. In this case, I used this query: 1) “Give me a piece of javascript code that shows a snackbar message saying hello world,” and ChatGPT was even kind enough to include some styling. Go ahead and try it out yourself — what is returned is something that can easily be reworked into what we need.

ChatGPT answering the Snackbar query

ChatGPT has likewise already shown us how to create a snackbar and how to set an internal text.

Obviously, we still have to change what ChatGPT gave us to make it work perfectly. Let’s rework the result into our JavaScript Action. We’ll write a function that creates and shows a snackbar and at the end of the action we will call the function. Let’s also give the snackbar <div> a classname based on a String parameter classNameToGive). Finally, let’s pass the sourceText String parameter as innerHTML into a <p> element and place this <p> into the snackbar <div>.

// BEGIN USER CODE

//function that creates the snackbar, waits and then removes it.
async function showSnackbar(){

//create div for the snackbar, with the proper id and with the right class
let snackbar = document.createElement('div');

//set classNameToGive
snackbar.setAttribute('class', classNameToGive);

//Let's set the message in a <p>, add it create and append it to the snackbar.
let paragraph = document.createElement('p');
paragraph.innerHTML = sourceText;
snackbar.appendChild(paragraph);

}

//call the function to create and show the snackbar
showSnackbar();
// END USER CODE

Next up, we want to create a mechanism to place the snackbar into our HTML. It is best to place a snackbar directly in the .region-content of your page. Likewise, if you change the page, the content of this <div> will also be replaced by Mendix, automatically destroying your snackbar along with it. In some cases, it could be handy to let the snackbar remain in sight, so let’s make the parent dynamic with a String parameter called parentElement:

...
//get the parentElement class from the html and inject the snackbar into it.
let parentElement = document.querySelectorAll(parentClass)[0];
parentElement.insertBefore(snackbar, parentElement.firstChild); //inject element

If you run this code from a Nanoflow, the snackbar will already appear, but it will not hide itself after some time. In order to achieve this, we need a timeout and apply a .fade-out class. The timeout length should be configurable, so I added a timeOutLength parameter — an integer in milliseconds.

I asked ChatGPT and learned about setting up a delay constant, which I could then use in theasync function showSnackbar() . After the delay, I added the class .fade-out that causes the snackbar to become hidden. After yet another delay, the snackbar should be removed altogether:

// constant needed for asynchronous (waiting time) call below
const delay = ms => new Promise(res => setTimeout(res, ms));

...
//continuation of showSnackbar()

//wait for a bit
await delay(timeOutLength);

//after wait, add fade out animation class and wait again so the animation can play
snackbar.classList.add('fade-out');
await delay(timeOutLength);

//after it is hidden, remove the snackbar
parentElement.removeChild(snackbar);

The only thing left to do is to ensure that everything looks nice. I needed some advanced CSS to trigger an animation that brings the snackbar into view, and some code that hides it. It will look somewhat like this:

//animation to fade in an element from the top
@keyframes fadeIn {
0% {
opacity: 0;
top: -20vh;
}

100% {
opacity: 0.8;
top: 100px;
}
}

//animation to fade out an element to the top.
@keyframes fadeOut {
0% {
opacity: 0.8;
top: 100px;
}

100% {
opacity: 0;
top: -20vh;
}
}

//class that makes the snackbar fade in.
.fade-in-snackbar {
animation: fadeIn 0.5s ease-in-out;
}

//class that makes the snackbar fade out.
.fade-out {
animation: fadeOut 0.5s ease-in-out;
animation-fill-mode: forwards;
}

Should you want to test the actual result, go right here to test the snackbars yourself. If you want to take a look at the code, then you can download the actual element, styling, and an example Nanoflow or setting image right here. Try it out to see if it works for you (Mx 9.23).

Example 2: Using .Click() to open Tab Containers

Mendix Tabs can be challenging to open from the click of a button. A Nanoflow with a JavaScript Action can help us achieve that effect. Let’s first inspect the tab container element we want to create a link to:

Inspection of a tab-container list of tabs — each element gets a unique class; the <a> is our target

Each tab in the tab container standard gets a unique element class name in Mendix. Let’s ask ChatGPT for help: “Give me a piece of JavaScript that finds a button with class name ‘mx-name-tabPage5’ and clicks it, and make it scroll into view.”

ChatGPT giving us the basic JavaScript we need

The resulting code works excellently! However, I wanted to parameterize the .classname, so I could use the same code more generically. Sometimes a scroll might not be needed. Hence, I created and used a Boolean parameter there as well. The JavaScript Action code result was as follows:

/**
* @param {string} targetClassNameUnique - targetClass - should start with a full-stop e.g. '.mx-name-tabPage5'
* @param {boolean} scrollIntoView - If you want to scroll the element into view, indicate true.
* @returns {Promise.<void>}
*/
export async function JsA_ClickElementScrollIntoView(targetClassNameUnique, scrollIntoView) {
// BEGIN USER CODE

//get target element
const element= document.querySelector(targetClassNameUnique);

//if found
if (element) {
element.click(); //click on it

//if we want the element to scroll into view
if (scrollIntoView){
element.scrollIntoView({ behavior: 'smooth' }); // do so
}
}

// END USER CODE
}

Example 3: Adding Image Divs to Tab Containers

The third and final example revolves around Tab Containers in Mendix. These currently do not allow much customization. The widget itself has only a very rudimentary set of options per tab button—no additional styling classes can be set on the tab buttons other than what is determined by the Name field, which is auto-cast into a class name such as the one outlined in the example above (2). If we want to add a <div> with a special class to a tab button, that will be impossible to do without some JavaScript magic. However, without a child <div> our styling would be extremely difficult.

Mx Tab buttons cannot be configured to receive custom classes

Let’s ask ChatGPT for help: “Please give me a piece of javascript that looks up tabContainers with class ‘.mx-tabcontainer’ and that adds a div with an incrementing class name for each element in it. The classnames should look like ‘tab-1,’ ‘tab-2,’ ‘tab-3,’ etc.” This is the working code that ChatGPT generated, annotated by myself for your comfort:

//get all tab-container elements in the document
let tabContainers = document.querySelectorAll('.mx-tabcontainer');

//for each tabContainer, find all buttons inside: <a> elements, called tabs
tabContainers.forEach(function(container) {
let tabs = container.querySelectorAll('a');

tabs.forEach(function(tab, index) { //for each tab,
let div = document.createElement('div'); //create a <div>
div.classList.add('tab-' + (index + 1)); //addthe right classname
tab.parentNode.appendChild(div, tab.nextSibling); //and insert into <a>
});
});

And to prove that this works, just copy this block of code into a JavaScript action, add it to a Nanoflow, and call it from a Microflow Timer that fires once after a page load.

Here is what it did for my page. Below, it is clearly visible that each <a> now has a <div> element with a styling class that we can target to put images inside the tab buttons.

Image showing five tabs, which now all have a child-div with a target class that can be styled.

By the way, if you don’t know how to style an image onto these new divs, you can also ask ChatGPT, of course! Moreover, if you get syntax errors from your JavaScript, just ask ChatGPT to help debug your code:

ChatGPT debugging faulty JavaScript Code

Concluding, the JavaScript action API in Mendix is a very powerful tool that we can use to improve the UX of our Mendix apps. Three examples were given:

  1. Create and show Snackbars
  2. Open tab containers and make them scroll into view
  3. Add divs with custom class names to tab container buttons, so we can target these classes to display images.

JavaScript Actions are an inevitable Mendix extension that is fun to build, and ChatGPT is the perfect way to help you get where you need to be, and get there quickly!

Have you used ChatGPT with Mendix? Leave a comment and tell me how!

#About: Wouter Penris
Wouter is a (lead) Mendix Software Engineer with a background in education (English & Music) and in music (Jazz Vocals & piano); a multi-potentialite. Where as a teacher he spent years perfecting the art of instructing his students as simply and understandably as possible, he now immensely enjoys using this same skill to build high-tech products with an intuitive and easily-understandably UX. He is a highly creative problem solver, in which he blends research, technology and aesthetics into actual business value and advice. Wouter is a communicator at heart and especially enjoys working with international clients due to his background in English. Wouter currently works as Senior Principal Expert in Mendix at Ordina.

Ordina promo, March 2023 — www.ordina.nl

Read More of My Articles:

From the Publisher -

If you enjoyed this article you can find more like it on our Medium page. For great videos and live sessions, you can go to MxLive or our community Youtube page.

For the makers looking to get started, you can sign up for a free account, and get instant access to learning with our Academy.

Interested in getting more involved with our community? Join us in our Slack community channel.

--

--