Web SDKv1.0.0

FormsApi

Form filling, headless — the same rules as typing into the fields. fields() and getValues() read the form and need the extract feature; setValues() writes it and needs forms (without forms, a viewer shows fields read-only). Keys are fully qualified field names, as fields()[].name gives them (topmostSubform[0].Page1[0].f1_01[0]).

With a viewer open on the document, the values go through it — shown at once, on its undo stack, in doc.save() and in viewer.createExporter()'s output alike, and formFieldChanged fires once per applied field. Without one they are written into the document itself, as a reader that typed them would: each field's value and its appearance, a formatted field shown formatted ($1,234.50) with its value as entered (1234.5), and calculated fields recalculated, so doc.save() and a viewer opened later both have them. A static XFA form, once filled, is saved as the AcroForm it is laid over.

Not available: resetting fields to their defaults, a flatten of the form alone (doc.annotations.flatten() and the export's flatten flatten everything), and FDF import. Field values travel as the <fields> of an XFDF file through exportXFDF / importXFDF. A field's rect is a Rect in page space.

namespacedoc.forms

Usage

TypeScript
const doc = await PDFDocument.fromUrl('/forms/w9.pdf');
const { rejected } = await doc.forms.setValues({
  'topmostSubform[0].Page1[0].f1_01[0]': 'Ada Lovelace',
  'topmostSubform[0].Page1[0].c1_1[0]': '1', // a check box, by its export value
});
if (rejected.length > 0) console.warn(rejected);
const filled = await doc.save();

Reading

typemethodsince 1.0.0
type(): Promise<FormType>
The kind of form the document carries, as a FormType. Only AcroForm fields are interactive. Needs no feature.
Returns Promise<FormType> 'none', 'acroform', 'xfa' or 'xfa-foreground'.
  • DOCUMENT_CLOSED — the document has been closed.
TypeScript
if ((await doc.forms.type()) === 'xfa') showNotice('Dynamic XFA forms are not interactive');
fieldsmethodsince 1.0.0
fields(pageIndex?: number): Promise<FormFieldInfo[]>
The form's fields as the document holds them — every widget with its name, type, options, the booleans its flags set and the value the file carries (a check box's or radio button's export value when on, 'Off' when off, as getValues() speaks it) — on one page, or on every page when the index is omitted. For what a viewer shows now, see getValues(). A document is read as at most 16 384 widgets: past that many, the rest of the form is left as the pages paint it, and setValues() reports those fields as unknown_field. Needs the extract feature.
ParameterTypeDescription
pageIndex?numberZero-based page index. Omit for every page.
Returns Promise<FormFieldInfo[]> Each with name, type, value, pageIndex, rect, readOnly, required, noExport, multiline, password, comb, multiSelect, hidden and, where set, options, maxLength, exportValue, dateFormat, signature, format, range, calculation, look and rotation.
  • INVALID_ARGUMENT — a page index out of range.
  • FEATURE_NOT_LICENSED — the license lacks extract.
  • DOCUMENT_CLOSED — the document has been closed.
TypeScript
const required = (await doc.forms.fields()).filter((f) => f.required && f.value === '');
getValuesmethodsince 1.0.0
getValues(): Promise<Record<string, FormValue>>
Every field's value by fully qualified name: a text field's text, a check box's or radio group's export value when one is on and 'Off' when none is, a choice field's option (a multi-select list box's choices as an array). Signature fields are left out. With a viewer open, what the viewer holds, typed values included. What it returns can be given back to setValues(); only read-only fields are refused. Needs the extract feature.
Returns Promise<Record<string, FormValue>> By fully qualified name; a FormValue is a string, or an array of strings for a multi-select list box.
  • FEATURE_NOT_LICENSED — the license lacks extract.
  • DOCUMENT_CLOSED — the document has been closed.
TypeScript
const values = await doc.forms.getValues();
await fetch('/submit', { method: 'POST', body: JSON.stringify(values) });

Writing

setValuesmethodsince 1.0.0
setValues(values: Record<string, FormValue | boolean>): Promise<SetFieldResult>

Sets fields by fully qualified name and resolves to a SetFieldResult; nothing is thrown for a field, a value of the wrong kind included. Every field is read_only when the document forbids filling it in — by its permissions, or by a certification that allows no changes. Needs the forms feature.

The rules, which a viewer open on the document applies through its fields: a text field keeps as many characters as its length limit allows; a formatted field (number, percentage, date, time, phone…) takes what its format accepts when typed, a date also as YYYY-MM-DD; a check box or radio group takes the export value of the widget to turn on, 'Off' or '' turning all off (a radio group that cannot be turned off refuses 'Off'); a dropdown or list box takes one of its options — a multi-select list box its choices as an array ([] clears it; '' clears any list box), and '' is taken for a dropdown only when it holds no choice (a dropdown cannot be emptied); an array of more than one for a field that takes one is invalid_value; a comb field distributes characters as typing would, up to its length limit. Without a viewer a password field is refused (unsupported_type): a file never keeps a password field's text.

ParameterTypeDescription
valuesRecord<string, FormValue | boolean>By fully qualified name — a string, an array of strings for a multi-select list box, or a boolean: true turns a check box on (its export value), false turns a check box or radio group off ('Off'); true for a radio group is invalid_value, since a group has no one "on".
Returns Promise<SetFieldResult> applied names and rejected ones with a reason: unknown_field, read_only, invalid_value or unsupported_type (exported as SetFieldRejection.UNKNOWN_FIELD, .READ_ONLY, …).
  • FEATURE_NOT_LICENSED — the license lacks forms.
  • DOCUMENT_CLOSED — the document has been closed.
  • EXPORT_FAILED — with no viewer open, the document could not be saved to keep a formatted field's value as entered, or, on the form's first write, to name a font every reader has for its fields.
  • INVALID_STATE — a progressive document still downloading.
TypeScript
const { applied, rejected } = await doc.forms.setValues({
  'topmostSubform[0].Page1[0].f1_01[0]': 'Ada Lovelace',
  'topmostSubform[0].Page1[0].c1_1[0]': true, // a check box, on
});
for (const { name, reason } of rejected) console.warn(name, reason);