or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotation-api.mdconfiguration.mddocument-api.mdeditor-api.mdindex.mdrendering-api.mdtext-layer.mdxfa-api.md

xfa-api.mddocs/

0

# XFA API

1

2

XML Forms Architecture (XFA) support for dynamic PDF forms and interactive content. XFA forms provide rich, dynamic form experiences with complex layouts and data binding.

3

4

## Capabilities

5

6

### XFA Layer Rendering

7

8

Renders XFA forms as interactive HTML elements, enabling complex form interactions and dynamic content updates.

9

10

```javascript { .api }

11

class XfaLayer {

12

/**

13

* Render XFA form content

14

* @param parameters - XFA layer parameters

15

* @returns XFA layer result

16

*/

17

static render(parameters: XfaLayerParameters): XfaLayerResult;

18

19

/**

20

* Update existing XFA layer

21

* @param parameters - XFA layer parameters

22

*/

23

static update(parameters: XfaLayerParameters): void;

24

25

/**

26

* Set up XFA layer container

27

* @param div - Container element

28

* @param parameters - Setup parameters

29

*/

30

static setupStorage(div: HTMLElement, parameters: any): void;

31

}

32

```

33

34

### XFA Layer Parameters

35

36

Configuration for rendering XFA forms.

37

38

```javascript { .api }

39

interface XfaLayerParameters {

40

/** Page viewport for positioning */

41

viewport: PageViewport;

42

/** Container element for XFA content */

43

div: HTMLElement;

44

/** XFA HTML content */

45

xfaHtml: Element;

46

/** Annotation storage for form data */

47

annotationStorage?: AnnotationStorage;

48

/** Link service for navigation */

49

linkService: IPDFLinkService;

50

/** XFA HTML factory for element creation */

51

xfaHtmlFactory: any;

52

/** Optional document base URL */

53

docBaseUrl?: string;

54

/** Page index */

55

pageIndex?: number;

56

}

57

58

interface XfaLayerResult {

59

/** Root XFA element */

60

element: HTMLElement;

61

/** Child elements */

62

children: HTMLElement[];

63

/** Intent of the rendering */

64

intent: string;

65

}

66

```

67

68

**Usage Examples:**

69

70

```javascript

71

import { XfaLayer } from "pdfjs-dist";

72

73

// Check if page has XFA content

74

const xfaHtml = await page.getXfa();

75

76

if (xfaHtml) {

77

// Create XFA layer container

78

const xfaDiv = document.createElement("div");

79

xfaDiv.className = "xfaLayer";

80

document.body.appendChild(xfaDiv);

81

82

// Render XFA form

83

const xfaResult = XfaLayer.render({

84

viewport: viewport,

85

div: xfaDiv,

86

xfaHtml: xfaHtml,

87

annotationStorage: annotationStorage,

88

linkService: linkService,

89

xfaHtmlFactory: new XfaHtmlFactory()

90

});

91

92

console.log("XFA form rendered with", xfaResult.children.length, "elements");

93

}

94

```

95

96

### XFA HTML Factory

97

98

Factory for creating XFA HTML elements with proper event handling and styling.

99

100

```javascript { .api }

101

interface XfaHtmlFactory {

102

/**

103

* Create XFA element

104

* @param data - Element data

105

* @returns HTML element

106

*/

107

createElement(data: XfaElementData): HTMLElement;

108

109

/**

110

* Create XFA text node

111

* @param text - Text content

112

* @returns Text node

113

*/

114

createTextNode(text: string): Text;

115

116

/**

117

* Create XFA document fragment

118

* @returns Document fragment

119

*/

120

createDocumentFragment(): DocumentFragment;

121

}

122

123

interface XfaElementData {

124

/** Element tag name */

125

name: string;

126

/** Element attributes */

127

attributes?: { [key: string]: string };

128

/** Child elements */

129

children?: XfaElementData[];

130

/** Text content */

131

value?: string;

132

/** Element namespace */

133

namespace?: string;

134

}

135

```

