Community Spring Cleaning week is here! Join your fellow Maveryx in digging through your old posts and marking comments on them as solved. Learn more here!

Engine Works

Under the hood of Alteryx: tips, tricks and how-tos.
Ozzie
Alteryx
Alteryx

Introduction


If you’ve stumbled upon this article and you’re wondering “Huh? What’s an HTML GUI SDK?” then I highly recommend checking out @RithiS's Overview of the Developer Platform. In that article, we explain all the different ways you can build custom tools in Alteryx and why creating different types of tools is incredibly useful. In this article, we will build a simple example of one of many possible combinations of ways you can make tools in Alteryx. More specifically, we are going to build out an HTML user interface using the HTML GUI SDK for an already existing macro or as I like to say “HTML Macro” for short. For the scope of this article, we will only be mimicking the macro interface in our HTML front end. However, with the concepts presented in this article, you should have the basic tools and knowledge to make your HTML Macro have even greater levels of interactivity than a regular macro interface can provide. 

 

what we are building.png

 

In this walk-through, the existing macro that I will convert will be a tool created by our very own @SophiaF called the Email Parse tool. This tool is a simple macro that takes a “first name” field and a “last name” field and outputs an email address based on the user’s configuration. Here is what the current interface looks like:

 

emailtoololdui.png

Looking at the configuration we have two dropdowns, one checkbox and four textboxes (one is visible when the checkbox is checked). All of these macro interface objects are available as widgets in the HTML GUI SDK; thus this tool will be great to recreate the interface in HTML.

So how do we start? The very first step is creating the necessary folder and file structure.

 

Creating the folder structure


The three directories where an HTML tool will be recognized by Alteryx are:

  • [Alteryx_installation]\bin\HtmlPlugins
  • C:\ProgramData\Alteryx\Tools
  • C:\Users\{username}\AppData\Roaming\Alteryx\Tools

If you are building a tool that will be scheduled, I suggest placing that tool’s folder in either of the first two options so that it will be recognized by the default system. Otherwise you will need to set your “Run As” setting to your user in order for that tool to not appear missing by the system.

First, create a folder in one of these directories and name it after your tool. Next, create these files:

 

folderstructureemail.png


 

 

 

 

 

 

Inside Supporting_Macros, copy and paste the macro along with any other supporting macros that your tool uses. While the Supporting_Macros folder is optional, it makes it easier for pathing and packaging. It also hides the original macro from your tool palette. The first Config.xml is also optional, but it will be used for YXI creation which we will get into later. ToolNameConfig.xml, ToolNameGui.html and ToolNameIcon.png are however required. For ease, it’s probably better to copy these files from \bin\HtmlPlugins\HtmlGuiSdk so that way you don’t have to write these lengthy files out yourself. If all this already sounds like a pain, I highly recommend using our Alteryx Tool Generator which will automatically create this file structure for you in \Users\{username}\AppData\Roaming\Alteryx\Tools.

 

Config file verification


Whether you used the tool generator or not, using your favorite text editor, open up ToolNameConfig.xml. This XML file tells the Alteryx Engine what this tool is and how to interact with it. The three most important things to make sure of is the engine settings, GUI settings, and connections.

The EngineDllEntryPoint points to the file that the engine expects to give it instructions. In this case, we are pointing to a macro file. EngineDll is going to be what type of backend the tool is going to be so in this case we put “Macro.” If you’re working with other SDKs like the python SDK, this will instead say ”Python” and EngineDllEntryPoint will instead point to a python file. SDKVersion should say “10.1”. Everything in the MetaInfo tag should be familiar to you. These tags are the same fields that are in the Meta Info tab in the workflow configuration panel of a macro. Only the MetaInfo specified in here will be recognized by Alteryx so I highly encourage you to fill this out if you already have this info in your original macro.

 

emailconfigxml.png

 

In the GUI settings, we specify the path of our HTML and icon files. We also have the option to add our own custom help documentation if we want to get fancy.

In the Connections section, you should have the same number of input and output connection lines as you do in your tool. In this case, we have one input and one output connection in our macro so one line for each as shown above is correct. An important and often easy thing to forget is that the Name property for both input and output connections MUST match the connection name that is in the Macro Input and Macro Output tools.

 

inputconnection_namemacro.png

 

Otherwise, Alteryx will not know where the input and output streams are so you’ll get a “Missing Incoming Connection” error if these names don’t match.

 

The top macro is just the original macro, the bottom is the HTML macro that we are building.The top macro is just the original macro, the bottom is the HTML macro that we are building.

 

Labels are optional, but you must put them here if you want them to show up on your macro. If you only put anchor abbreviations in your Macro Input and Output tools, they will not show up because the interface of the tool is now dependent on the settings defined in the XML file.

 

Building the user interface


Now that our files are all set up, we are ready for the fun stuff, which is building out the UI. If you happened to copy the HTML – GUI Library example HTML you’ll notice the vast choices of widgets available. All the widgets will appear between <ayx> tags. The most important part of this HTML file though is between the first script tags.

document.write('<link rel="import" href="' + window.Alteryx.LibDir + '2/lib/includes.html">')


This line is for importing the sdk and widgets. Without this none of the widgets would function.

In this case lets copy the widgets that we need and delete everything else between the first body tag and the script tag. We will also delete everything in between that second script tag as we will be putting some JavaScript in there later. As I stated in the beginning, we need two dropdowns, one checkbox, and four text boxes.

 

emailBodayDraft.png

 

In addition to adding the widgets, I have changed some properties and added some labels and legends. I have added the “Email Parse” legend at the top and added labels that matched the labels in the original macro. With each widget, you’ll see some properties inside data-ui-props.

For all of them, we changed the widgetId to something appropriate. Each widgetId must also be unique otherwise it won't render. For the dropdowns, we added placeholder text with the “placeholder” property and made the dropdowns searchable. Now our macro’s UI should look like this:

 

emailUIupdate1.png

 

Now that we have our widgets laid out, we have one more thing that we need to do that will make the macro work. We need a way for the values that our user inputs to transfer downstream to the macro for it to be able to do its magic. For this, we will use data items. Data items allow us to save and pass values into the tools configuration XML. To do this, ,we can add data-item-props to our widgets and we assign a dataName property. For convenience, we usually just make this the same as the corresponding widgetId. For the Textboxes, we will also set a dataType property to either “SimpleString” or “SimpleInt” so that way we can restrict what we want the user to enter for certain text boxes. For example, for two of the text boxes where we ask the user to enter a number that corresponds to how many letters they want to parse out of the first and last name, we only want users to enter in numbers; thus we restrict the dataType to a SimpleInt. This will only let users enter in numbers in the UI.

In addition to specifying the dataNames in the HTML file, we must change the Name of each interface tool in the Annotation tag inside the main macro to have it match with our HTML counterparts.

 

macroAnnotations.png

 

datanamematchpng.png

 

 

 

Changing the annotation in the macro also changes the macro's xml. Therefore, what makes this work is that since the engine is given instructions on what processes to perform via the macro’s XML, the configuration values stored in the configuration xml (the part we make when creating an HTML UI) are what the engine will use to fill in the gaps. Therefore, the dataNames and Annotations need to match if you plan on passing values downstream to a macro. Otherwise, you’ll end up with a warning like this when you run the workflow.

 

macro out of date.png

 

In this case, I changed the annotation tag of the dropdown to “firstNameWrong” in the macro. Now there is no instance of firstName in the macro XML but it still exists in the configuration XML; thus Alteryx still is expecting it somewhere. So it is important to make sure your dataNames match with your interface tool’s names, otherwise, the values that you want to pass down to the macro won’t be passed down and your tool won’t work as expected. If you create a data item that has nothing to do with the macros, then this error shouldn’t concern you.

