Advanced Report Helpers

Introduction

You use report helpers when creating templates to build FX Reports. Report helpers insert and format data on FX Reports. FieldFX supports Handlebars expressions to load data. A Handlebars expression is contained within two sets of curly braces.

Example 1. A Handlebars expression
{{labels.FX5__Price_Book__c}}

Handlebars expressions are further described and defined at https://handlebarsjs.com/.

To render data, you must combine Handlebars expressions with XML.

The Report Helpers below can be added to the XML template as XML elements if the <template> tag has an attribute of preprocess="true".

  • The preprocess converts handlebars tags written as XML elements into their equivalent handlebars syntax.

  • This allows the XML author to write in XML without having to switch back and forth to Handlebars syntax.

    <template pageSize="LETTER" pageOrientation="portrait" pageMargins="36 36 36 36" preprocess="true">
      <header>header text</header>
      <body>
        body text ...
        <group collection="FX5__Ticket_Items__z" fields="RecordType.DeveloperName">
          more text ...
        </group>
      </body>
      <footer>footer text</footer>
    </template>

    The <group> element, a report helper, will be converted to the proper Handlebars syntax during preprocessing.

  • Handlebars syntax can still be added to the XML document directly even with preprocess="true".

Helpers and Helper Categories

These categories of helpers can be used:

Category Helpers

../

We fixed an issue where the bold, italic, and underline formatting for a Report PDF wasn’t working. Those formatting controls now work when the report is made into PDF and rendered.

Field Helpers

../

Navigates to the object’s parent to access a field on the parent object.

You can chain multiple ../ together to navigate to additional levels or #filters.
Example 2. Ticket Report

Use the following code to only list ticket items with a record type of Labor, where the ticket items are marked as Billable, and where the item’s Catalog Item is categorized as Callout.