136

137

### XFA Form Controls

138

139

Interfaces for different XFA form control types.

140

141

```javascript { .api }

142

interface XfaTextField {

143

/** Field name */

144

name: string;

145

/** Field value */

146

value: string;

147

/** Whether field is required */

148

required: boolean;

149

/** Whether field is read-only */

150

readOnly: boolean;

151

/** Maximum length */

152

maxLength?: number;

153

/** Input pattern */

154

pattern?: string;

155

/** Placeholder text */

156

placeholder?: string;

157

158

/**

159

* Set field value

160

* @param value - New value

161

*/

162

setValue(value: string): void;

163

164

/**

165

* Validate field value

166

* @returns Validation result

167

*/

168

validate(): boolean;

169

170

/**

171

* Focus the field

172

*/

173

focus(): void;

174

}

175

176

interface XfaCheckBox {

177

/** Field name */

178

name: string;

179

/** Whether checked */

180

checked: boolean;

181

/** Whether field is required */

182

required: boolean;

183

/** Whether field is read-only */

184

readOnly: boolean;

185

186

/**

187

* Set checked state

188

* @param checked - Whether to check

189

*/

190

setChecked(checked: boolean): void;

191

192

/**

193

* Toggle checked state

194

*/

195

toggle(): void;

196

}

197

198

interface XfaDropdownList {

199

/** Field name */

200

name: string;

201

/** Selected value */

202

value: string;

203

/** Available options */

204

options: { value: string; text: string }[];

205

/** Whether field is required */

206

required: boolean;

207

/** Whether field is read-only */

208

readOnly: boolean;

209

210

/**

211

* Set selected value

212

* @param value - Value to select

213

*/

214

setValue(value: string): void;

215

216

/**

217

* Add option

218

* @param option - Option to add

219

*/

220

addOption(option: { value: string; text: string }): void;

221

222

/**

223

* Remove option

224

* @param value - Value of option to remove

225

*/

226

removeOption(value: string): void;

227

}

228

```

229

230

### XFA Data Binding

231

232

Interfaces for XFA data binding and dynamic content.

233

234

```javascript { .api }

235

interface XfaDataConnection {

236

/** Connection name */

237

name: string;

238

/** Data source URL */

239

dataSource: string;

240

/** Connection type */

241

type: "xml" | "json" | "database";

242

243

/**

244

* Load data from source

245

* @returns Promise resolving to data

246

*/

247

loadData(): Promise<any>;

248

249

/**

250

* Save data to source

251

* @param data - Data to save

252

* @returns Promise resolving when complete

253

*/

254

saveData(data: any): Promise<void>;

255

256

/**

257

* Bind data to form

258

* @param formData - Form data object

259

*/

260

bindData(formData: any): void;

261

}

262

263

interface XfaCalculation {

264

/** Expression to evaluate */

265

expression: string;

266

/** Target field name */

267

target: string;

268

/** Dependencies */

269

dependencies: string[];

270

271

/**

272

* Execute calculation

273

* @param context - Calculation context

274

* @returns Calculated value

275

*/

276

execute(context: any): any;

277

278

/**

279

* Check if calculation is valid

280

* @returns Whether valid

281

*/

282

isValid(): boolean;

283

}

284

```

285

286

### XFA Events

287

288

Event handling for XFA form interactions.

289

290

