Participant list as a table
For a meeting invitation or minutes, the user enters the participants in the Forms dialog. In the document they appear as a table with name, initials and role. The number of rows follows the number of participants.
Result
- Forms dialog: list of participants; each entry with first name, last name, initials and the roles chair and minutes.
- Document: table with a header row and one row per participant, followed by a sentence with the count.
- Without participants, the content row of the table is hidden.
Building blocks
| Building block | Task in this example | Reference |
|---|---|---|
| Forms (content template) | ObjectCollection Participants with schema and result list | Forms |
| Fields (content template) | WordTableRows field ParticipantRows generates the rows; Text field ParticipantCount counts | Fields, Builder API |
| Word content template | table with a header row and one content row; bind the content row and the field | Accessing primedocs fields |
Data flow
Step 1: Forms with the list of participants
Activate the Forms document function on the content template:
<FormsConfiguration>
<Elements>
<ObjectCollection Id="Participants" Label="Teilnehmende">
<Schema>
<Text Id="FirstName" Label="Vorname" />
<Text Id="LastName" Label="Name" />
<Text Id="Alias" Label="Kürzel" />
<YesNo Id="IsLead" Label="Sitzungsleitung" />
<YesNo Id="TakesMinutes" Label="Protokoll" />
</Schema>
<Summary>
<Field Id="FirstName" />
<Field Id="LastName" />
<Field Id="Alias" />
</Summary>
</ObjectCollection>
</Elements>
</FormsConfiguration>
The labels are set directly in Label so that the configuration works without preparation. For multilingual templates, use translate-Label with a key from the global translations instead.
Why an ObjectCollection: It holds any number of entries of the same kind. Each entry has the fields of the Schema; Summary determines which of them appear in the list of the dialog.
Step 2: Fields for table rows and count
Activate the Fields document function on the content template:
<FieldsConfiguration>
<Fields>
<WordTableRows Name="ParticipantRows">
<Code><![CDATA[
function main() {
const builder = $.wordTableRows.getBuilder();
const participants = $("Forms.Participants");
for (const participant of participants) {
const roles = $.joinNonEmpty(", ",
participant.IsLead ? "Sitzungsleitung" : "",
participant.TakesMinutes ? "Protokoll" : "");
builder.append(
$.joinNonEmpty(" ", participant.FirstName, participant.LastName),
participant.Alias,
roles
);
}
return builder.build();
}
]]></Code>
</WordTableRows>
<Text Name="ParticipantCount">
<Code>
function main() {
return $("Forms.Participants").length.toString();
}
</Code>
</Text>
</Fields>
</FieldsConfiguration>
$("Forms.Participants")returns an array;for … ofwalks through every entry.IsLeadandTakesMinutesareBoolean.- Each call of
append(…)produces one row. The number of arguments corresponds to the cells of the content row from step 3 and must be the same for every call. build()is the last call. Without participants it produces no row, and the content row is hidden.ParticipantCount:.lengthis a number, aTextfield must return aString, hence.toString().
Step 3: Table in the Word template
- In the content template, create a table with two rows: a header row with the column titles name, initials and role, and an empty content row below it. The header row is not bound.
- Select the whole content row, click «Bind field» and select
ParticipantRows. primedocs creates a copy of this row for every entry; its three cells correspond to the three arguments ofappend(…). - Below the table, write a sentence such as «… persons attend the meeting.», place the cursor where the count goes and bind
ParticipantCount.
Testing
- Test the template in the template editor. In the Forms dialog, the test-data button also fills the list with sample entries. The table shows one row per entry, the sentence the matching count.
- Roles: Set both roles for one entry. The cell shows both names, separated by a comma.
- Empty list: Remove all entries. The content row is not visible in the generated document; the sentence shows
0.
Variants
Participants from a data source: Give the ObjectCollection a DataProviders block, as in the example Letter with a recipient from an address data source. Field and table stay the same.
Formatted cells: The builder also accepts FormattedText, WordContent and InlineWordContent, for example the name with the last name in bold: $.formattedText.parse("<p>{{first}} <b>{{last}}</b></p>", { first: participant.FirstName, last: participant.LastName }).
Rows in a snippet: If a WordContent snippet contains the table, its content row carries the placeholder primedocs.SnippetTableRowsPlaceholder=<Name>, and the field passes the rows in the mapping of getWordContent. See Placeholders in a WordContent snippet.
List instead of table: A Text field that joins the names with map() and join(", "). See Objects and ObjectCollections in code.
Pitfalls
| Symptom | Cause | Solution |
|---|---|---|
| The field cannot be bound | Not exactly one complete table row selected | Select the whole content row, not individual cells |
| Generation error about the number of cells | append(…) was called with a varying number of arguments | Always pass the same number of arguments, empty cells as "" |
| The table shows only the header row | No participants entered; the content row is hidden | Intended behaviour; otherwise enter entries in the Forms dialog |
| XML error when saving the configuration | < or & in the code, for example in a comparison a < b | Put the code in <![CDATA[ … ]]>, as in step 2 |
Error message about the return type of ParticipantCount | .length is a number | .toString() as in step 2 |