Button PDF Form Trigger
Overview
This Vue component enables users to download a prefilled PDF form based on the user’s authentication data and saved address information. When a user clicks the "Download form" button, the form is automatically filled with user details (such as name, address, etc.) and is opened in a new browser tab.
Features
- Prefill PDF Form: Automatically fills out the PDF fields with user data, such as name, company, mobile number, etc.
- Dynamic Address Filling: Fetches and fills the user's primary address from the account store.
- Conditional Logic: If the user is not authenticated, they are redirected to an external PDF URL.
- PDF Generation: Uses
pdf-libto manipulate and prefill the PDF form before download. - Seamless User Experience: Opens the prefilled PDF in a new browser tab for immediate access.
Prerequisites
- Vue 3: The component is built using Vue 3’s Composition API.
- pdf-lib: The
pdf-liblibrary is used to manipulate PDF documents. - Authentication Store: The
useAuthStorecomposable provides the user's authentication details. - Account Store: The
useAccountStorecomposable provides the user's saved address information.
Setup
Dependencies
Ensure you have the following dependencies in your project:
pdf-lib: A library used to modify PDF files in JavaScript.useAuthStoreanduseAccountStore: Custom composables for managing user authentication and account data.
Install pdf-lib by running:
npm install pdf-lib
Component Structure
Template
<template>
<ts-button variant="primary" size="md" @click="handlePDFAction">
Download form
</ts-button>
</template>
This template contains a button (ts-button) which triggers the PDF prefill and download action when clicked.
Script
<script setup lang="ts">
import { PDFDocument } from "pdf-lib";
const authStore = useAuthStore();
const { id, first_name, last_name, mobile, username, company }: any =
authStore.user || {};
const fieldsToFill = new Map([
["Tekstveld 2", company],
["Tekstveld 3", first_name],
["Tekstveld 4", last_name],
["Tekstveld 5", ""],
["Tekstveld 6", ""],
["Tekstveld 7", ""],
["Tekstveld 8", ""],
["Tekstveld 9", mobile],
["Tekstveld 10", username],
["Tekstveld 76", formatDate(new Date())],
]);
const fillAndOpenPDF = async () => {
const accountStore = useAccountStore();
const pdfUrl =
"/pdf/202408301-NL-Corporate-identity-letters_-forms_-etc.-Retourformulier.pdf";
try {
const response = await fetch(pdfUrl);
if (!response.ok) {
throw new Error(`Failed to fetch PDF: ${response.statusText}`);
}
await accountStore.getSavedAddresses(id);
fieldsToFill.set(
"Tekstveld 5",
accountStore.primaryAddress?.formatted?.[0]
);
fieldsToFill.set("Tekstveld 6", accountStore.primaryAddress?.postcode);
fieldsToFill.set("Tekstveld 7", accountStore.primaryAddress?.town);
fieldsToFill.set(
"Tekstveld 8",
accountStore.primaryAddress?.formatted
? accountStore.primaryAddress?.formatted[
accountStore.primaryAddress?.formatted.length - 1
]
: []
);
const existingPdfBytes = await response.arrayBuffer();
const pdfDoc = await PDFDocument.load(existingPdfBytes);
const form = pdfDoc.getForm();
fieldsToFill.forEach((item, key) => {
form.getTextField(key).setText(item);
});
const pdfBytes = await pdfDoc.save();
const pdfBlob = new Blob([pdfBytes], { type: "application/pdf" });
const pdfUrlNew = URL.createObjectURL(pdfBlob);
window.open(pdfUrlNew, "_blank");
} catch (error) {
console.error("Error filling PDF:", error);
}
};
const handlePDFAction = () => {
if (authStore.is_authenticated) {
fillAndOpenPDF();
} else {
window.location.href =
"https://cdn.toolstation.nl/content/202408301-NL-Corporate-identity-Letters_-forms_-etc.-Retourformulier.pdf";
}
};
</script>
Component Breakdown
- Template:
- The template consists of a single button (
ts-button) which, when clicked, triggers thehandlePDFActionmethod.
- The template consists of a single button (
- Script:
- Data Preparation:
- The
authStoreis used to retrieve user authentication data. fieldsToFillis aMapwhere keys are the form field names, and values are the corresponding data to be prefilled.
- The
- PDF Fetching and Prefilling:
- The
fillAndOpenPDFfunction fetches the PDF form from a specified URL. - It uses
pdf-libto load the PDF, fill in the form fields with data, and generate a new PDF.
- The
- Conditional Handling:
- The
handlePDFActionfunction checks if the user is authenticated (authStore.is_authenticated). If authenticated, it callsfillAndOpenPDF. If not, it redirects the user to an external PDF URL.
- The
- Data Preparation:
Usage Flow
- User Clicks "Download form" Button:
- If the user is authenticated:
- The app fetches the PDF file and fills in the necessary fields with user data (name, company, address, etc.).
- The filled PDF is then opened in a new browser tab.
- If the user is not authenticated:
- The app redirects the user to an external link where they can access the raw PDF.
- If the user is authenticated:
Error Handling
If any errors occur during the PDF fetching or filling process (e.g., network errors, missing fields), the error is logged to the console, and the user is not provided with the filled PDF.
Customization
- Modify PDF Fields: You can customize the
fieldsToFillMapto include any additional fields or modify the existing ones to match your PDF’s structure. - Additional Form Data: Modify the user data extraction from the
authStoreoraccountStoreto populate the fields with different data. - External PDF URL: Update the fallback URL (
window.location.href) to point to a different PDF if needed.
Example Output
When the button is clicked and the user is authenticated, the following steps will occur:
- A PDF form is fetched from the URL.
- The form is populated with user data like:
- Company name (
Tekstveld 2) - First name (
Tekstveld 3) - Last name (
Tekstveld 4) - Mobile number (
Tekstveld 9) - Username (
Tekstveld 10)
- Company name (
- The filled PDF is opened in a new tab, ready for download.
Conclusion
This component offers a seamless way to prefill PDF forms based on authenticated user data. By utilizing pdf-lib, it provides flexibility and control over form population, allowing dynamic data to be injected directly into the PDF form for a more efficient user experience.