Skip to content

Fill Form Fields and Save with FormData - Vuejs

In this example we allow the user to complete a pdf with form fields and save the completed document.

Prerequisites

This example assumes that there exists a document form.pdf in your storage. If you do not have such a document you can run the following command to add a document with fields under that name:

shell
node src/post-document.js

Field handling

You can use the loaded and formdatachanged events on the pdf document element to capture those events.

html
<PdfDocument
  ref="document"
  @loaded="onLoaded"
  @formdatachanged="onFormDataChanged"
/>

Inside these event handlers you can retrieve the field values:

ts
const onLoaded = async ({ target }: PdfDocumentCustomEvent<string | null>) => {
  formData.value = await target.getFormData();
};
ts
const onFormDataChanged = async ({ target }: PdfDocumentCustomEvent<unknown>) => {
  formData.value = await target.getFormData();
};

Saving documents

You can save the pdf document with the filled in fields to your storage.

note

UnoPdf nevers mutates documents in it's storage. It always creates a copy of your document.

Create a save button with an click event handler.

html
<button
  type="button"
  style="font-size: 20px"
  @click="saveDocument"
>
  save
</button>

In the click event handler you can call the save method on the document element. In addition you can get the field value from the document and post those to an application endpoint to start or continue the business workflow of which the completion of this form is a part.

ts
const saveDocument = async () => {
  const _doc = document.value?.$el;
  if (_doc) {
    responseDocument.value = await _doc.save('response.pdf');
    if (responseDocument.value) {
      console.log(`document saved with id ${responseDocument.value.id}`);
    } else {
      console.log(`document not saved`);
    }
    // In addition to saving the pdf, you can also access
    // the form data at this point to submit it
    // e.g. to a rest endpoint for processing.
    // The pdf that is saved can be kept as part
    // of the audit trail for the transaction.
    console.log('form data', (await _doc.getFormData()));
  }
}

Screenshot

Screenshot op fill-save

Code

vue
<script setup lang="ts">
import { ref, onMounted, nextTick } from "vue";
import {
  PdfApplication,
  PdfDocument,
  PdfPages,
  type IPdfDocument,
  type PdfDocumentCustomEvent,
} from "@tallcomponents/unopdf-vue";

// Note: this example uses Vite and retrieves the keys from the environment.
// This should not be used in production.
// See the authentication section in the usage guide for more information.

const publickey = import.meta.env.VITE_PUBLIC_KEY;
const privatekey = import.meta.env.VITE_PRIVATE_KEY;

const app = ref<{ $el: HTMLPdfApplicationElement }>();
const document = ref<{ $el: HTMLPdfDocumentElement }>();
const pages = ref<{ $el: HTMLPdfPagesElement }>();
const formDocument = ref<IPdfDocument>();
const responseDocument = ref<IPdfDocument | null>()
const formData = ref<Record<string, string>>({});

onMounted(async () => {
  await nextTick();
  const _app = app.value?.$el;
  if (_app) {
    formDocument.value = (await _app.getDocuments()).find((doc) => doc.originalFileName == "form.pdf");
    const _doc = document.value?.$el;

    if (_doc && formDocument.value && formDocument.value.id) {
      await _doc.open(formDocument.value.id);
    }
  }
});

// #region set-form-data-on-load
const onLoaded = async ({ target }: PdfDocumentCustomEvent<string | null>) => {
  formData.value = await target.getFormData();
};
// #endregion set-form-data-on-load

// #region set-form-data-on-change
const onFormDataChanged = async ({ target }: PdfDocumentCustomEvent<unknown>) => {
  formData.value = await target.getFormData();
};
// #endregion set-form-data-on-change

// #region save-document-handler
const saveDocument = async () => {
  const _doc = document.value?.$el;
  if (_doc) {
    responseDocument.value = await _doc.save('response.pdf');
    if (responseDocument.value) {
      console.log(`document saved with id ${responseDocument.value.id}`);
    } else {
      console.log(`document not saved`);
    }
    // In addition to saving the pdf, you can also access
    // the form data at this point to submit it
    // e.g. to a rest endpoint for processing.
    // The pdf that is saved can be kept as part
    // of the audit trail for the transaction.
    console.log('form data', (await _doc.getFormData()));
  }
}
// #endregion save-document-handler

const downloadDocument = () => {
  document.value?.$el.download()
}
</script>

<template>
  <h1>UnoPdf Example: Fill Form Fields and Save with FormData in Vue</h1>

  <PdfApplication
    ref="app"
    :publickey="publickey"
    :privatekey="privatekey"
  />

  <!-- #region pdf-document -->
  <PdfDocument
    ref="document"
    @loaded="onLoaded"
    @formdatachanged="onFormDataChanged"
  />
  <!-- #endregion pdf-document -->

  <div style="display: flex">
    <div>
      <PdfPages ref="pages" />
    </div>
    <div>
      <div style="padding: 10px">
        You can fill out the fields in the document and see your changes reflected below
      </div>
      <div style="padding: 10px">
        <dl>
          <template
            v-for="(value,name) in formData"
            :key="name"
          >
            <dt>
              {{ name }}:
            </dt>
            <dd style="font-weight: bold; padding-bottom: 10px">
              {{ value || '&nbsp;' }}
            </dd>
          </template>
        </dl>
      </div>
      <div style="display: flex">
        <div style="padding: 10px">
          <!-- #region save-document-button -->
          <button
            type="button"
            style="font-size: 20px"
            @click="saveDocument"
          >
            save
          </button>
          <!-- #endregion save-document-button -->
        </div>
        <div style="padding: 10px">
          <button
            type="button"
            style="font-size: 20px"
            @click="downloadDocument"
          >
            download
          </button>
        </div>
      </div>
      <div
        v-if="responseDocument"
        style="padding: 10px"
      >
        Document saved as {{ responseDocument }}
      </div>
    </div>
  </div>
</template>

Running the example

  • Download the vue - Fill Form Fields and Save with FormData project
  • Unzip the file to a directory vue-fill-save.
    shell
    unzip vue-fill-save.zip -d vue-fill-save
  • Open a terminal and go to that directory
    shell
    cd vue-fill-save
  • Install dependencies
    shell
    npm install
    shell
    yarn
  • Start the project
    shell
    npm run start
    shell
    yarn start