Resize multiline text fields to avoid overflow

To resize a multiline text form field in height when it’s overflown, use the following code snippet, which will make multiline text widgets auto-grow in height when overflown:

instance.contentDocument.addEventListener(
  "input",
  async function (event) {
    if (event.target.nodeName === "TEXTAREA") {
      const textInput = event.target;
      const id = textInput.parentNode.dataset.annotationId;
      const pageIndex = instance.viewState.currentPageIndex;
      const annotations = await instance.getAnnotations(pageIndex);
      const widget = annotations.find(
        (annotation) => annotation.id === id
      );
      if (
        widget &&
        typeof widget.fontSize === "number" &&
        textInput.scrollHeight > textInput.clientHeight
      ) {
        while (textInput.scrollHeight > textInput.clientHeight) {
          await instance.update(
            widget.set(
              "boundingBox",
              widget.boundingBox.set(
                "height",
                widget.boundingBox.height + widget.fontSize
              )
            )
          );
          // This is needed so the widget height change is propagated to the DOM
          // before the next check. Otherwise there may be an endless loop.
          await new Promise(requestAnimationFrame);
        }
      }
    }
  }
);
Information

This requires the Form Creator component. The snippet above can also be adapted to your needs to resize other form fields.

It’s important to note that the code above:

  • Only works for text widgets with a fixed number fontSize value (not “auto”).

  • Only works for text widgets with a doNotScroll value of false.

  • Won’t change the layout of any other widgets, which will likely either overlap the text widget or be covered by it (you can add this logic yourself if necessary).

  • Won’t prevent the widget from growing down the bottom bound of the page (you can add this logic yourself if necessary).

Tested in PSPDFKit for Web 2021.3.0.