Two optional scripts, validate.js and process.js, cover anything a form's declarative validation rules or a block's inline template can't - both plain JavaScript via flutter_js, edited via the Script Editor. Neither is required - a project with no cross-field checks and no conditional layout content doesn't need either file.

The processing pipeline

Hitting Generate on Fill Out a Form runs, in this exact order:

  1. Static validation - the form's own required/min/max/regex rules (see the Form Editor). Stops here if anything fails.
  2. validate.js - cross-field validation. Stops here if it writes any errors.
  3. process.js - layout assembly: decides which layout partials to include, and can prepare presentation data for blocks to use.
  4. Render - the assembled layout is drawn onto the page canvas and saved to the project's output/ folder.

Nothing about a submission is saved anywhere except the generated PDF itself - see Document Project Structure.

Conditions & Expressions

A block's condition property and a form's computed-field expression (see Form Editor) both use a different, simpler engine than validate.js/process.js/block templates - arithmetic and field access only, not full JavaScript:

is_certified == true
sale_price > 0
trim_level == 'Sport' || trim_level == 'Premium'
inputs['sale_price'] * 1.08

Bare field names and inputs['field_id'] bracket access both work and mean the same thing. Falsy (false, 0, "", null) hides the block or fails the condition; leaving condition off entirely always shows the block.

There's no js:-prefixed escape hatch for a condition - if you need something more complex than this syntax allows, that belongs in validate.js (rejecting the submission) or a {...} block template segment (formatting for display), not in condition.

Where each engine applies

It's easy to mix these up since they all look like "put a formula here" - here's the actual split:

Where Engine What it can do
validate.js, process.js Real JavaScript (flutter_js) Anything - loops, method calls, string building
A block's text/data inside {...} (or a grid's data, unwrapped) Real JavaScript (flutter_js) Same as above, evaluated fresh per block at render time
A block's condition The expressions package Arithmetic, comparisons, field access only - no method calls
A computed field's expression in form.json The expressions package Same restricted syntax as condition