> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/web/forms/working-with-fields.md).

# Fields and Widgets

Learn how to work with WebViewer form fields and understand their relationship with widget annotations.

Form fields and widget annotations are the two main components of a form workflow. Form fields represent the data entry points for users, while widget annotations serve as the visual elements that encapsulate these fields, providing interactive components like checkboxes, text boxes, and dropdown menus. The sections below cover some of the common use cases when working with form fields and widgets.

## Creating form fields

Creating form fields requires you to define the value and type of the field, along with some optional parameters. You can find a detailed explanation on field creation by visiting [Creating form fields](/web/forms/create-fields.md). Below is a simple example of a text field.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { Annotations, annotationManager } = instance.Core;
    const field = new Annotations.Forms.Field('Field Name', { type: 'Tx' });
    annotationManager.getFieldManager().addField(field);
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Field](https://sdk.apryse.com/api/web/Core.Annotations.Forms.Field.html#Field__anchor) [FieldManager#addField](https://sdk.apryse.com/api/web/Core.Annotations.Forms.FieldManager.html#addField__anchor)

## Setting widget flags

`WidgetFlags` allow you to define certain behaviors of a field and its associated widgets. The available flags may change over time, but these are the [currently supported WidgetFlags](https://sdk.apryse.com/api/web/Core.Annotations.WidgetFlags.html#main). A `WidgetFlags` object can be passed to a form field at creation to define the default state of the field.

![](https://3532544125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX9YnTSKIHvV7m0A36LbO%2Fuploads%2Fgit-blob-2876a5e69cd325692812c54d68fcfeda5e46e40d%2F9f614154770d288b392adf1f7e349cbca6e916f7-314x109.png?alt=media)

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { annotationManager, Annotations } = instance.Core;
    const { WidgetFlags } = Annotations;

    const flags = new WidgetFlags();
    flags.set(WidgetFlags.MULTILINE, true);
    flags.set(WidgetFlags.REQUIRED, true);

    const field = new Annotations.Forms.Field('Field Name', {
      flags
      type: 'Tx'
    });

    annotationManager.getFieldManager().addField(field);
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Field](https://sdk.apryse.com/api/web/Core.Annotations.Forms.Field.html#Field__anchor) [WidgetFlags](https://sdk.apryse.com/api/web/Core.Annotations.WidgetFlags.html#main) [FieldManager#addField](https://sdk.apryse.com/api/web/Core.Annotations.Forms.FieldManager.html#addField__anchor)

## Updating widget flags

You can update `WidgetFlags` by accessing the `WidgetFlags` that have been added to the field. This can be done by calling the `set` method. All `WidgetFlags` accept a boolean value to determine the desired state.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { annotationManager, Annotations } = instance.Core;
    const { WidgetFlags } = Annotations;

    // Create a field with READ_ONLY flag set to true.
    const flags = new WidgetFlags();
    flags.set(WidgetFlags.READ_ONLY, true);
    const field = new Annotations.Forms.Field('Field Name', {
      flags
      type: 'Tx',
    });

    // Modify the flag to set READ_ONLY to false.
    field.flags.set(WidgetFlags.READ_ONLY, false);
    annotationManager.getFieldManager().addField(field);
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Field](https://sdk.apryse.com/api/web/Core.Annotations.Forms.Field.html#Field__anchor) [WidgetFlags](https://sdk.apryse.com/api/web/Core.Annotations.WidgetFlags.html#main) [WidgetFlags#set](https://sdk.apryse.com/api/web/Core.Annotations.Forms.Field.html#set__anchor) [FieldManager#addField](https://sdk.apryse.com/api/web/Core.Annotations.Forms.FieldManager.html#addField__anchor)

## Updating field values

The most consistent way to update a field's value is to call the `setValue` method on the field object. This will result in the field being updated along with all of the associated widgets.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { annotationManager, Annotations } = instance.Core;

    const field = new Annotations.Forms.Field('Field Name', { type: 'Tx' });

    field.setValue("Hello World");
    annotationManager.getFieldManager().addField(field);
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Field#setValue](https://sdk.apryse.com/api/web/Core.Annotations.Forms.Field.html#setValue__anchor) [FieldManager#addField](https://sdk.apryse.com/api/web/Core.Annotations.Forms.FieldManager.html#addField__anchor)

## Highlighting Widgets

Form field highlighting is enabled by default to visually indicate interactive fields in the UI. This applies to:

* Text fields
* Choice fields
* Signature fields
* Checkboxes
* Radio buttons

However, highlight is not applied to push buttons. Highlighting is a UI-only visual cue and does **not** change the underlying widget styling or appearance.

![Form Fields highlighted](https://3532544125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX9YnTSKIHvV7m0A36LbO%2Fuploads%2Fgit-blob-dea0019141cd3aad19bbc97e5403927f2aacdfe7%2Fddc91cc08ead80704b26a15161ad87c7fcfc432b-2396x944.png?alt=media)

You could choose to enable or disable the highlight with the following APIs:

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { annotationManager, Annotations } = instance.Core;

    const annotationManager = instance.Core.documentViewer.getAnnotationManager();
    const fieldManager = annotationManager.getFieldManager();
  
    // Enable/disable standard widget highlighting
    fieldManager.enableWidgetHighlighting();
    fieldManager.disableWidgetHighlighting();
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

[FieldManager#enableWidgetHighlighting](https://sdk.apryse.com/api/web/Core.Annotations.Forms.FieldManager.html#enableWidgetHighlighting__anchor) [FieldManager#disableWidgetHighlighting](https://sdk.apryse.com/api/web/Core.Annotations.Forms.FieldManager.html#disableWidgetHighlighting__anchor)

## Configuring multiple widgets for a single field

The PDF specification allows multiple widgets to be associated with a single field, ensuring consistency across these widgets. For instance, a user may want to enter their first name only once and have it shown in multiple places in the form. We support this functionality by passing the same field into different widgets during object creation.

![](https://3532544125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX9YnTSKIHvV7m0A36LbO%2Fuploads%2Fgit-blob-51468cf5ffaa05db7a046a02c036182838412f70%2F0b0e3911f2f1a760a99b7dc7e15a9bb3e07dfa05-532x224.gif?alt=media)

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
function createWidget (field, options, x, y, Annotations) {
  let newWidget = new Annotations.TextWidgetAnnotation(field, options);
  newWidget.PageNumber = 1;
  newWidget.X = x;
  newWidget.Y = y;
  newWidget.Width = 50;
  newWidget.Height = 20;
  return newWidget;
}

WebViewer(...)
  .then(instance => {
    const { annotationManager, Annotations } = instance.Core;

    const field = new Annotations.Forms.Field('Field Name', { type: 'Tx' });

    const widgetAnnot = createWidget(field, {}, 100, 100, Annotations);
    const widgetAnnot02 = createWidget(field, {}, 200, 200, Annotations);

    annotationManager.getFieldManager().addField(field);
    annotationManager.addAnnotations([widgetAnnot, widgetAnnot02]);
    annotationManager.drawAnnotationsFromList([widgetAnnot]);
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Field](https://sdk.apryse.com/api/web/Core.Annotations.Forms.Field.html#Field__anchor) [FieldManager#addField](https://sdk.apryse.com/api/web/Core.Annotations.Forms.FieldManager.html#addField__anchor) [AnnotationManager#addAnnotations](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#addAnnotations__anchor) [AnnotationManager#drawAnnotationsFromList](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#drawAnnotationsFromList__anchor) [AnnotationManager#getFieldManager](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#getFieldManager__anchor)

## Configuring widgets across multiple pages

You can also link widget annotations across multiple pages to a single form field. The same update behavior mentioned in the previous section applies. In the example below, we extend the `createWidget` function to accept a `Page` argument. Finally, we attach multiple cross-page widgets to a single field. This allows you to have shared fields across multiple PDF pages, streamlining data entry and ensuring that updates to one widget are automatically propagated to the other widgets that relate to the same field.

![](https://3532544125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX9YnTSKIHvV7m0A36LbO%2Fuploads%2Fgit-blob-ba5d0909e6dfd809d35a42e19c53484532c1ceaa%2Fbff202c97717dbdc36c9541740b224f07b79b25a-667x603.gif?alt=media)

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
function createWidget (field, options, x, y, Annotations, page = 1) {
  let newWidget = new Annotations.TextWidgetAnnotation(field, options);
  newWidget.PageNumber = page;
  newWidget.X = x;
  newWidget.Y = y;
  newWidget.Width = 50;
  newWidget.Height = 20;
  return newWidget;
}

WebViewer(...)
  .then(instance => {
    const { annotationManager, Annotations } = instance.Core;

    const field = new Annotations.Forms.Field('Field Name', { type: 'Tx' });

    const widgetAnnot01_page1 = createWidget(field, {}, 100, 100, Annotations);
    const widgetAnnot02_page1 = createWidget(field, {}, 200, 200, Annotations);
    const widgetAnnot03_page2 = createWidget(field, {}, 200, 200, Annotations, 2);
    const widgetAnnot04_page3 = createWidget(field, {}, 200, 200, Annotations, 3);

    const widgetsToAdd = [
      widgetAnnot01_page1,
      widgetAnnot02_page1,
      widgetAnnot03_page2,
      widgetAnnot04_page3
    ];

    annotationManager.getFieldManager().addField(field);
    annotationManager.addAnnotations(widgetsToAdd);
    annotationManager.drawAnnotationsFromList(widgetsToAdd);
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Field](https://sdk.apryse.com/api/web/Core.Annotations.Forms.Field.html#Field__anchor) [FieldManager#addField](https://sdk.apryse.com/api/web/Core.Annotations.Forms.FieldManager.html#addField__anchor) [AnnotationManager#addAnnotations](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#addAnnotations__anchor) [AnnotationManager#drawAnnotationsFromList](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#drawAnnotationsFromList__anchor) [AnnotationManager#getFieldManager](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#getFieldManager__anchor)

## Additional field properties

The field has optional additional properties that can further define its behavior.

### Max length

This defines the maximum number of characters that can be inputted into the field.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { annotationManager, Annotations } = instance.Core;

    const field = new Annotations.Forms.Field('Field Name', { type: 'Tx' });
    field.set({ maxLen: 5 });

    annotationManager.getFieldManager().addField(field);
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Field#set](https://sdk.apryse.com/api/web/Core.Annotations.Forms.Field.html#set__anchor) [FieldManager#addField](https://sdk.apryse.com/api/web/Core.Annotations.Forms.FieldManager.html#addField__anchor) [AnnotationManager#getFieldManager](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#getFieldManager__anchor)

### Tooltips

This defines the tooltip that will be displayed when a user hovers over the widget annotation.

![](https://3532544125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX9YnTSKIHvV7m0A36LbO%2Fuploads%2Fgit-blob-456154d96ac9b687dc5f5c9bce17586f865834a3%2F57815037837312491541c666d7ad5c13613c6234-346x98.png?alt=media)

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { annotationManager, Annotations } = instance.Core;

    const field = new Annotations.Forms.Field('Field Name', { type: 'Tx' });
    field.set({ tooltipName: `I'm a tooltip!` });

    annotationManager.getFieldManager().addField(field);
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Field#set](https://sdk.apryse.com/api/web/Core.Annotations.Forms.Field.html#set__anchor) [FieldManager#addField](https://sdk.apryse.com/api/web/Core.Annotations.Forms.FieldManager.html#addField__anchor) [AnnotationManager#getFieldManager](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#getFieldManager__anchor)

### Options

Options are only applicable to list box and combo box field types. They define the possible values a user can select when interacting with these fields.

![](https://3532544125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX9YnTSKIHvV7m0A36LbO%2Fuploads%2Fgit-blob-2d59cb60956a60996c5c27d4de12631cd9ee15aa%2F6b88547c0d358776821fd1720a42d5adcd6daffb-299x244.png?alt=media)

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { annotationManager, Annotations } = instance.Core;

    const options = [
      { value: 'option1', displayValue: '1' },
      { value: 'option2', displayValue: '2' },
      { value: 'option3', displayValue: '3' },
      { value: 'option4', displayValue: '4' },
    ];

    // Creates a listbox field. WidgetFlags.COMBO is false by default, so no `flags` object is needed.
    field = new Annotations.Forms.Field('Field Name', {
      type: 'Ch',
      options
    });

    annotationManager.getFieldManager().addField(field);
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Field](https://sdk.apryse.com/api/web/Core.Annotations.Forms.Field.html#Field__anchor) [FieldManager#addField](https://sdk.apryse.com/api/web/Core.Annotations.Forms.FieldManager.html#addField__anchor) [AnnotationManager#getFieldManager](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#getFieldManager__anchor)

### Checkbox Widgets and Appearances

Checkbox widgets can also have appearances like Annotations. However, some files can have appearances that don’t match their values. If the value or appearance state is set to `On`, then the checkbox will be checked in WebViewer.

| Checkbox Value | Appearance | Rendered State |
| -------------- | ---------- | -------------- |
| On             | On         | On             |
| Off            | Off        | Off            |
| On             | Off        | On             |
| Off            | On         | On             |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/web/forms/working-with-fields.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