```javascript { .api }

291

interface XfaEvent {

292

/** Event type */

293

type: "initialize" | "calculate" | "validate" | "full" | "save" | "print" | "change" | "exit" | "click";

294

/** Source element */

295

source: HTMLElement;

296

/** Event data */

297

data: any;

298

/** Whether event can be cancelled */

299

cancelable: boolean;

300

301

/**

302

* Cancel event

303

*/

304

cancel(): void;

305

306

/**

307

* Get field value

308

* @param fieldName - Name of field

309

* @returns Field value

310

*/

311

getFieldValue(fieldName: string): any;

312

313

/**

314

* Set field value

315

* @param fieldName - Name of field

316

* @param value - Value to set

317

*/

318

setFieldValue(fieldName: string, value: any): void;

319

}

320

321

interface XfaEventHandler {

322

/**

323

* Handle XFA event

324

* @param event - XFA event

325

*/

326

handleEvent(event: XfaEvent): void;

327

328

/**

329

* Register event listener

330

* @param eventType - Type of event

331

* @param handler - Event handler function

332

*/

333

addEventListener(eventType: string, handler: (event: XfaEvent) => void): void;

334

335

/**

336

* Remove event listener

337

* @param eventType - Type of event

338

* @param handler - Event handler function

339

*/

340

removeEventListener(eventType: string, handler: (event: XfaEvent) => void): void;

341

}

342

```

343

344

### XFA Utilities

345

346

Helper functions for XFA form operations.

347

348

```javascript { .api }

349

/**

350

* Get XFA page viewport with proper scaling

351

* @param xfaPage - XFA page element

352

* @param viewport - Base viewport

353

* @returns XFA-adjusted viewport

354

*/

355

function getXfaPageViewport(xfaPage: Element, viewport: PageViewport): PageViewport;

356

357

/**

358

* Extract XFA form data

359

* @param xfaElement - Root XFA element

360

* @returns Form data object

361

*/

362

function extractXfaData(xfaElement: HTMLElement): { [key: string]: any };

363

364

/**

365

* Populate XFA form with data

366

* @param xfaElement - Root XFA element

367

* @param data - Data to populate

368

*/

369

function populateXfaForm(xfaElement: HTMLElement, data: { [key: string]: any }): void;

370

371

/**

372

* Validate XFA form

373

* @param xfaElement - Root XFA element

374

* @returns Validation results

375

*/

376

function validateXfaForm(xfaElement: HTMLElement): { isValid: boolean; errors: string[] };

377

```

378

379

**Usage Examples:**

380

381

