In this part of the tutorial we want to create a properly formatted table in a widget. This is not quite as easy as with a website because there is no classic table element. However, a table-like structure can be built up via a stack, which should meet most requirements.
The class WidgetStack
Any number of stacks can be added to a widget. Each stack is a self-contained area that can be formatted independently of the other stacks of the widget.
In order to build a table, a stack is first required, which can then hold the data of the table. As with the other elements of a widget, a widget stack is not generated directly, but by calling the .addStack method on the widget.
var stack = widget.addStack();
With this code, our widget is expanded by a stack that will contain our table.
A stack automatically arranges the added elements horizontally. The .addText method can be used to add text to a stack. If we call this method several times, our columns are automatically generated. So the following code would generate 3 columns:
stack.addText("Column 1"); stack.addText("Column 2"); stack.addText("Column 3");
Alternatively, there is also the .addImage method, with which we could display an image in the stack.
The freshly created stack now adds the three columns directly to one another, there is still some space missing between the 3 text elements. The .addSpacer method exists to create space between the elements, so our example must be adapted as follows:
stack.addText("Column 1"); stack.addSpacer(); stack.addText("Column 2"); stack.addSpacer(); stack.addText("Column 3");
The .addSpacer method inserts a flexible spacing by default; the width of the spacer is dynamically adapted to the available space. Alternatively, a fixed desired width can be specified using .addSpacer(length: number).
The above code example already leads to a first table-like structure:
Rows of the table
Unfortunately there is no explicit row element which could be used to add a new row to the stack. Therefore we have to use a simple line break to create a new line, which we can create within a string with \n:
stack.addText("Row 1\nRow 2\nRow 3"); stack.addSpacer(); stack.addText("Row 1\nRow 2\nRow 3"); stack.addSpacer(); stack.addText("Row 1\nRow 2\nRow 3");
The procedure for creating a new line is somewhat unusual at first glance. For example, in a classic HTML table the content is structured line by line, in Scriptable we generate the table column by column.
A little tip at this point: If the data is traditionally available line by line in an array object structure, the content of the array can be converted into the column text as follows (the data array contains objects with the column1 attribute):
stack.addText(data.reduce((accumulator, currentValue) => accumulator + currentValue.column1 + "\n", ""));
Formatting the table
The main way to format the table is to format the text it contains. The procedure here is analogous as described in the first tutorial for adding text to a widget using widget.addText.
The call to stack.addText returns an object of the type WidgetText, which can be formatted individually. We have 3 interesting options for this:
- .font: It is possible to assign a font object to influence the font and font size
- .textColor: The color of the text can be defined
- .textOpacity: The degree of transparency of the text can be defined
For example, a bold print could be created like this:
var text = stack.addText("Example"); text.font = Font.semiboldSystemFont(14);
Creating tables in a widget is a bit cumbersome, but basically possible. With the methods shown above, it should also be possible to implement more complex layouts and to display data clearly.
The following page is available for all kinds of questions:
Hundreds of examples can also be found here, just waiting to be tried out. You will also be happy to help with problems here.
If you like my little scriptable tutorial, I would be happy about a small tip:
You are of course free to decide how big the coffee should be 🙂