Take a look at this
small gallery web app, do you think that it's written entirely in UI5? The correct answer is "yes", but with the help of
Semantic UI and the
UI5 JSX renderer.
This blog is meant to be a fast teaser for my presentation at
Inside Track: Timisoara. We'll take a glance over some useful JSX techniques for building custom controls that I've used throughout the development of the gallery app.
JSX Intro
JSX is a syntax extension for JavaScript popularised by ReactJS. The power of JSX comes from the fact that it can be mixed with regular JavaScript expressions. In order to work, it needs to be compiled (or "transpiled") back into normal JavaScript using, for example,
BabelJS.
The following ReactJS JSX snippet:
const element = (
<h1 className="greeting">Hello, world!</h1>
);
Is compiled into the following JavaScript code:
const element = React.createElement(
'h1', {className: 'greeting'}, 'Hello, world!'
);
For embedding expressions inside JSX, we just have to surround the JS expressions with curly brackets. This nesting of JavaScript and JSX can be done recursively to virtually any level.
JSX with UI5
A while back, I wrote a small BabelJS plugin for compiling JSX into UI5 render manager calls. It allows you to write something like this:
oRm.render(
<div ui5ControlData={oC} class="title">
<h1 class="ui center aligned header">
{ oC.getTitle() }
</h1>
<div class="ui center aligned subtitle">
{ oC.getSubtitle() }
</div>
</div>
);
And then compiles it into something along the lines of this:
oRm.write("<div ");
oRm.writeControlData(oC);
oRm.addClass("title");
oRm.writeClasses();
oRm.write(">");
oRm.write("<h1 ");
oRm.addClass("ui");
oRm.addClass("center");
oRm.addClass("aligned");
oRm.addClass("header");
oRm.writeClasses();
oRm.write(">");
oRm.writeEscaped((oC.getTitle() || ""));
oRm.write("</h1>");
oRm.write("<div ");
oRm.addClass("ui");
oRm.addClass("center");
oRm.addClass("aligned");
oRm.addClass("subtitle");
oRm.writeClasses();
oRm.write(">");
oRm.writeEscaped((oC.getSubtitle() || ""));
oRm.write("</div>");
oRm.write("</div>");
Notice that it is incredibly hard to understand what we are actually rendering when looking at the compiled code? Even if you would write it by hand and introduce some helper methods, it would be ugly to behold and difficult to grasp.
Techniques
So now that we have the very basic concept of what we can do with JSX, let's look at some easy examples from the gallery app. In the following snippets, I will omit auto-generated IDs for brevity and consider that the
oC
variable contains the custom control. We will look at the JSX code and the rendered output at runtime.
Simple property substitution
One of the most basic of all JSX techniques: simply adding some "dynamic" text into some static HTML. Through "dynamic", I mean taken from the custom control's properties or from some variable in general.
(the control has a string property
title
with the value
"Title"
)
Conditional rendering
This one is also fairly simple: it allows you to conditionally render a sub-tree of the DOM. It is based on the way in which the
logical operators work in JavaScript with non-boolean values.
Property enumeration
This can be easily used when you either have an array property or you obtain an array somehow (e.g. using a
split
) and you want to render a DOM subtree for each array element.
(the control has a property string[]
images
with the value
["a.png", "b.png", "c.png"]
)
Child control enumeration
When you have multi-cardinality aggregations, you will inevitably want to render each child control in a loop:
(the control has an aggregation
right
containing three child controls)
Dynamic CSS class name
This is fairly useful when you dynamically add a class based on the value of a property (or some other condition). This could be used to achieve an effect similar to the standard
ToolbarDesign mechanism.
(the control has a string property
icon
)
Dynamic CSS class toggle
Whenever your control can be in two different states that differ by merely the presence of a CSS class, you can do the following:
(the control has a boolean property
active
)
Further examples
If you want to see more fleshed-out examples like the following control:
Then you can check out these two repositories on GitHub: