LibPDF

PDFForm

Form class for reading, filling, creating, and flattening interactive form fields.

PDFForm

The PDFForm class manages interactive forms (AcroForms) in a PDF document. It provides methods for reading, filling, creating, and flattening form fields.

const pdf = await PDF.load(bytes);
const form = pdf.getForm();

if (form) {
  form.fill({
    name: "John Doe",
    email: "john@example.com",
    agree: true,
  });
}

Properties

fieldCount

Number of fields in the form.

Type: number (readonly)


isEmpty

Whether the form has no fields.

Type: boolean (readonly)


hasUnsavedChanges

Whether any field has been modified and needs appearance update.

Type: boolean (readonly)


properties

Form-level properties.

Type: FormProperties (readonly)

interface FormProperties {
  defaultAppearance: string;
  defaultAlignment: TextAlignment;
  needAppearances: boolean;
  hasSignatures: boolean;
  isAppendOnly: boolean;
}

Field Access

getFields()

Get all form fields.

Returns: FormField[]

const fields = form.getFields();
for (const field of fields) {
  console.log(`${field.name}: ${field.type}`);
}

getFieldNames()

Get the names of all fields.

Returns: string[]

const names = form.getFieldNames();
// ["name", "email", "phone", "agree"]

getField(name)

Get a field by name (untyped).

ParamTypeDescription
namestringField name

Returns: FormField | undefined

const field = form.getField("name");
if (field?.type === "text") {
  console.log(field.getValue());
}

hasField(name)

Check if a field exists.

ParamTypeDescription
namestringField name

Returns: boolean


Type-Safe Field Access

These methods return properly typed fields, or undefined if not found or wrong type.

getTextField(name)

Get a text field by name.

Returns: TextField | undefined

const nameField = form.getTextField("name");
if (nameField) {
  nameField.setValue("John Doe");
  console.log(nameField.getValue());
}

getCheckbox(name)

Get a checkbox field by name.

Returns: CheckboxField | undefined

const agree = form.getCheckbox("terms");
if (agree) {
  agree.check();
  console.log(agree.isChecked()); // true
}

getRadioGroup(name)

Get a radio button group by name.

Returns: RadioField | undefined

const payment = form.getRadioGroup("payment_method");
if (payment) {
  payment.setValue("credit_card");
  console.log(payment.getOptions()); // ["credit_card", "paypal", "bank"]
}

getDropdown(name)

Get a dropdown (combo box) field by name.

Returns: DropdownField | undefined

const country = form.getDropdown("country");
if (country) {
  country.setValue("United States");
  const options = country.getOptions();
  // options: [{ value: "USA", display: "United States" }, ...]
}

getListBox(name)

Get a list box field by name.

Returns: ListBoxField | undefined

const colors = form.getListBox("favorite_colors");
if (colors) {
  colors.setValue(["red", "blue"]);
}

getSignatureField(name)

Get a signature field by name.

Returns: SignatureField | undefined

const sig = form.getSignatureField("signature1");
if (sig) {
  console.log(sig.isSigned());
}

getButton(name)

Get a button field by name.

Returns: ButtonField | undefined


Bulk Field Access

getTextFields()

Get all text fields.

Returns: TextField[]


getCheckboxes()

Get all checkboxes.

Returns: CheckboxField[]


getRadioGroups()

Get all radio button groups.

Returns: RadioField[]


getDropdowns()

Get all dropdowns.

Returns: DropdownField[]


getListBoxes()

Get all list boxes.

Returns: ListBoxField[]


getSignatureFields()

Get all signature fields.

Returns: SignatureField[]


getButtons()

Get all buttons.

Returns: ButtonField[]


Bulk Operations

fill(values)

Fill multiple fields at once.

ParamTypeDescription
valuesRecord<string, FieldValue>Field names to values

Returns: { filled: string[], skipped: string[] }

Throws: TypeError - If a value type doesn't match the field type

This method is lenient: fields that don't exist are silently skipped.

