Conditional Logic
Sometimes a document should not read exactly the same way every time. An offer letter might need an extra paragraph only for remote employees. An invoice should only show a discount line if a discount actually applies. Conditional logic is what makes a template smart enough to include or leave out content automatically, based on the answers given on the form.
This page explains the different levels of conditional logic available, from hiding a whole section of a document down to hiding a single word or phrase. You do not need to memorize all of it. Skim the level you need, copy the pattern, and adjust the field names to match your template.
Every pattern on this page has a matching example in the Lab. Click Examples there and load Conditional Logic, If / Elsif / Else Chain, Ternary Shorthand, Repeating List / Table, or Grouped Fields + AND/OR to load it straight into the editor, fill out the generated form, and see the finished document update in real time.
A simple example first
Here is a short example before the details. This paragraph in a template:
{{#if shippingSpeed == "express"}}
Your order ships within 24 hours with expedited shipping.
{{#else}}
Your order ships within 3-5 business days with standard shipping.
{{/if}}
means: "If the shipping speed answer on the form is 'express,' print the
first sentence. Otherwise, print the second sentence." Only one of the two
ever appears in the finished document. shippingSpeed is just an ordinary
question on the form, such as a dropdown the person filling it out picks
from themselves.
How Formaliq reads a template
When a document is generated, Formaliq works through a template in two passes:
- First, it decides what to keep and what to remove, working through
{{#if}}blocks (which can wrap paragraphs, whole tables, or images). - Then, it fills in the placeholders that are left, including generating table rows for any repeating lists.
Because removal happens first, you do not need to worry about a placeholder being left empty inside a block that gets hidden entirely. If the block is removed, nothing inside it is ever looked at.
Hiding a whole section or a whole table
Use {{#if}} / {{/if}} for this too, the same tag that hides a
paragraph can wrap several paragraphs, an image, or an entire table, and
Formaliq removes (or keeps) all of it as one unit. Put the opening and
closing tags on their own line, immediately before and after the content:
{{#if showLegalSection}}
[Any document content: paragraphs, tables, images]
{{/if}}
{{#if wantsItemizedPricing}}
| Product | Price | Description |
| A | $100 | Product A |
| B | $200 | Product B |
{{/if}}
If the condition is not true on the form, everything between the two tags is left out of the finished document, whole table included.
{{#if}} can show or hide an entire table, but there is currently no way to
show or hide just one row while keeping the rest of the table. If you need
a row to appear only sometimes, the closest options are to build a repeating
list (below), which only creates rows for the entries actually filled in, or
to accept that the row is either always there or the whole table is hidden.
Repeating rows for a list of items
Some tables need one row per item in a list, such as invoice line items,
rather than a fixed number of rows. For this, add placeholders using the
list's name followed by a field name, such as {{items.name}} and
{{items.price}}, inside a single table row. Formaliq treats that row as
the pattern and automatically creates one copy of it for every item
submitted on the form, filling in each copy with that item's answers. You
do not need any extra start/end tags around the row, and the row does not
need a matching {{#if}}, just placing the list's placeholders in the row
is enough.
| Product | Category | Price |
| {{items.name}} | {{items.category}} | {{items.price}} |
If someone submits three items on the form, the finished document has three rows built from that one template row.
Choosing between a few paragraphs
Use if, elsif, and else when you want the document to say one of
several different things depending on an answer, similar to the simple
example at the top of this page.
{{#if shippingSpeed == "express"}}
Dear {{clientName}},
You selected expedited shipping. Your order will ship within 24 hours and
arrive within 2 business days.
{{#elsif shippingSpeed == "standard"}}
Dear {{clientName}},
You selected standard shipping. Your order will ship within 3-5 business
days.
{{#else}}
Dear {{clientName}},
Thank you for your order. We'll confirm a shipping method with you shortly.
{{/if}}
shippingSpeed here is simply a dropdown question on the form (for
example, with choices like "express," "standard," and left blank), the
person filling out the form picks one, and Formaliq uses that answer to
choose which paragraph to print.
Formaliq checks each condition in order and uses the first one that matches.
If none of them match, it falls back to whatever is inside else.
Hiding a single word or phrase
For small changes within a sentence, rather than a whole paragraph, use an inline condition.
Either/or phrasing, using a question mark and colon:
{{hasDiscount ? "Your discount code is on file" : "No discounts available"}}
{{wantsBulkDiscount ? "Bulk Order Discount Applied" : "Standard Pricing"}}
{{field ? "yes" : "no"}} only works with a single field name before the
?, checked for truthiness the same way a plain {{#if field}} is (see
Writing the condition itself below). It
does not support a comparison like orderCount > 5 or shippingSpeed == "express" in that spot. If you need a comparison, use a yes/no question
(a toggle or boolean field) that's already set to the right answer, or fall
back to a full {{#if comparison}}...{{#else}}...{{/if}} block instead.
See Choosing between a few paragraphs.
Include this phrase only if true, otherwise say nothing:
Dear {{customerName}}, {{#if hasSpecialOffer}}don't miss our limited time offer!{{/if}}
Writing the condition itself
Every example above depends on a condition, such as shippingSpeed == "express". Conditions are built from comparisons and, optionally, combined
with AND / OR / NOT logic.
Comparisons:
| Symbol | Meaning |
|---|---|
== | is equal to |
!= | is not equal to |
> | is greater than |
< | is less than |
>= | is greater than or equal to |
<= | is less than or equal to |
>, <, >=, and <= only work on number and date fields. Use == or
!= when comparing text or a yes/no answer.
Combining conditions:
| Symbol | Meaning |
|---|---|
&& | both conditions must be true (AND) |
|| | at least one condition must be true (OR) |
! | reverses a condition (NOT) |
{{#if age >= 55 && state == "CA"}}
Eligible for the California senior pricing
{{/if}}
{{#if quantity >= 10 || wantsBulkDiscount}}
A bulk order discount has been applied to this order
{{/if}}
age, state, quantity, and wantsBulkDiscount are each their own
separate question on the form (a number, a dropdown, a number, and a yes/no
toggle) that the person filling it out answers directly.
Stick to one kind of combination per condition (either && comparisons or
|| comparisons, not both mixed together in the same {{#if}}). Mixing
AND and OR in a single condition isn't evaluated in a reliable order today,
so split it into a nested {{#if}} instead if you need both.
Referring to a field inside a group
Some questions on a form bundle several related answers into one group, such as a single "address" question that collects a street, city, state, and zip code together (see Placeholders). To check one part of a grouped answer, reach into it using a period between the group's name and the part you want:
{{#if shippingAddress.state == "CA"}}
California residents: sales tax has been added below.
{{/if}}
A full example
This example combines every level above into one template excerpt. Every
placeholder here (shippingSpeed, clientName, shippingAddress,
orderTotal, and items) is its own separate question on the form:
{{#if shippingSpeed == "express"}}
EXPEDITED ORDER
===============
{{/if}}
Invoice for: {{clientName}}
{{shippingAddress}}
{{#if shippingSpeed == "express"}}
Shipping Method: Express (1-2 business days)
Express Shipping Fee: $25
{{#else}}
Shipping Method: Standard (3-5 business days)
Standard Shipping: Free
{{/if}}
| Item | Quantity | Price | Total |
| {{items.name}} | {{items.quantity}} | {{items.price}} | {{items.total}} |
{{#if orderTotal > 1000}}
Thank you for your large order! A 5% loyalty credit has been applied.
{{/if}}
For an order with express shipping and a total over $1,000, the finished document includes the expedited banner, the express shipping method line, the express fee note, and the loyalty credit note. For every other order, none of those four things appear, and there are no blank lines or gaps left behind where they would have been. The item table generates one row for every item submitted on the form, regardless of shipping speed.
A few tips
- Name fields clearly.
shippingSpeedis easier to work with later thanfield3. - Be specific in comparisons. Write
shippingSpeed == "express"rather than justshippingSpeed, so it is clear exactly what you are checking for. - Test the edge cases. Before relying on a template, try generating a document where an optional field was left blank, to make sure nothing looks wrong.
- Keep start and end tags on their own line.
{{#if}}and{{/if}}should each be the only thing on their line, especially when wrapping a table or several paragraphs, so Formaliq can cleanly tell what's inside the block.