{{#filter FX5__Ticket_Items__r "RecordType.DeveloperName" is="Labor"}}
 {{#filter items "Billable__c" is=true}}
   >>{{#if ../../FX5__Category__c "==" "Callout"}}
       {{#each items}}

       {{/each}}
     {{/if}}
 {{/filter}}
{{/filter}}
  • The first filter helper excludes Ticket Items without a name value.

  • The second filter helper excludes Ticket Items that not not marked as being billable.

  • The if only includes items where the ticket item’s Catalog Item record is Callout.

    There are two ../ elements, going through a filter and a parent object to navigate to the Catalog Item record to access the Catalog Item’s Category field.
  • Add expressions inside the each helpers to specify the fields to display for each item.

Example 3. Ticket Report

Use the following code to only list ticket items with a record type of Labor, where the ticket items are marked as Billable, where the item is not hidden from reports, and where the item’s Catalog Item is categorized as Callout.

{{#filter FX5__Ticket_Items__r "RecordType.DeveloperName" is="Labor"}}
 {{#filter items "Billable__c" is=true}}
   {{#filter items "Hide_from_Report__c" is=false}}
     >>{{#if ../../../FX5__Category__c "==" "Callout"}}
         {{#each items}}

         {{/each}}
       {{/if}}
     {{/filter}}
  {{/filter}}
{{/filter}}
  • The first filter helper excludes Ticket Items without a name value.

  • The second filter helper excludes Ticket Items that not not marked as being billable.

  • The third filter helper excludes Ticket Items that are hidden from reports.

  • The if only includes items where the ticket item’s Catalog Item record is Callout.

    There are three ../ elements, going through two filters and a parent object to navigate to the Catalog Item record to access the Catalog Item’s Category field.
  • Add expressions inside the each helpers to specify the fields to display for each item.

Data Helpers

Labels (Deprecated)

The labels helper is deprecated in FieldFX.

labels pulls information based on the locale of the user, which may not be the language desired for the report. While the helper functions, it is not a means to support multi-language reports.

Inserts field names.

Field names display in the language selected in the user’s record.
Example 4. Use the following code to insert the name of the Price Book field from the Job object.
<text>{{labels.FX5__Price_Book__c}}</text>
Example 5. Use the following code to insert the name of the Customer field from the Job object.
<text>{{labels.FX5__Job__r.FX5__CustomerAccount__c}}</text>

User Profile

Description

Inserts data about the current user.

Available Fields

The userProfile helper can insert data from the following fields:

Object Field

Contact

Any field

User

Username

Full Name

Phone

Email

Time Zone

Locale

Example

Use the following code to insert data from the Full Name field on the User object

<text>{{userProfile "FullName"}}</text>

Date & Number Helpers

formatCurrency

Description

Formats currency fields.

Settings

You can set the following for the formatCurrency helper:

Setting Description

CurrencyIsoCode

Controls whether the ISO currency code displays

symbol

Controls whether the currency symbol displays

precision

Controls the number of decimal places that display after the decimal mark

separator

Controls the symbol used for the thousands separator, which separates sequences of three digits

decimal

Controls the symbol used for the decimal mark, which separates the integer and fractional parts of numbers

emptyValue

Controls what represents null values

You can’t use this option for formula or roll-up summary fields.

Functions

On the Sync 4.0 release channels, you can use the following functions inside the formatCurrency helper:

Setting Description

max

Inserts the lowest value entered in the specified field

min

Inserts the highest value entered in the specified field

Examples

Example 6. Use the following code to display monetary amounts as "12.345"
<text>{{formatCurrency Extended_Amount__c symbol="" precision="3" separator="," decimal="."}}</text>
Example 7. Use the following code to display monetary amounts as "1.234.567,89"
<text>{{formatCurrency Extended_Amount__c symbol="" precision="2" separator="." decimal=","}}</text>
Example 8. Use the following code to display monetary amounts as "€1,234.56"
<text>{{formatCurrency Extended_Amount__c symbol="€" precision="2" separator="," decimal="."}}</text>
Example 9. Use the following code to display monetary amounts as "USD 1,234.56
<text>{{CurrencyIsoCode}} {{formatCurrency FX5__Price__c symbol="" precision="2" separator="," decimal="."}}</text>
Example 10. Use the following code to display null values as blank entries
<text>{{formatCurrency Price__c symbol="" precision="2" separator="," decimal="." emptyValue=""}}</text>
Example 11. Use the following code to display null values as "0"
<text>{{formatCurrency Price__c symbol="" precision="2" separator="," decimal="." emptyValue="0"}}</text>
Example 12. Use the following code to insert geolocation data with two decimal places
<text>{{formatCurrency Geolocation__Latitude__s symbol="" precision="2" separator="," decimal="."}}{{formatCurrency Geolocation__Longitude__s symbol="" precision="2" separator="," decimal="."}}</text>
Example 13. Use the following code to insert the highest cost for a ticket item
<text>{{formatCurrency (max FX5__Ticket_Items__r "FX5__Cost__c") precision="2" separator="," decimal="."}}</text>
The max function inserts the highest cost.
Example 14. Use the following code to define empty values as 99.99% for the` FX5Discount_Percentc` on ticket items
{{formatPercent FX5__Discount_Percent__c decimalPlaces="2" emptyValue= "99.99%"}}
The emptyValue inserts 99.99% when the value of the field is 0.00 (null).

formatDate

Description

Formats date fields.

Settings

You can set the following for the formatDate helper:

Setting Description

format

Controls the format of the date.

If you don’t specify a format, the date uses a standard format.

Refer to the Moment.js documentation for valid date formats.

locale

Controls the locale used for the date:

  • If you specify a locale, the date displays based on the specified locale.

  • If you don’t specify a locale, the date displays based on the user’s locale setting.

Functions

On the Sync 4.0 release channels, you can use the following functions inside the formatDate helper:

Setting Description

max

Inserts the latest end date entered in the specified field.

min

Inserts the earliest start date entered in the specified field.

Examples

Example 15. Use the following code to display dates as "Jan 1st 17"
<text>{{formatDate FX5__Ticket_Date__c format="MMM Do YY"}}</text>
Example 16. Use the following code to display dates as "01.01.2017" and set German (de) as the locale
<text>{{formatDate FX5__Ticket_Date__c format="L" locale="de"}}</text>
Example 17. Use the following code to insert the earliest start date and latest end date for a ticket item
<text>{{formatDate (min FX5__Ticket_Items__r "FX5__Date_Start__c")}} to {{formatDate (max FX5__Ticket_Items__r "FX5__Date_End__c")}}</text>
The min function inserts the earliest start date and the max function inserts the latest end date.

formatDateTime

Description

Formats date/time fields.

Settings

You can set the following for the formatDateTime helper:

Functions

On the Sync 4.0 release channels, you can use the following functions inside the formatDateTime helper:

Setting Description

max

Inserts the earliest start date/time entered in the specified field.

min

Inserts the latest end date/time entered in the specified field.

Examples

Example 18. Use the following code to display dates and times as "January 1st 2017, 1:00 PM"
<text>{{formatDateTime FX5__Ticket_Date__c format="MMMM Do YYYY, h:mm A"}}</text>
Example 19. Use the following code to display dates and times as "01/01/17 8:30"
<text>{{formatDateTime FX5__Ticket_Date__c format="MM/DD/YY h:mm"}}</text>
Example 20. Use the following code to display dates and times as "01/01/2017 08:30", with times in 24-hour format
<text>{{formatDateTime FX5__Ticket_Date__c format="MM/DD/YYYY HH:mm"}}</text>
Example 21. Use the following code to display dates and times as "1. January 2017 09:30 Uhr" and set German (de) as the locale
<text>{{formatDateTime FX5__Ticket_Date__c format="LLL" locale="de"}}</text>
Example 22. Use the following code to insert the earliest start date/time and latest end date/time for a ticket item
<text>{{formatDateTime (min FX5__Ticket_Items__r "FX5__Date_Start__c")}} to {{formatDateTime (max FX5__Ticket_Items__r "FX5__Date_End__c")}}</text>
The min function inserts the earliest start date/time and the max function inserts the latest end date/time.

formatPercent

Description

Formats percentage fields.

Settings

You can set the following for the formatPercent helper:

Setting Description

decimalPlaces

Controls the number of decimal places that display after the decimal mark.

emptyValue

Controls what represents null values.

You can’t use this option for formula or roll-up summary fields.

Functions

On the Sync 4.0 release channels, you can use the following functions inside the formatPercent helper:

Setting Description

max

Inserts the earliest percentage entered in the specified field.

min

Inserts the latest percentage entered in the specified field.

Examples

Example 23. Use the following code to display percentages as "50%"
<text>{{formatPercent FX5__Discount_Percent__c decimalPlaces=0}}</text>
Example 24. Use the following code to display percentages as "50.00%"
<text>{{formatPercent FX5__Discount_Percent__c decimalPlaces=2}}</text>
Example 25. Use the following code to insert the highest discount percentage for a ticket item
<text>{{formatDateTime (max FX5__Ticket_Items__r "FX5__Date_End__c")}}</text>
The max function inserts the highest discount percentage.

formatTime

Description

Formats time fields.

  • The time contains no date, so numbers greater than 24 or less than 0 roll around to a value between 0 and 24.

  • Salesforce Classic displays time according to the user’s locale settings. Lightning Experience and Salesforce Mobile display time as GMT.

Settings

You can set the following for the formatTime helper:

Setting Description

format

Controls the format of the time. If you don’t specify a format, the time uses a standard format.

Refer to the Moment.js documentation for valid time formats.

locale

Controls the locale used for the time:

  • If you specify a locale, the time displays based on the specified locale.

  • If you don’t specify a locale, the time displays based on the user’s locale setting.

Examples

Example 26. Use the following code to display dates and times as "1:00 PM"
<td>{{formatTime Time__c format="h:mm A"}}</td>

Geolocation Helper

Description

  • Geolocation fields are handled as a part of the formatCurrency number helper.

  • Call Latitude and Longitude separately with two different settings:

    Setting Description

    Geolocation__Latitude__s

    Calls the latitude portion of a geolocation field

    Geolocation__Longitude__s

    Calls the longitude portion of a geolocation field.

Example

Example 27. Use the following code to insert geolocation data with two decimal places
<text>{{formatCurrency Geolocation__Latitude__s symbol="" precision="2" separator="," decimal="."}}{{formatCurrency Geolocation__Longitude__s symbol="" precision="2" separator="," decimal="."}}</text>

Math Helpers

You can use these math helpers:

avg

Description

Inserts the average of a field in a collection.

Settings

You can set the following for the avg helper:

Setting Description

precision

Controls the number of decimal places that display after the decimal mark.

separator

Controls the symbol used for the thousands separator, which separates sequences of three digits.

decimal

Controls the symbol used for the decimal mark, which separates the integer and fractional parts of numbers.

Examples

Example 28. Use the following code to insert the average Discounted Price for all ticket items
 <text>{{avg FX5__Ticket_Items__r "Discounted_Price__c" precision="2" separator="," decimal="."}}</text>
Example 29. Use the following code to insert the average discount percentage for all ticket items on a job.
 {{#collect FX5__Tickets__r "FX5__Ticket_Items__r"}}
   <text>${{avg items "FX5_Discount_Percent__c" precision="2" separator="," decimal="."}}</text>
 {{/collect}}
The collect helper builds the collection of ticket items.

formula

Description

Inserts the calculated value of a formula.

  • Use the round function or formatCurrency helper to set the number of decimal places for calculated values.

  • If you are unable to insert a value using the formula helper, add a formula field to calculate the value and reference that field on the report instead.

  • Refer to the Formulas article for a full list of supported functions and operators.

Examples

Example 30. Use the following code to insert a value calculated by multiplying two field values (Price & Qty)
 <text>{{formula "round({0} * {1},2)" FX5__Price__c Qty__c}}</text>
The round function inserts the calculated value with two decimal places.
Example 31. Use the following code to insert a value calculated by dividing a subexpression by a number (ten)
<text>{{formatCurrency (formula "{0} / 10" (sum FX5__Ticket_Items__r "Extended_Amount__c" )) precision="2" separator="," decimal="."}}</text>
The formatCurrency helper inserts the calculated value in "1,234.56" format.
Example 32. Use the following code to insert a value calculated by subtracting two calculated values
<text>${{formatCurrency (formula "{0} - {1}" (sum FX5__Ticket_Items__r "FX5__Price__c") (sum FX5__Ticket_Items__r "Discounted_Price__c")) precision="2" separator="," decimal="."}}</text>
The subexpressions let you calculate the total price and total discounted price of items in the collection.
The formatCurrency helper inserts the calculated value in "1,234.56" format.
Example 33. Use the following code to insert data if there is a value in one of three designated fields
{{#if (formula "!ISBLANK({0}) || !ISBLANK({1}) || !ISBLANK({2})" O2_ppmV_Outlet__c NH3_Ammonia_ppmV_Outlet__c Ethylbenzene_Outlet__c)}}
  <text>Special Readings</text>
  <text>SO2 ppmV: {{formatCurrency SO2_ppmV_Outlet__c precision="2" separator="," decimal="."}}</text>
  <text>NH3 / Ammonia ppmV: {{formatCurrency NH3_Ammonia_ppmV_Outlet__c precision="2" separator="," decimal="."}}</text>
  <text>Ethylbenzene ppmV: {{formatCurrency Ethylbenzene_Outlet__c precision="2" separator="," decimal="."}}</text>
{{/if}}
The subexpressions return calculated values inside the if helper expression.
Example 34. Use the following code to highlight in gray every other row
{{#each items}}
{{#if (formula "MOD({0}, 2) = 1" @position)}}
<row>
<cell fillColor="lightgrey"></cell>
</row>
{{else}}
<row>
<cell></cell>
</row>
{{/if}}
{{/each}}

sum

Description

Inserts totals for fields in a collection.

Settings

You can set the following for the sum helper:

Setting Description

precision

Controls the number of decimal places that display after the decimal mark.

separator

Controls the symbol used for the thousands separator, which separates sequences of three digits.

decimal

Controls the symbol used for the decimal mark, which separates the integer and fractional parts of numbers.

roundEach (optional)

Rounding applies to each value before a result is determined.

To only round the result, set this helper to False.

Examples

Example 35. Use the following code to insert the total Extended Amount for all ticket items.
<text>{{sum FX5__Ticket_Items__r "Extended_Amount__c" precision="2" separator="," decimal="."}}</text>
Example 36. Use the following code to insert the total Extended Amount for all ticket items.
{{#collect FX5__Tickets__r "FX5__Ticket_Items__r"}}
  <text>${{sum items "Extended_Amount__c" precision="2" separator="," decimal="."}}</text>
{{/collect}}
Example 37. Use the following code to return results where rounding is not done until the result is calculated
{{sum items "Total_Hours__c" precision="1" separator="," decimal="." roundEach="false" }}
The roundEach setting overrides the default of rounding each value before calculating result.
When set to False, each value retains its full precision for the sum helper function, then the total is rounded.

Logical Helpers

You can use these logical helpers:

collect

Description

Builds a collection of items so that you can insert data for that collection. This helper is ideal for inserting totals for tickets and ticket items on job reports.

Data Variables

You can use the following data variable inside the collect helper:

Option Description

@root

Returns you to the root context for a data collection.

Examples

Example 38. Use the following code to insert the total Extended Amount for all ticket items.
{{#collect FX5__Tickets__r "FX5__Ticket_Items__r"}}
  <text>${{sum items "Extended_Amount__c" precision="2" separator="," decimal="."}}</text>
{{/collect}}
Example 39. Use the following code to insert the Ticket Log entries for all tickets.
{{#collect FX5__Tickets__r "FX5__Ticket_Logs__r"}}
  {{#sort items "FX5__Start_Time__c"}}
    <text>{{Tracking_Number__c}}</text>
    <text>{{FX5__Category__c}}</text>
    <text>{{formatDateTime FX5__Start_Time__c format="MM/DD/YY h:mm A"}}</text>
    <text>{{formatDateTime FX5__Stop_Time__c format="MM/DD/YY h:mm A"}}</text>
    <text>{{FX5__Comments__c}}</text>
  {{/sort}}
{{/collect}}
The sort helper sorts the Ticket Log entries in chronological order by start date/time.

each

Description

Inserts the items in a collection for the specified object.

Data Variables

You can use the following data variable inside the each helper:

Option Description

@root

Returns you to the root context for a data collection.

Iteration Variables

Option Description

@first

Returns TRUE for the first item in a list.

@index

Returns the index number of an item in a list.

@last

Returns TRUE for the last item in a list.

@position

Returns the position number of an item in a list.

Examples

Example 40. Use the following code to insert the ticket items on each ticket for a job
{{#each FX5__Tickets__r}}
{{#each FX5__Tickets_Items__r}}

{{/each}}
{{/each}}
Add expressions inside the each helper to specify the fields to display for each item.
Example 41. Use the following code to insert a collection of labor ticket items
{{#filter FX5__Ticket_Items__r "RecordType.DeveloperName" is="Labor"}}
{{#each items}}

{{/each}}
{{/filter}}
The filter helper excludes non-labor items.
Add expressions inside the each helper to specify the fields to display for each item.
Example 42. Use the following code to insert a collection of ticket items with sequential item numbers starting at 0
{{#each items}}
  <row>
    <cell>{{@index}}</cell>
    <cell>{{FX5__Description__c}}</cell>
    <cell>{{Qty__c}}</cell>
    <cell>{{FX5__Price__c}}</cell>
    <cell>{{FX5__Discount_Percent__c}}</cell>
    <cell>{{Extended_Amount__c}}</cell>
  </row>
{{/each}}
The {{@index}} iteration variable inserts the item numbers.
Example 43. Use the following code to insert a collection of ticket items with sequential item numbers starting at 1
{#each items}}
  <row>
    <cell>{{@position}}</cell>
    <cell>{{FX5__Description__c}}</cell>
    <cell>{{Qty__c}}</cell>
    <cell>{{FX5__Price__c}}</cell>
    <cell>{{FX5__Discount_Percent__c}}</cell>
    <cell>{{Extended_Amount__c}}</cell>
  </row>
{{/each}}
The {{@position}} iteration variable inserts the item numbers.
Example 44. Use the following code to insert data from an FX Form
{{#each JSAs__r}}

{{/each}}
JSAs__r is the plural label for the FX Form object.
Add expressions inside the each helper to specify the fields to display from the FX Form.
Example 45. Use the following code to insert data from a child FX Form onto a report for the parent FX Form
{{#each Pipe_Heads__r}}

{{/each}}
Pipe_Heads__r is the Child Relationship Name for the Master-Detail field on the child FX Form object.
Add expressions inside the each helper to specify the fields to display from the child FX Form.
Example 46. Use the following code to insert crew planning data for a job
{{#each FX5__Crew_Planning__r}}

{{/each}}
Add expressions inside the each helper to specify the fields to display for each crew planning record.
Example 47. Use the following code to insert equipment planning data for a job
{{#each FX5__Job_Equipment__r}}

{{/each}}
Add expressions inside the each helper to specify the fields to display for each equipment planning record.

filter

Description

Filters the items in a collection by a specified parameter, such as a field or record type.

Consider writing a filter used in conjunction with an if helper in the formula setting of the if helper.

Data Variables

You can use the following data variable inside the filter helper:

Option Description

@root

Returns you to the root context for a data collection.

Examples

Example 48. Use the following code to exclude non-labor ticket items
{{#filter FX5__Ticket_Items__r "RecordType.DeveloperName" is="Labor"}}
{{#each items}}

{{/each}}
{{/filter}}
Add expressions inside the each helper to specify the fields to display for each item.
Example 49. Use the following code to insert the total number of labor ticket items
{{#filter FX5__Ticket_Items__r "RecordType.DeveloperName" is="Labor"}}
  <text>Count: {{items.length}}</text>
{{/filter}}
The items.length expression inserts the ticket item count.
Example 50. Use the following code to exclude ticket items with an Extended Amount of $0.00
{{#filter FX5__Ticket_Items__r "Extended_Amount__c" not=0}}
{{#sort items "FX5__Price__c" desc=true}}

{{/sort}}
{{/filter}}
The sort helper sorts the ticket items in descending numerical order by Price.
Add expressions inside the sort helper to specify the fields to display for each item.
Example 51. Use the following code to exclude ticket items that aren’t parent or child items
{{#filter FX5__Ticket_Items__r "FX5__Parent_Ticket_Item__c" is=null}}
  {{#if items.length}}
    {{#each items}}

      {{#filter @root.FX5__Ticket_Items__r "FX5__Parent_Ticket_Item__c" is=Id}}
        {{#each items}}

        {{/each}}
      {{/filter}}
    {{/each}}
  {{/if}}
{{/filter}}
The first filter helper excludes non-parent items.
The second filter helper uses the @root variable to return to an unfiltered list of items and then excludes non-child items.
The if helper inserts the block only if there are parent and child items on the ticket.
Add expressions inside the each helpers to specify the fields to display for each item.
Example 52. Use the following code to include tickets in the "Ready for Signature" status and "Equipment" ticket items only
{{#filter FX5__Tickets__r "FX5__Status__r.Name" is="Ready for Signature"}}
  {{#collect items "FX5__Ticket_Items__r"}}
    {{#filter items "RecordType.DeveloperName" is="Equipment"}}
      {{#each items}}

      {{/each}}
    {{/filter}}
  {{/collect}}
{{/filter}}
The first filter helper excludes tickets that are not in the "Ready for Signature" status.
The second filter helper excludes non-equipment ticket items.
The collect helper builds the collection of ticket items.
Add expressions inside the each helper to specify the fields to display for each item.

filterBy

Description

Filters the items in a collection based on a formula.

Settings

You can set the following for the filterBy helper:

Setting Description

as

Use filterBy to filter the group by a field or record type and then use as to define a different name for the field or record type you filtered by.

Limitations

This report helper is only available for reports in FieldFX Mobile.

Examples

Example 53. Use the following code to exclude ticket items with price of $0.00
{{#filterBy FX5__Ticket__Items__r "FX5__Price__c > 0"}}

{{/filterBy}}
Example 54. Use the following code to exclude ticket items that don’t have notes entered
{{#filterBy FX5__Ticket__Items__r "!ISBLANK(FX5__Notes__c)"}}

{{/filterBy}}
Example 55. Use the following code to exclude ticket items that don’t have notes entered and name the returned ticket items "ticketitems"
{{#filterBy FX5__Ticket__Items__r "!ISBLANK(FX5__Notes__c)" as="ticketitems"}}

{{/filterBy}}
Example 56. Use the following code to set an IF statement to choose which field to filter by. In this scenario, it is based on a Ticket Field value, determining if it’s the SyncID or Parent Ticket Item field
{{#filterBy FX5__Ticket_Items__r "IF(NOT(ISPICKVAL(FX5__Ticket__r.PSFX_Bundle_Children_Rollup__c, 'Hide Children')), FX5__SyncID__c, ISBLANK(FX5__Parent_Ticket_Item__c))"}}
{{/filterBy}}

group

Description

Groups the items in a collection by a specified parameter, such as a field or record type.

When you group items by a field, you must complete that field for each item. Failure to do so will result in you not being able to load the report.

Settings

You can set the following for the group helper:

Setting Description

desc=false

Use to sort items in ascending order (from lowest to highest)

desc=true

Use to sort items in descending order (from highest to lowest)

Data Variables

You can use the following data variable inside the group helper:

Option Description

@root

Returns you to the root context for a data collection.

Iteration Variables

You can use the following iteration variables inside the group helper:

Option Description

@first

Returns TRUE for the first item in a list

@index

Returns the index number of an item in a list

@last

Returns TRUE for the last item in a list

@position

Returns the position number of an item in a list

Examples

Example 57. Use the following code to group ticket items by record type.
{{#group FX5__Ticket_Items__r "RecordType.DeveloperName"}}
  {{#each items}}

  {{/each}}
{{/group}}
Add expressions inside the each helper to specify the fields to display for each item.
Example 58. Use the following code to group ticket items by record type and sort them by record type.
{{#group FX5__Ticket_Items__r "RecordType.DeveloperName" sortBy="RecordType_DeveloperName" desc=false}}
  {{#each items}}

  {{/each}}
{{/group}}
The sortBy and desc settings sort the items in ascending alphabetical order by record type.
Add expressions inside the each helper to specify the fields to display for each item.
Example 59. Use the following code to group labor ticket items by employee.
{{#filter FX5__Ticket_Items__r "RecordType.DeveloperName" is="Labor"}}
  {{#group items "FX5__Contact__r.Name"}}
    {{#each items}}

    {{/each}}
  {{/group}}
{{/filter}}
The filter helper excludes non-labor items.
Add expressions inside the each helper to specify the fields to display for each employee.
Example 60. Use the following code to group labor ticket items by employee, arranged in order of clock in and clock out times when multiple items are found for the same employee.
{#filter FX5__Ticket_Items__r "RecordType.DeveloperName" is="Labor"}}
  {{#group items "FX5__Contact__c Clock_In__c Clock_Out__c"}}
    {{#each items}}

    {{/each}}
  {{/group}}
{{/filter}}
The filter helper excludes non-labor items.
Add expressions inside the each helper to specify the fields to display for each employee.

if

Description

Inserts data conditionally.

Settings

You can set the following for the if helper:

Setting Description

formula

Use "formula" to define an expression as the criteria for the if statement.

This reduces the use of the filter helper, as you add the formula directly to the if helper instead.

Operators

You can use the following operators inside the if helper:

Operator Description

==

Evaluates whether two values are equal

!=

Evaluates whether two values aren’t equal

<

Evaluates whether a value is less than the value that follows this symbol

>

Evaluates whether a value is greater than the value that follows this symbol

Evaluates whether a value is less than or equal to the value that follows this symbol

>=

Evaluates whether a value is greater than or equal to the value that follows this symbol

&&

Evaluates whether two values or expressions are both true

||

Evaluates whether at least one of multiple values or expressions is true

Data Variables

You can use the following data variable inside the if helper:

Option Description

@root

Returns you to the root context for a data collection

Iteration Variables

You can use the following iteration variables inside the if helper:

Option Description

@first

Returns TRUE for the first item in a list

@index

Returns the index number of an item in a list

@last

Returns TRUE for the last item in a list

@position

Returns the position number of an item in a list

Examples

Example 61. Use the following code to insert notes if they exist. If no notes exist, the if helper inserts the "There are no notes available" message.
{{#if FX5__Notes__c}}
  <text>Notes: {{FX5__Notes__c}}</text>
  {{else}}
    <text>There are no notes available.</text>
{{/if}}
Example 62. Use the following code to insert a checkbox from an FX Form.
<text>Fire Protection:</text>
<text>{{#if Fire_Protection__c}}<input type="checkbox" checked>{{else}}<input type="checkbox">{{/if}}</text>
Example 63. Use the following code to insert ticket items with an Extended Amount greater than or equal to $1.00. If items have an Extended Amount below $1.00, the if helper doesn’t insert them.
{{#if Extended_Amount__c ">=" "1.00"}}
  <row>
    <cell>{{FX5__Description__c}}</cell>
    <cell>{{formatCurrency Qty__c symbol="" precision="2" separator="," decimal="."}}</cell>
    <cell>{{formatCurrency FX5__Price__c symbol="$" precision="2" separator="," decimal="."}}</cell>
    <cell>{{formatPercent FX5__Discount_Percent__c decimalPlaces="2"}}</cell>
    <cell>{{formatCurrency Extended_Amount__c symbol="$" precision="2" separator="," decimal="."}}</cell>
  </row>
{{/if}}
Example 64. Use the following code to insert a conditional message.
{{#if (sum items "Extended_Amount__c") ">" "10000.00"}}
  <text>Over Budget</text>
  {{else}}
    <text>Under Budget</text>
{{/if}}
If the Extended Amount for all ticket items is less than $10000.00, the if helper inserts "Under Budget" onto the report.
If the Extended Amount for all ticket items is greater than $10000.00, the if helper inserts "Over Budget" onto the report.
This example uses a subexpression to return calculated values inside the if helper expression.
Example 65. Use the following code to insert data if there is a value in one of three designated fields on an FX Form.
{{#if (formula "!ISBLANK({0}) || !ISBLANK({1}) || !ISBLANK({2})" SO2_ppmV_Outlet__c NH3_Ammonia_ppmV_Outlet__c Ethylbenzene_Outlet__c)}}
  <text>SO2 ppmV: {{formatCurrency SO2_ppmV_Outlet__c precision="2" separator="," decimal="."}}</text>
  <text>NH3 / Ammonia ppmV: {{formatCurrency NH3_Ammonia_ppmV_Outlet__c precision="2" separator="," decimal="."}}</text>
  <text>Ethylbenzene ppmV: {{formatCurrency Ethylbenzene_Outlet__c precision="2" separator="," decimal="."}}</text>
{{/if}}
This example uses a subexpression to return calculated values inside the if helper expression.
Example 66. Use the following code to insert a Total Discount amount for all ticket items if there were any discounts applied. If there were no discounts applied, the if helper doesn’t insert the Total Discount amount.
{{#filter FX5__Ticket_Items__r "Discounted__c" is=true}}
{{#if items.length}}
  <text>Total Discount:</text>
  <text>{{sum items "Discount_Amount__c" precision="2" separator"," decimal="."}}</text>
{{/if}}
{{/filter}}
The filter helper excludes non-discounted items.
The sum helper calculates the total discounts applied.
Example 67. Use the following code to insert a comma between ticket item date ranges in a list but don’t add a comma after the last date range.
{{#each items}}
  <text>{{formatDate FX5__Date_Start__c format="MM/DD/YYYY"}}{{#if FX5__Date_End__c}}-{{formatDate FX5__Date_End__c format="MM/DD/YYYY"}}{{/if}}{{#if @last "==" false}}, {{/if}}</text>
{{/each}}
Example 68. Use the following code to list only ticket items in a ticket report that have a 'not labor' record type.
{{#each items}}
  <text>{{#if formula="RecordType.DeveloperName == 'Labor'"}}Labor{{else}}NotLabor{{/if}}</text>
{{/each}}

sort

Description

Sorts the items in a collection by a specified parameter, such as a field or record type.

Settings

You can set the following for the sort helper:

Setting Description

desc=false

Use to sort items in ascending order (from lowest to highest)

desc=true

Use to sort items in descending order (from highest to lowest)

Data Variables

You can use the following data variable inside the sort helper:

Option Description

@root

Returns you to the root context for a data collection

Iteration Variables

You can use the following iteration variables inside the sort helper:

Option Description

@first

Available on the Sync 4.0 release channels only.

Returns TRUE for the first item in a list

@index

Returns the index number of an item in a list

@last

Available on the Sync 4.0 release channels only.

Returns TRUE for the last item in a list

@position

Returns the position number of an item in a list

Examples

Example 69. Use the following code to insert ticket items sorted in descending numerical order by Extended Amount
{{#sort FX5__Ticket_Items__r "Extended_Amount__c" desc=true}}
  <row>
    <cell>{{FX5__Description__c}}</cell>
    <cell>{{formatCurrency Qty__c symbol="" precision="2" separator="," decimal="."}}</cell>
    <cell>{{formatCurrency FX5__Price__c symbol="$" precision="2" separator="," decimal="."}}</cell>
    <cell>{{formatCurrency Extended_Amount__c symbol="$" precision="2" separator="," decimal="."}}</cell>
  </row>
{{/sort}}
Example 70. Use the following code to insert ticket items sorted in alphabetical order by description and insert sequential item numbers starting at 0.
{{#sort items "FX5__Description__c" desc=true}}
  <row>
    <cell>{{@index}}</cell>
    <cell>{{FX5__Description__c}}</cell>
  </row>
{{/sort}}
The @index iteration variable inserts the item numbers.
Example 71. Use the following code to insert ticket items sorted in alphabetical order by description and insert sequential item numbers starting at 1.
{{#sort items "FX5__Description__c" desc=true}}
  <row>
    <cell>{{@position}}</cell>
    <cell>{{FX5__Description__c}}</cell>
  </row>
{{/sort}}
The @position iteration variable inserts the item numbers.

unless

Description

Inserts data conditionally.

Examples

Example 72. Use the following code to insert the Price for a ticket item if the On Standby checkbox isn’t selected.
<text>{{#unless FX5__On_Standby__c}}{{FX5__Price__c}}{{/unless}}</text>
If the On Standby checkbox is selected for an item, the unless helper doesn’t insert anything.

with

Description

Puts you in the context of the specified object so you can insert data for that object.

This helper is ideal for inserting job data on ticket reports.

Examples

Example 73. Use the following code to job data.
{{#with FX5__Job__r}}
  <text>Job: {{Name}}</text>
  <text>Customer: {{FX5__CustomerAccount__r.Name}}</text>
{{/with}}
Example 74. Use the following code to insert crew planning data for a job.
{{#with FX5__Job__r}}
  {{#each FX5__Crew_Planning__r}}

  {{/each}}
{{/with}}
Add expressions inside the each helper to specify the fields to display.
Example 75. Use the following code to insert equipment planning data for a job.
{{#with FX5__Job__r}}
  {{#each FX5__Job_Equipment__r}}

  {{/each}}
{{/with}}
Add expressions inside the each helper to specify the fields to display.

Image Helpers

captureImage

Description

Inserts an interactive image placeholder. Use this placeholder to attach an image to a report, such as a photo or stamp.

Example of an signature with a customer stamp
Figure 1. The captureImage Report Helper allows you the user to attach a photo while completing a report

Settings

You can set the following for the captureImage helper:

Setting Description

maxSize

Downsizes images proportionately to have a height or width no greater than the specified pixel size

Limitations

You cannot use the captureImage helper on PDF reports.

Examples

Example 76. Use the following code to insert a 2 in x 1 in image placeholder.
<div style="width: 2in; height: 1in">{{{captureImage}}}</div>
If you insert an image that has larger dimensions than the placeholder, the image resizes to fit the space.
Example 77. Use the following code to insert a 2 in x 1 in image placeholder with a 500px size limit.
<div style="width: 2in; height: 1in">{{{captureImage maxSize="500"}}}</div>
When you specify a maximum pixel size, images downsize proportionately to have a height or width no greater than that size

Signature Helpers

signatureBlock

Description

Inserts an interactive signature line. Use this signature line to capture digital signatures.

Limitations

You can’t use the signatureBlock helper on PDF reports.

Use the <signatureBlock> element to insert signature lines on PDF reports.

Examples

Use the following code to insert a basic signature line

<div class="signature">{{{signatureBlock}}}</div>

When you insert a signature line, you also need to add CSS code to specify the style and image to use for the signature line. The image for the signature line embeds in the code using the base64 string format.

.signature {
  page-break-inside: avoid;
  position: relative;
  display: inline-block;
  margin-top: .25in;
  height: 66px;
  width: 293px;
  background-image: url(data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2Q==);
}
Example 78. Use the following code to insert a signature line with a watermark.
<div class="signature">
  <div class="signature-watermark">{{FX5__Tracking_Number__c}}</div>
  {{{signatureBlock}}}
</div>
Example of a signature line with the tracking number watermark
Figure 2. This example signature block uses the ticket tracking number as the watermark for the signature line.

When you insert a signature line with a watermark, you also need to add CSS code to specify the styles to use for the signature line and watermark. The image for the signature line embeds in the code using the base64 string format.

.signature {
  page-break-inside: avoid;
  position: relative;
  display: inline-block;
  margin-top: .25in;
  height: 66px;
  width: 293px;
  background-image: url(data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2Q==);
}
.signature-watermark {
  position: absolute;
  line-height: 3em;
  opacity: 0.25;
  font-size: 2.5em;
  width: 100%;
  text-align: center;
  pointer-events: none;
}

Advanced Helpers

We fixed an issue where the bold, italic, and underline formatting for a Report PDF wasn’t working. Those formatting controls now work when the report is made into PDF and rendered.

applyTemplate

Description

Applies Handlebars expressions to the contents of a designated value.

Examples

Example 79. Use this code to create a Job report
<?xml version="1.0" encoding="UTF-8"?>
<template pageSize="LETTER" pageOrientation="portrait" pageMargins="72 72 72 72">
  <body>
    {{applyTemplate FX5__Notes__c}}
  </body>
</template>

Copy and the past this code into the Notes field.

<text bold="true">Here is a sample of a sub-template: {{FX5__Tracking_Number__c}}</text>
Example of the report generated with the Tracking Number
Figure 3. As the example shows, the resulting text from the Notes field displays in bold text.
Example 80. Use the following code to render a localized report.

Prerequisites

  1. Create a lookup called ReportLocales.

  2. Ensure each row in ReportLocales has a Language field and a field for each label.

  3. Ensure each row contains a translation for a given language and the TandC field holds the XML with the formatting instructions for the Terms and Conditions.

<?xml version="1.0" encoding="UTF-8"?>
<template pageSize="LETTER" pageOrientation="portrait" pageMargins="72 72 72 72">
  <body>
    <text>{{Language__r.Tracking_Number__c}}: {{FX5__Tracking_Number__c}}</text>
    <text>{{Language__r.Office__c}}: {{FX5__Office__r.Name}}</text>
    <text>{{Language__r.Customer__c}}: {{FX5__CustomerAccount__r.Name}}</text>
    <stack marginTop="32">
      {{applyTemplate Language__r.TandC__c}}
    </stack>
  </body>
</template>