const result = form.fill({
  name: "John Doe",
  email: "john@example.com",
  agree: true, // checkbox
  country: "USA", // dropdown
  colors: ["red", "blue"], // listbox
  nonexistent: "ignored",
});

console.log(result.filled); // ["name", "email", "agree", "country", "colors"]
console.log(result.skipped); // ["nonexistent"]

FieldValue Types:

Field TypeValue Type
Textstring
Checkboxboolean or string
Radiostring or null
Dropdownstring
Listboxstring[]

resetAll()

Reset all fields to their default values.

form.resetAll();

Field Creation

createTextField(name, options?)

Create a new text field.

ParamTypeDefaultDescription
namestringrequiredUnique field name
[options]TextFieldOptions
[options.font]EmbeddedFontFont for text
[options.fontSize]number0 (auto)Font size
[options.color]ColorblackText color
[options.maxLength]numberMax characters
[options.multiline]booleanfalseMultiline input
[options.password]booleanfalseMask input
[options.comb]booleanfalseFixed-width cells
[options.alignment]TextAlignment"left"Text alignment
[options.defaultValue]stringDefault value
[options.backgroundColor]ColorBackground
[options.borderColor]ColorBorder
[options.borderWidth]number1Border width

Returns: TextField

Throws: Error - If field name already exists

const nameField = form.createTextField("name", {
  fontSize: 12,
  maxLength: 100,
  defaultValue: "John Doe",
});

// Place on page
page.drawField(nameField, {
  x: 100,
  y: 700,
  width: 200,
  height: 24,
});

createCheckbox(name, options?)

Create a new checkbox field.

ParamTypeDefaultDescription
namestringrequiredUnique field name
[options]CheckboxOptions
[options.onValue]string"Yes"Value when checked
[options.symbol]CheckboxSymbol"check"Symbol style
[options.defaultChecked]booleanfalseInitially checked
[options.backgroundColor]ColorBackground
[options.borderColor]ColorBorder
[options.borderWidth]number1Border width

Returns: CheckboxField

CheckboxSymbol: "check" | "cross" | "square"

const agree = form.createCheckbox("agree", {
  onValue: "Yes",
  symbol: "check",
  defaultChecked: true,
});

page.drawField(agree, {
  x: 100,
  y: 650,
  width: 18,
  height: 18,
});

createRadioGroup(name, options)

Create a new radio button group.

ParamTypeDefaultDescription
namestringrequiredUnique field name
optionsRadioGroupOptionsrequired
options.optionsstring[]requiredAvailable values
[options.symbol]RadioSymbol"circle"Symbol style
[options.defaultValue]stringInitially selected
[options.backgroundColor]ColorBackground
[options.borderColor]ColorBorder
[options.borderWidth]number1Border width

Returns: RadioField

Throws:

  • Error - If field name already exists
  • Error - If options array is empty

RadioSymbol: "circle" | "check"

const payment = form.createRadioGroup("payment", {
  options: ["Credit Card", "PayPal", "Bank Transfer"],
  defaultValue: "Credit Card",
});

// Each option needs its own widget
page.drawField(payment, {
  x: 100,
  y: 550,
  width: 16,
  height: 16,
  option: "Credit Card",
});
page.drawField(payment, {
  x: 100,
  y: 520,
  width: 16,
  height: 16,
  option: "PayPal",
});
page.drawField(payment, {
  x: 100,
  y: 490,
  width: 16,
  height: 16,
  option: "Bank Transfer",
});

createDropdown(name, options)

Create a new dropdown (combo box) field.

ParamTypeDefaultDescription
namestringrequiredUnique field name
optionsDropdownOptionsrequired
options.optionsstring[]requiredAvailable values
[options.font]EmbeddedFontFont for text
[options.fontSize]numberFont size
[options.color]ColorText color
[options.editable]booleanfalseAllow custom input
[options.defaultValue]stringInitially selected
[options.backgroundColor]ColorBackground
[options.borderColor]ColorBorder

Returns: DropdownField

Throws: Error - If options array is empty