Now that we defined our data-item-props in each widget our macro will work as expected. What’s left now? Well right now the checkbox doesn’t hide the punctuation textbox as it does in the regular macro, so we might want to write some simple JavaScript to make it happen. Also, it would be nice to have default values when the tool first loads just like the regular macro so we’ll do this as well.

This is where we begin writing JavaScript inside that second script tag in our HTML. Of course, you can write in a separate JavaScript file and link to it in the tags if you prefer. We’ll start by creating a function called unhidePunctuation.

 

unhidepunct.png

 

Something that may be unfamiliar to you may be Alteryx.Gui.Manager. The manager lets us access and interact with widgets and data items. Documentation around the manager can be found here. We use the manager to extract the value from our checkbox, which will always be a boolean value, to determine if we should hide the div named punctuation that contains our textbox widget for entering punctuation.

Now that we have this, we still need have an event listener set up for our checkbox so that way it runs unhidePunctuation every time the user clicks the checkbox. Now the way we implement this might be a bit different then you are used to.

 

Afterload.png

 

In the code we implement a function called Alteryx.Gui.Afterload. This function is executed once all the data stores have been loaded. The important thing to note here is that the function will be called when we drag the tool onto the canvas and when we click on and off the tool. More documentation about this function can be found here.

From Lines 96-113, we set our default values by using the manager in Alteryx.Gui.Afterload becausecan Alteryx.Gui.Afterload is run each time the tool is loaded.

This is the same manager that I described before but since Alteryx.Gui.Afterload already passes the manager in as a parameter, we can just reference the parameter instead of the global instance (Alteryx.Gui.Manager).

Now that we have our default values set, we set up the property listener for the checkbox. In line 116, we initially just call unhidePunctuation because we want to have an initial check when a user clicks back on the tool before registering a property listener. In Line 117, we use the registerpropertylistener method to make sure unhidePunctuation is called each time the 'value' of our checkbox is changed. Now that we have that done. We are officially done with building our HTML tool.

 

emailUIupdateFinal.png

 

Debugging

 

If at any point you get stuck building an HTML tool and run into trouble. I highly encourage using the CEF Developer tools. If you’re used to debugging web apps in Chrome, this should look familiar to you. To be able to use the debug tools, read here to learn how to enable them for Designer.

 

YXI creation


Now that we have built our fancy new HTML Macro, we want to share it and brag to all of our coworkers about how awesome our macro is. We will do this by creating a YXI. You can find documentation on package and installing a YXI. I will also go over it briefly.

Remember that other Config.xml file that we didn’t touch?

This file is like the ToolNameConfig.xml file but in here there is only metainfo.

 

configxml.png

 

The metainfo that is in this file will affect the contents of the pop-up dialog when a user first clicks the YXI.


yxi-dialog.png

 

To create the YXI copy the Config.xml and place it in the parent directory. Select the tool folder and the Config.xml file, right click and click Send To -> Compressed (zipped) folder. Then change the extension to from .zip to .yxi. Congratulations, we just successfully built an HTML Macro and are able to share it with whomever we want to brag to.

I hope this walk through was helpful, the yxi of this tool is attached to the article. If you have comments or questions about the concepts presented in the article, please feel free to leave a comment and let us know what other kinds of developer content you would like to see. Cheers! And Happy Alteryx-ing!

Ozzie Dembowski
Software Engineer

Ozzie is a Software Engineer that began his career at Alteryx as a Customer Support Engineer in January of 2016. After learning the in's and out's of Alteryx and having a love for building stuff, he couldn't help himself but tinker more with the product and create custom tools and macros every chance he could. Ozzie now spends his days building tools that keep pushing the boundaries of what Alteryx can provide. When he is not coding, he is probably traveling or critiquing beer.

Ozzie is a Software Engineer that began his career at Alteryx as a Customer Support Engineer in January of 2016. After learning the in's and out's of Alteryx and having a love for building stuff, he couldn't help himself but tinker more with the product and create custom tools and macros every chance he could. Ozzie now spends his days building tools that keep pushing the boundaries of what Alteryx can provide. When he is not coding, he is probably traveling or critiquing beer.

Comments