Handlebars - Advanced: How to Print all Repeatable Section Entries in a Table

 Note: This feature is a limited release for clients using Version 2 forms. 

This article is about using Handlebars to reference questions in custom PDF, Word, and HTML documents.  We recommend reading about Basic Question References and Advanced Question References before trying this. 

 

About

Repeatable sections allow you to add multiple entries for the same set of questions, as many times as a user needs to.   In documents, Repeatable sections are typically printed out in a table.  This article explains how to do this most efficiently. 

We will print out the below example into a document from a simple Repeatable Section. 

 

 

Example Form

Here is a form with a Repeatable Section (which collects Today's Date, and the Hours Worked).   Only one entry to the repeatable section is shown here to save on space. 

One "row" in the above data structure is one repeatable section entry.  You will want to loop through the rows to print them all.   In the example below, we will print each "row" in the repeatable section into its own row in the table.  This will work whether you enter 1 or 30 entries into the repeatable section. 

HTML and Handlebars Example:

<table>

<!-- Below are the column headers -->
<thead>
<tr>
<th>Date</th>
<th>Hours</th>
</tr>
</thead>

<tbody>
<!-- This "each" is the beginning of the loop -->
{{#each dataRecord.pages.HoursWorked.sections.Timesheet.rows}}

<!-- Below is a table row and cells, with the question references (starting AFTER the rows container)-->
<tr>
<td>{{pages.Timesheet.sections.TimesheetSection.answers.TodaysDate.values.[0]}}</td>
<td>{{pages.Timesheet.sections.TimesheetSection.answers.Hoursworked.values.[0].display}}</td>
</tr>

<!-- This is the end of the loop-->
{{/each}}

</tbody>
</table>

 

Document Output Example:


How does it work?
 

The #each helper tells the document, for each "row" that it finds in the Repeatable section, to print out a table row containing the two cells with the question references.  When it is done with one "row", it loops back and starts work on the next row, until all rows have been printed. 

 

 

 

Was this article helpful?
2 out of 2 found this helpful
Have more questions? Submit a request

Comments

  • Avatar
    Pierre Lamarche

    I'm using Handlebars to generate JSON custom documents. Site https://handlebarsjs.com/guide/builtin-helpers.html#each mentions there are @first and @last variables available within #each loops. I use @last to detect the last object in an array and not insert a comma after it. However (a) those variables are not mentioned here (b) they are available but in what seems to be a non-standard way.

    I tried http://tryhandlebarsjs.com/ to test my templates against JSON data from a form submission. The following fragment loops through pages, sections and answers to show how Handlebars sees the data, especially @variables


    <pages>  {{! Show labels and names from all pages and sections (XML for readability) }}
    {{#each dataRecord.pages}}
      <page index="{{@index}}" key="{{@key}}" label="{{this.label}}" name="{{this.name}}">
      {{#each this.sections}}
        <section index="{{@index}}" key="{{@key}}" type="{{this.type}}" label="{{this.label}}" name="{{this.name}}" first="{{@first}}" last="{{@last}}">
        {{#each this.answers}}    {{! code for repeatable sections omitted for simplicity }}
          <answer index="{{@index}}" key="{{@key}}" label="{{this.label}}" value="{{this.values.[0]}}"></answer>
        {{/each}}
      </section>
      {{/each}}
    </page>
    {{/each}}

    The <section> lines show the values for @first and @last. This is the first line, showing these variables are boolean and led me to assume we could do stuff like {{#if @last}}.
    <section index="0" key="NewSection" type="Flow" label="New Section" name="FLIGHT_INFO" first="true" last="false">

    But if you run the same template fragment within ProntoForms, you get this:
    <section index="0" key="NewSection" type="Flow" label="New Section" name="FLIGHT_INFO" first="first" last="">

    To test for last iteration in a #each loop, you need this (it inserts comma if not last iteration):
    {{#pf:if @last "!is" "last"}},{{/pf:if}}

    It would be nice to have a reference page from ProntoForms with the differences from the standard Handlebars (if there is such a thing).

     

  • Avatar
    Karen Cann

    Thank you for the suggestion! I will add this item to our documentation backlog. Please feel free to send your feedback directly to documentation@prontoforms.com