const country = form.createDropdown("country", {
  options: ["USA", "Canada", "UK", "Germany"],
  defaultValue: "USA",
  fontSize: 11,
});

page.drawField(country, {
  x: 100,
  y: 600,
  width: 200,
  height: 24,
});

createListbox(name, options)

Create a new list box field.

ParamTypeDefaultDescription
namestringrequiredUnique field name
optionsListboxOptionsrequired
options.optionsstring[]requiredAvailable values
[options.font]EmbeddedFontFont for text
[options.fontSize]numberFont size
[options.color]ColorText color
[options.multiSelect]booleanfalseAllow multiple selection
[options.defaultValue]string[]Initially selected
[options.backgroundColor]ColorBackground
[options.borderColor]ColorBorder

Returns: ListBoxField

Throws: Error - If options array is empty

const colors = form.createListbox("colors", {
  options: ["Red", "Green", "Blue", "Yellow"],
  multiSelect: true,
  defaultValue: ["Red", "Blue"],
});

page.drawField(colors, {
  x: 100,
  y: 400,
  width: 150,
  height: 100,
});

createSignatureField(name, options?)

Create a new signature field.

ParamTypeDefaultDescription
namestringrequiredUnique field name
[options]SignatureFieldOptions
[options.backgroundColor]ColorBackground
[options.borderColor]ColorBorder
[options.borderWidth]number1Border width

Returns: SignatureField

const sigField = form.createSignatureField("Signature1");
// Sign later via pdf.sign({ fieldName: "Signature1", ... })

Form Operations

updateAppearances()

Regenerate appearance streams for all modified fields.

form.updateAppearances();

flatten(options?)

Flatten all form fields into static page content.

ParamTypeDefaultDescription
[options]FlattenOptions

After flattening:

  • Field appearances become static page content
  • Widget annotations are removed
  • The form can no longer be edited
form.fill({ name: "John", email: "john@example.com" });
form.flatten();
const bytes = await pdf.save();

reloadFields()

Reload fields from the underlying AcroForm.

Call this if the form structure has been modified externally.

form.reloadFields();

acroForm()

Get the underlying AcroForm for low-level operations.

Returns: AcroForm

const acroForm = form.acroForm();
console.log(acroForm.defaultAppearance);

Field Types

TextField

Method/PropertyReturnsDescription
getValue()stringGet current value
setValue(value)voidSet value
maxLengthnumberMax length (0 = no limit)
isMultilinebooleanWhether multiline
setFont(font)voidSet font
setFontSize(size)voidSet font size
setTextColor(r, g, b)voidSet text color

CheckboxField

MethodReturnsDescription
isChecked()booleanCheck state
check()voidCheck the box
uncheck()voidUncheck the box
setValue(value)voidSet by value string
getOnValue()stringGet the "on" value

RadioField

MethodReturnsDescription
getValue()string | nullGet selected option
setValue(value)voidSelect option
getOptions()string[]Get available options

Method/PropertyReturnsDescription
getValue()stringGet selected value
setValue(value)voidSelect value
getOptions()ChoiceOption[]Get available options
isEditablebooleanWhether editable
setFont(font)voidSet font
setFontSize(size)voidSet font size

ListBoxField

Method/PropertyReturnsDescription
getValue()string[]Get selected values
setValue(values)voidSet selected values
getOptions()ChoiceOption[]Get available options
isMultiSelectbooleanWhether multi-select
setFont(font)voidSet font
setFontSize(size)voidSet font size

SignatureField

MethodReturnsDescription
isSigned()booleanCheck if signed

Types

TextAlignment

type TextAlignment = "left" | "center" | "right";

FieldValue

type FieldValue = string | boolean | string[] | null;

ChoiceOption

interface ChoiceOption {
  value: string; // Export value
  display: string; // Display text (may equal value)
}

FormField

interface FormField {
  name: string;
  type: FieldType;
  isReadOnly(): boolean;
  isRequired(): boolean;
}

type FieldType = "text" | "checkbox" | "radio" | "dropdown" | "listbox" | "signature" | "button";

On this page