Iterate Over All Form Fields and Widgets in a Document

It’s possible to iterate over all form fields and widgets in a document. The code below outlines the general process on an example where you set a solid border for empty form fields:

function updateWidgetBorder(formField, widget) {
  if (formField.value) {
    // Reset the widget border properties when form field has a value.
    return widget
      .set("borderColor", undefined)
      .set("borderWidth", undefined)
      .set("borderStyle", undefined);
  } else {
    // Set a solid border if the form field does not have a value.
    return widget
      .set("borderColor", PSPDFKit.Color.LIGHT_RED)
      .set("borderWidth", 1)
      .set("borderStyle", "solid");

async function refreshWidgets() {
  // Retrieve all form fields.
  const formFields = await instance.getFormFields();

  // Retrieve all widget annotations in the document.
  const widgetAnnotations = (
    await Promise.all(
        length: instance.totalPageCount
      }).map(async (_, pageIndex) =>
        (await instance.getAnnotations(pageIndex)).filter(
          (it) => it instanceof PSPDFKit.Annotations.WidgetAnnotation
  ).flatMap((pageAnnotations) => pageAnnotations.toArray());

  // Iterate over all form fields and their widgets to update their appearance.
  const widgetsToUpdate = formFields.flatMap((formField) => {
    // Find all widget annotations for a given form field.
    const widgets = widgetAnnotations.filter((annotation) =>

    // Update all widgets based on the form field value.
    return =>
      updateWidgetBorder(formField, widget)

  // Now perform the batch update with your updated widget annotations.
  return instance.update(widgetsToUpdate);

This has been tested with PSPDFKit for Web 2020.6.4


This example behaves similar to what can be achieved with required form fields. If you only need to style required fields, refer to the instructions in this guide.