ATLAS FormBuilder - Text Merge Formatting (Advanced Users)
TextMergeField Formatter Usage
Text merge fields all support a ResolveForResponse
method that emits a string for use in sections, emails, pdfs, etc. However, the output for a given merge field is fixed and can't be changed or formatted differently. For example, a text merge field that outputs a date may not be formatted in the way that the form author desires. Text merge field formatters (hereafter referred to as a "formatter") are appended to the end of a merge field declaration and are used to modify the data emitted by a merge field. Here's a basic example of modifying the output of a merge field that deals with dates:
Your form was submitted on
[[FormSubmitDate]]
!
This text resolves into the following:
Your form was submitted on 2019-08-27 06:51:07 PM!
Perhaps the author didn't want to have the full date and time listed, or perhaps they did not want to have it in ISO-8601 format. In this case, the author really just wanted the day of the week to be listed. They would add a formatter declaration to the end of the merge field.
Your form was submitted on
[[FormSubmitDate]]{{ "dateFormat": "DayOfWeek" }}
!
Now, the output of the merge field would be:
Your form was submitted on Wednesday!
Formatters are not just limited to dates. Currently, a formatter can handle:
- dates
- numbers
- booleans (true/false, checked/unchecked)
- lists
- composite questions (formatting as tables)
- empty values
- alternate text when a value is present
Formatter Syntax
Formatter declarations are defined by two left curly braces ({{
) immediately following a merge field declaration with no spaces, ending with two right curly braces (}}
). The contents between the braces must be comma-separated, quoted key/value pairs with a colon separating the keys and values ("key1": "value1", "key2":"value2"
). A sample formatter declaration would be:
{{"key1": "value1", "key2":"value2"}}
Formatter Types
As mentioned above, formatters can handle different types of data in a text merge field. Some formatter properties can also be combined with others. For example, an emptyValue
formatter can be combined with most other formatter directives. All formatter directives can have nested text merge fields (with their own formatter declarations) that will be resolved if necessary.
Dates
Date formatting uses the dateFormat
and optional timeZone
directives.
dateFormat
The dateFormat
directive accepts a string that contains the text that should replace the original merge field output. This text can either be a single date format declaration, or it can have text with one or more single-quoted date format strings in it.
dateFormat
Single Date Formats
DayOfWeek
-> TuesdayMonthOfDate
-> SeptemberMonthDayYear
-> 9/3/2019StandardTime
-> 1:59 PM
dateFormat
Examples
{{"dateFormat": "DayOfWeek"}}
-> Tuesday{{"dateFormat": "yyyy-MM-dd"}}
-> 1955-11-5{{"dateFormat": "Hi there, you were born on a 'DayOfWeek' in 'yyyy'!"}}
-> Hi there, you were born on a Tuesday in 1955!{{"dateFormat": "Updated on a 'DayOfWeek' by [[FormAssociatedUser_DisplayName]]"}}
-> Updated on a Tuesday by John Smith
timeZone
The timeZone
directive is only used in combination with the dateFormat
directive. This is used to alter the time being fed into the dateFormat
directive to match a given time zone. The contents of this directive must match a tz database identifier. If no timeZone
directive is given, a time zone of America/Chicago
will be used.
timeZone
Examples
{{"dateFormat": "hh:mm tt", "timeZone": "America/Chicago"}}
-> 05:32 pm{{"dateFormat": "hh:mm tt", "timeZone": "America/New_York"}}
-> 06:32 pm{{"dateFormat": "hh:mm tt"}}
-> 05:32 pm
Numbers
Number formatting uses the numberFormat
directive.
numberFormat
The numberFormat
directive accepts a string that contains the text that should replace the original merge field output. This text can either be a single number format declaration, or it can have text with one or more single-quoted number format strings in it.
numberFormat
Examples
These examples use a source number of 42.256
{{"numberFormat": "000.0"}}
-> 042.3{{"numberFormat": "The amount of $'0.00' was paid using [[CreditCardUsed]]"}}
-> The amount of $42.26 was paid using Visa{{"numberFormat": "$'#00.0000'"}}
-> 42.2560
Boolean Values
Boolean value formatting uses the checkedValue
and uncheckedValue
directives. The checkedValue
and uncheckedValue
directives are often used together, but they can be used independently if you prefer to only modify one boolean option, leaving the other to be resolved normally by the text merge field.
checkedValue
The checkedValue
directive accepts a string that contains literal text and optional text merge fields that are inserted when the text merge field has a true
value (e.g. when a checkbox is checked).
uncheckedValue
The uncheckedValue
directive accepts a string that contains literal text and optional text merge fields that are inserted when the text merge field has a false
value (e.g. when a checkbox is unchecked).
checkedValue
and uncheckedValue
Examples
{{"checkedValue":"Thanks for selecting the option to donate.","uncheckedValue":"Sorry to see you decided not to donate, [[LastModifiedBy_FirstName]]. It's ok to call you [[LastModifiedBy_FirstName]], right?"}}
-> Sorry to see you decided not to donate, John. It's ok to call you John, right?
Empty Values
When a text merge field would return a null or empty value, an empty string is emitted. This can occur if a question doesn't have an answer, or if an attribute field doesn't resolve. In these cases, the emptyValue
can be used to substitute text.
emptyValue
The emptyValue
directive accepts a string that contains literal text and optional text merge fields that are inserted when the text merge field would emit an empty string.
emptyValue
Examples
{{"emptyValue":"No street address was given"}}
-> No street address was given{{"emptyValue":"[[Question_ValueOf:preferred_first_name]]"}}
-> Jim{{"emptyValue":"[[Question_ValueOf:last_name_also_empty]]{{ emptyValue: \"Going down the rabbit hole!\" }}"}}
-> Going down the rabbit hole!
Present Values
Sometimes, one wishes to substitute the value of a merge field with something completely different. The hasValue
merge field handles this case.
hasValue
The hasValue
directive accepts a string that contains literal text and optional text merge fields that are inserted when the text merge field would emit anything other than an empty string.
hasValue
Examples
{{"hasValue":"We shall take your output and replace it with this instead."}}
-> We shall take your output and replace it with this instead.{{"hasValue":"[[Question_ValueOf:preferred_first_name]]"}}
-> Jim{{"hasValue":"[[Question_ValueOf:last_name]]{{ \"hasValue\": \"Going down the rabbit hole!\" }}"}}
-> Going down the rabbit hole!
Both the hasValue
and the emptyValue
can also be used together.
hasValue
and emptyValue
Examples
{{"hasValue":"This question has a value, so we appreciate it, [[Question_ValueOf:preferred_first_name]]", "emptyValue":"This question has no value. Why don't you fill it in, [[Question_ValueOf:preferred_first_name]]?}}
-> This question has a value, so we appreciate it, Jim
Composite Question Formatting
Merge fields involving composite questions typically don't format the way most people would want. Using the tableFormat
and optional columns
, columnFormat
and sortBy
directives, a much clearer output can be obtained.
tableFormat
The tableFormat
directive accepts one of the following values:
Html
- the output will be formatted as an HTML table.TabDelimited
- the output will be formatted as tab-delimited fields with line breaks between each row.CommaDelimited
- the output will be formatted as comma-separated fields with line breaks between each row.FixedWidthText
- the output will be formatted as a fixed-width table suitable for display with plain-text fixed-width fonts.
tableFormat
Examples
{{"tableFormat":"Html"}}
<table class="table table-bordered"><thead><tr><th>Date Question</th><th>Number Question</th><th>Signature Question</th><th>Single Line Text</th></tr></thead><tbody><tr><td>1955-11-05</td><td>1</td><td>Signed by user1 on 1955-11-05 07:14:15 AM</td><td>single line text answer 1</td></tr><tr><td>1955-11-06</td><td>2</td><td>Signed by user2 on 1955-11-06 07:14:15 AM</td><td>single line text answer 2</td></tr><tr><td></td><td></td><td></td><td>single line text answer 3</td></tr><tr><td>1955-11-08</td><td>4</td><td>False</td><td>single line text answer 4</td></tr></tbody></table>
{{"tableFormat":"TabDelimited"}}
Date Question Number Question Signature Question Single Line Text 1955-11-05 1 Signed by user1 on 1955-11-05 07:14:15 AM single line text answer 1 1955-11-06 2 Signed by user2 on 1955-11-06 07:14:15 AM single line text answer 2 single line text answer 3 1955-11-08 4 False single line text answer 4
{{"tableFormat":"CommaDelimited"}}
Date Question,Number Question,Signature Question,Single Line Text 1955-11-05,1,Signed by user1 on 1955-11-05 07:14:15 AM,single line text answer 1 1955-11-06,2,Signed by user2 on 1955-11-06 07:14:15 AM,single line text answer 2 ,,,single line text answer 3 1955-11-08,4,False,single line text answer 4
{{"tableFormat": "FixedWidthText"}}
Date Question | Number Question | Signature Question | Single Line Text --------------|-----------------|-------------------------------------------|-------------------------- 1955-11-05 | 1 | Signed by user1 on 1955-11-05 07:14:15 AM | single line text answer 1 1955-11-06 | 2 | Signed by user2 on 1955-11-06 07:14:15 AM | single line text answer 2 | | | single line text answer 3 1955-11-08 | 4 | False | single line text answer 4
columns
The columns
directive accepts a comma-delimited list of question field names that are children of the composite question being formatted. These columns will be the only columns included in the output, and will appear in the order specified.
columns
Examples
{{"tableFormat": "FixedWidthText", "columns":"number_question,date_question"}}
Number Question | Date Question ----------------|-------------- 1 | 1955-11-05 2 | 1955-11-06 | 4 | 1955-11-08
columnFormat
The columnFormat
directive accepts a comma-delimited list of format strings specific to the data type of the sub-question. For instance, one might want to format the dates in the example date_question. This directive can only be used in conjunction with the columns
directive. A format string is not required for each column included, but there does need to be at least an empty element for each column.
columnFormat
Examples
{{"tableFormat": "FixedWidthText", "columns":"number_question,date_question", "columnFormat":"'numberFormat: \\'You ate \\\'0\\\' donuts\\'','dateFormat: \\'MM/dd/yyyy\\''"}}
Number Question | Date Question ------------------|-------------- You ate 1 donuts! | 11/05/1955 You ate 2 donuts! | 11/06/1955 | You ate 4 donuts! | 11/08/1955
{{"tableFormat": "FixedWidthText", "columns":"single_line_text,number_question,date_question", "columnFormat":",,'dateFormat: \\'MM/dd/yyyy\\''"}}
Single Line Text | Number Question | Date Question --------------------------|-----------------|-------------- single line text answer 1 | 1 | 11/05/1955 single line text answer 2 | 2 | 11/06/1955 single line text answer 3 | | single line text answer 4 | 4 | 11/08/1955
sortBy
The sortBy
directive accepts a quoted, comma-delimited list of question field names (followed by an optional ASC
or DESC
) that are children of the composite question being formatted. These columns will be used to sort the rows of each table. Note that the columns listed in the sortBy
directive do not necessarily have to be included in the output columns defined by the columns
directive, and can even be used with only the tableFormat
directive without any other directives.
sortBy
Examples
{{"tableFormat": "FixedWidthText", "sortBy":"'number_question DESC', 'date_question'"}}
Date Question | Number Question | Signature Question | Single Line Text --------------|-----------------|-------------------------------------------|-------------------------- 1955-11-08 | 4 | False | single line text answer 4 1955-11-06 | 2 | Signed by user2 on 1955-11-06 07:14:15 AM | single line text answer 2 1955-11-05 | 1 | Signed by user1 on 1955-11-05 07:14:15 AM | single line text answer 1 | | | single line text answer 3
{{"tableFormat": "FixedWidthText", "columns":"number_question,date_question", "sortBy":"'number_question DESC', 'date_question'"}}
Number Question | Date Question ----------------|-------------- 4 | 1955-11-08 2 | 1955-11-06 1 | 1955-11-05 |
{{"tableFormat": "FixedWidthText", "columns":"single_line_text,date_question", "sortBy":"'number_question DESC', 'date_question'"}}
Single Line Text | Date Question --------------------------|-------------- single line text answer 4 | 1955-11-08 single line text answer 2 | 1955-11-06 single line text answer 1 | 1955-11-05 single line text answer 3 |
List Formatting
Text merge fields that return lists of information, such as a student's StudentMajorCodes_Current
attribute, or the answers to a choice-based question like a list of checkboxes will output their values as a comma-delimited list. The listFormat
directive allows one to choose different formatting options.
listFormat
The listFormat
directive accepts one of the following values:
Bullets
- the output will be formatted as an HTML unordered (<ul>
) list. note: if the ultimate output format is plain text (such as an email), then the list will be output as a series of lines with an asterisk*
at the startUnorderedList
- same asBullets
: the output will be formatted as an HTML unordered (<ul>
) list.OrderedList
- the output will be formatted as an HTML ordered (<ol>
) list. note: if the ultimate output format is plain text (such as an email), then the list will be output as a series of lines with a number followed by a right-parenthesis)
mark at the startCommaDelimited
- the output will be formatted as comma-separated fields.TabDelimited
- the output will be formatted as tab-separated fields.
listFormat
Examples
In this example, the source question has five values. Those values are:
red
blue
green
purple
other>!
Output:
- Markdown Output:
{{"listFormat":"Bullets"}}
<ul><li>red</li><li>blue</li><li>green</li><li>purple</li><li>other>!</li></ul>
- Plain Text Output:
{{"listFormat":"Bullets"}}
* red * blue * green * purple * other>!
- Markdown Output:
{{"listFormat":"OrderedList"}}
<ol><li>red</li><li>blue</li><li>green</li><li>purple</li><li>other>!</li></ol>
- Plain Text Output:
{{"listFormat":"OrderedList"}}
1) red 2) blue 3) green 4) purple 5) other>!
{{"listFormat":"TabDelimited"}}
red blue green purple other>!
{{"listFormat":"CommaDelimited"}}
red,blue,green,purple,other>!