Skip to main content

Slots

Slots are an elementary part of Tripetto's data collection mechanism. They are defined by the form definition and denote the data that a form can collect. If you imagine a form where the data is collected in a spreadsheet, the columns in the spreadsheet are the questions asked, and the rows are the respondents. The columns in the spreadsheet are then the slots.

🎓 How slots work

In Tripetto, question types are defined by blocks. And so blocks also define the slots for a form. Each block generates the slots that it needs. All those slots combined define the data that is collected by a form. For example, a text input block will generate a single slot to hold the value of the text input field in the form.

There a different slot types for the different types of data that is collected (for example, a String, Number, or Boolean value). And, besides the slot types, there are also slot kinds. There are four different kinds of slots available:

  • static: Static slots are fixed slots that are required for the functional operation of a block (for example, a string slot that holds the text value of a text input block);
  • dynamic: Dynamic slots are used for dynamic elements in a block (for example, slots that are created for each checkbox of a block that supports a customizable list of checkboxes);
  • feature: Feature slots are used for optional features of a block (for example, a slot that holds the score value of a block that supports an optional score feature);
  • meta: Meta slots are used to store metadata (for example, the time taken to answer a block).

Now, let's consider the following example form in the builder:

It defines three blocks: A single-line text block that collects a name, then a multiple-choice block with 2 options that can be selected, and finally, a rating block that collects a number from 0 to 5. The third block also has an alias set to RATING (this is the name of the column in the spreadsheet metaphor). If we now look at the slots that are generated by these blocks, we get the following diagram:

Slots diagram

The first block generates a slot of kind static with the type String. The name of the slot is the block's name, in this case, Name. The next block has two options that can be selected or not. So this block generates two slots of kind dynamic with the type Boolean. These slots are dynamic slots because they are generated based on a flexible list of options. In this case, the builder user has added two options. So two dynamic slots are generated. The names of the slots are derived from the name of the (multiple choice) options. The last block generates a static slot of type Number. This block has an alias set, so the slot's name is derived from the alias (in this case, RATING). If this form collects data, it will generate the following spreadsheet table:

Example form data

NameOption 1Option 2RATING
Marty McFlyTrueFalse4
Doc BrownFalseFalse5

👩‍💻 Declaring slots

Slots are declared by blocks using a special method in a block class (you can choose any name you like for the method). This method needs to be decorated by the @slots decorator. The method will then be called whenever the builder wants to know the slots that are required for the block. Here is a simple example:

import { tripetto, slots, NodeBlock, Slots } from "tripetto";

@tripetto({
type: "node",
identifier: "example-block",
label: "Example",
icon: "data:image/svg+xml;base64,PHN2ZyAvPg=="
})
class ExampleBlock extends NodeBlock {
@slots
onSlots(): void {
// Let's define a slot that holds a text value
this.slots.static({
type: Slots.Text,
reference: "value",
label: "Example value"
});
}
}

It uses the slots field of the NodeBlock class to retrieve a reference to the Slots collection instance. You can use the following methods for declaring new slots:

  • static: Creates a new static slot;
  • dynamic: Creates a new dynamic slot;
  • feature: Creates a new feature slot;
  • meta: Creates a new meta slot.

Where to declare slots

The methods decorated with the @slots or @editor decorators are the only place in a block where slots can be generated. Outside of these methods, the slots field can be used to reference the available slots, but you cannot declare new slots (this will throw an error). If new slots needs to be generated as a side-effect of another field, this field needs to be decorated with @affects("#slot") decorator. This indicates the builder that whenever the value of the field changes, the slots method needs to be called so the right slots can be generated. Here is an example that implements this decorator:

import { affects, definition, editor, tripetto, slots, NodeBlock, Slots } from "tripetto";

@tripetto({
type: "node",
identifier: "date-block",
label: "Date",
icon: "data:image/svg+xml;base64,PHN2ZyAvPg=="
})
class DateBlock extends NodeBlock {
@definition
@affects("#slots")
range?: boolean;

@slots
onSlots(): void {
this.slots.static({
type: Slots.Date,
reference: "date",
label: this.range ? "From" : "Date"
});

if (this.range) {
this.slots.static({
type: Slots.Date,
reference: "to",
label: "To"
});
} else {
this.slots.delete("to");
}
}

@editor
onEdit(): void {
this.editor.option({
name: "Range",
form: {
title: "Range",
controls: [
new Forms.Checkbox(
"Enable date range",
Forms.Checkbox.bind(this, "range", undefined, true)
),
],
},
activated: isBoolean(this.range),
});
}
}

Declaring dynamic slots

It is possible to generate slots in a Collection.Item. This is useful for generating dynamic slots. For example, in the multiple choice block, a slot is generated for each option added to the list of options. See the Collections guide for more information.

📇 Slot types

The following built-int slot types are available:

info

Besides the built-in slot types, you can define a custom slot type if desired. Custom slot types are derived from the Slot abstract class and need to implement a toValue and toString method. See the Slot class API reference for more information and an example.