```javascript

382

// Complete XFA form handling

383

class XfaFormHandler {

384

constructor(container, annotationStorage, linkService) {

385

this.container = container;

386

this.annotationStorage = annotationStorage;

387

this.linkService = linkService;

388

this.xfaElements = new Map();

389

this.eventHandlers = new Map();

390

}

391

392

async renderXfaPage(page, viewport) {

393

const xfaHtml = await page.getXfa();

394

395

if (!xfaHtml) {

396

return null; // No XFA content

397

}

398

399

const xfaDiv = document.createElement("div");

400

xfaDiv.className = "xfaLayer";

401

this.container.appendChild(xfaDiv);

402

403

const xfaResult = XfaLayer.render({

404

viewport: viewport,

405

div: xfaDiv,

406

xfaHtml: xfaHtml,

407

annotationStorage: this.annotationStorage,

408

linkService: this.linkService,

409

xfaHtmlFactory: new XfaHtmlFactory()

410

});

411

412

this.setupXfaEventHandlers(xfaResult.element);

413

this.xfaElements.set(page.pageNumber, xfaResult.element);

414

415

return xfaResult;

416

}

417

418

setupXfaEventHandlers(xfaElement) {

419

// Handle form field changes

420

xfaElement.addEventListener('change', (event) => {

421

const field = event.target;

422

if (field.name) {

423

this.annotationStorage.setValue(field.name, this.getFieldValue(field));

424

this.triggerCalculations();

425

}

426

});

427

428

// Handle validations

429

xfaElement.addEventListener('blur', (event) => {

430

const field = event.target;

431

if (field.name && field.required && !field.value) {

432

this.showValidationError(field, "This field is required");

433

}

434

});

435

}

436

437

getFieldValue(field) {

438

switch (field.type) {

439

case 'checkbox':

440

return field.checked;

441

case 'radio':

442

return field.checked ? field.value : null;

443

case 'select-one':

444

return field.value;

445

case 'select-multiple':

446

return Array.from(field.selectedOptions).map(opt => opt.value);

447

default:

448

return field.value;

449

}

450

}

451

452

triggerCalculations() {

453

// Find all calculated fields and update them

454

this.xfaElements.forEach(element => {

455

const calculatedFields = element.querySelectorAll('[data-calculate]');

456

calculatedFields.forEach(field => {

457

const expression = field.dataset.calculate;

458

try {

459

const result = this.evaluateExpression(expression);

460

field.value = result;

461

this.annotationStorage.setValue(field.name, result);

462

} catch (error) {

463

console.warn('Calculation error:', error);

464

}

465

});

466

});

467

}

468

469

evaluateExpression(expression) {

470

// Simple expression evaluator (implement based on XFA spec)

471

// This would need a full XFA expression parser in practice

472

return expression;

473

}

474

475

showValidationError(field, message) {

476

// Show validation error UI

477

field.classList.add('error');

478

const errorDiv = document.createElement('div');

479

errorDiv.className = 'validation-error';

480

errorDiv.textContent = message;

481

field.parentNode.appendChild(errorDiv);

482

483

setTimeout(() => {

484

field.classList.remove('error');

485

errorDiv.remove();

486

}, 3000);

487

}

488

489

getFormData() {

490

const formData = {};

491

this.xfaElements.forEach(element => {

492

const fields = element.querySelectorAll('input, select, textarea');

493

fields.forEach(field => {

494

if (field.name) {

495

formData[field.name] = this.getFieldValue(field);

496

}

497

});

498

});

499

return formData;

500

}

501

502

setFormData(data) {

503

this.xfaElements.forEach(element => {

504

Object.entries(data).forEach(([name, value]) => {

505

const field = element.querySelector(`[name="${name}"]`);

506

if (field) {

507

this.setFieldValue(field, value);

508

}

509

});

510

});

511

}

512

513

setFieldValue(field, value) {

514

switch (field.type) {

515

case 'checkbox':

516

case 'radio':

517

field.checked = Boolean(value);

518

break;

519

case 'select-multiple':

520

Array.from(field.options).forEach(option => {

521

option.selected = Array.isArray(value) && value.includes(option.value);

522

});

523

break;

524

default:

525

field.value = value || '';

526

}

527

528

// Trigger change event

529

field.dispatchEvent(new Event('change', { bubbles: true }));

530

}

531

}

532

```

533

534

### CSS Styling

535

536

Required CSS for XFA form display:

537

538

```css

539

.xfaLayer {

540

position: absolute;

541

left: 0;

542

top: 0;

543

transform-origin: 0% 0%;

544

line-height: 1.2;

545

}

546

547

.xfaLayer * {

548

color: inherit;

549

font: inherit;

550

font-style: inherit;

551

font-weight: inherit;

552

font-kerning: inherit;

553

letter-spacing: -0.01px;

554

}

555

556

.xfaLayer input,

557

.xfaLayer textarea,

558

.xfaLayer select {

559

background-color: rgba(0, 54, 255, 0.13);

560

border: 1px solid transparent;

561

border-radius: 2px;

562

padding: 2px;

563

}

564

565

.xfaLayer input:focus,

566

.xfaLayer textarea:focus,

567

.xfaLayer select:focus {

568

background-color: rgba(0, 54, 255, 0.13);

569

border: 1px solid rgba(0, 54, 255, 1);

570

outline: none;

571

}

572

573

.xfaLayer .validation-error {

574

color: red;

575

font-size: 12px;

576

margin-top: 2px;

577

}

578

579

.xfaLayer input.error {

580

border-color: red;

581

background-color: rgba(255, 0, 0, 0.1);

582

}

583

```