Package Exports
- @npoci/pdfform
- @npoci/pdfform/dist/pdfform.css
Readme
@npoci/pdfform
Modern PDF form renderer with HTML overlay fields. View, fill, validate, and map PDF forms directly in the browser.
Features
- 🎯 HTML Overlay Fields - Real HTML inputs positioned over PDF forms
- 📝 Form Filling - Fill and export PDF forms programmatically
- 🔍 Field Mapping - Visual field mapper to create user-friendly field definitions
- ✅ Validation - Built-in validation with custom patterns and error messages
- 🎨 Customizable - Override field renderers and styles
- 📦 Framework Agnostic - Works with React, Vue, Angular, or vanilla JS
- 🔒 Type Safe - Full TypeScript support
Installation
npm install @npoci/pdfform
Quick Start
Basic PDF Form Renderer
import { PDFFormRenderer } from '@npoci/pdfform'
const renderer = new PDFFormRenderer({
container: document.getElementById('pdf-container'),
pdfUrl: 'path/to/form.pdf'
})
// Listen for field changes
renderer.on('fieldChange', (field, validationState) => {
console.log(`${field.name}: ${field.value}`, validationState)
})
// Render the PDF
await renderer.render()
// Get form values
const values = renderer.getFieldValues()
// { email: 'user@example.com', name: 'John Doe' }
// Get validation states
const states = renderer.getFieldStates()
// { email: { valid: true }, name: { valid: false, error: 'Required' } }
Field Definitions
Make PDF fields user-friendly with custom definitions:
const renderer = new PDFFormRenderer({
container: document.getElementById('pdf-container'),
pdfUrl: 'form.pdf',
fieldDefinitions: [
{
key: 'field_12_a', // Original PDF field name
name: 'email', // User-friendly name for getFieldValues()
title: 'Email Address',
placeholder: 'Enter your email',
required: true,
pattern: '^[^@]+@[^@]+\\.[^@]+$',
errorMessage: 'Please enter a valid email'
}
]
})
Custom Field Renderers
Override how specific fields are rendered:
const renderer = new PDFFormRenderer({
container: document.getElementById('pdf-container'),
pdfUrl: 'form.pdf',
fieldOverrides: {
'signature_field': {
createField(field, bounds, setValue) {
const canvas = document.createElement('canvas')
canvas.width = bounds.width
canvas.height = bounds.height
// Add your signature drawing logic
return canvas
},
getValue(element) {
return element.toDataURL()
},
setValue(element, value) {
// Load signature from data URL
}
}
}
})
Fill and Download PDFs
import { PDFFiller } from '@npoci/pdfform'
const filler = new PDFFiller()
const values = renderer.getRawFieldValues()
// Fill the PDF
const filledPdfBytes = await filler.fillFromUrl('form.pdf', values)
// Download
const blob = new Blob([filledPdfBytes], { type: 'application/pdf' })
const url = URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = 'filled-form.pdf'
link.click()
Field Mapper
Create field definitions visually with the built-in mapper:
import { PDFFieldMapper } from '@npoci/pdfform'
const mapper = new PDFFieldMapper({
container: document.getElementById('mapper-container'),
pdfUrl: 'form.pdf'
})
// Listen for field selection
mapper.on('fieldSelected', ({ field, currentMapping }) => {
console.log('Selected:', field.key)
})
// Export field definitions
const definitions = mapper.getFieldDefinitions()
console.log(JSON.stringify(definitions, null, 2))
API Reference
PDFFormRenderer
Options
interface PDFFormRendererOptions {
container: HTMLElement
pdfUrl: string
fieldDefinitions?: FieldDefinition[]
fieldRenderers?: Record<string, FieldRenderer>
fieldOverrides?: Record<string, FieldRenderer>
scale?: number
page?: number
highlightColor?: string // Default: '#ffffcc'
highlightColorFocus?: string // Default: '#ffffaa'
}
Methods
render(): Promise<void>
- Render the PDFsetPage(pageNumber: number): void
- Change pagegetFieldValues(): Record<string, any>
- Get form values with user-friendly namesgetRawFieldValues(): Record<string, any>
- Get values with original PDF field namesgetFieldStates(): Record<string, ValidationState>
- Get validation statessetFieldValues(values: Record<string, any>): void
- Set multiple field valuesdestroy(): void
- Clean up resources
Events
ready
- PDF loaded and fields discoveredfieldChange
- Field value changed with validationpageChange
- Page changederror
- Error occurred
PDFFieldMapper
Options
interface PDFFieldMapperOptions {
container: HTMLElement
pdfUrl: string
fieldDefinitions?: FieldDefinition[]
}
Methods
render(): Promise<void>
- Render the mappersetFieldDefinition(key: string, definition: FieldDefinition): void
- Map a fieldremoveFieldDefinition(key: string): void
- Remove mappinggetFieldDefinitions(): FieldDefinition[]
- Get all mappingsexportDefinitions(): string
- Export as JSONimportDefinitions(json: string): void
- Import mappingsclearMappings(): void
- Clear all mappings
Browser Compatibility
- Chrome/Edge 88+
- Firefox 85+
- Safari 14+
License
MIT © npoci
Contributing
Issues and PRs welcome! Please check existing issues before creating new ones.