Hi all,
just wondering if it's possible to return a list of fields for each individual page? At present I've no problems getting a hold of the different pages and fields separately but curious if they have any sort of page/field relationship so they can be grouped together somehow.
For example, TextBox1 belongs to Page1, TextBox2 belongs to Page2, etc.
If that makes sense...
Cheers!
Hi - I am also curious about linking pages with fields, otherwise it feels like I'm flying blind. How are you at present listing out all of the fields on your pdf? And for that matter, have you figured out how to change the values on them? Trying to find in the docs rn but haven't had luck so far. Thanks
Hi - I am also curious about linking pages with fields, otherwise it feels like I'm flying blind. How are you at present listing out all of the fields on your pdf? And for that matter, have you figured out how to change the values on them? Trying to find in the docs rn but haven't had luck so far. Thanks
@jboxxx Have a sneaky peak at this for filling in form fields:
https://github.com/Hopding/pdf-lib/issues/48
As for the pages at present, I've basically saved out an individual PDF for each page, then when I've filled in each one, I merge them together at the end as one whole PDF. It's not ideal but seems to work for now. :)
Hello @sdfereday!
There is indeed such a relationship. A given form field belongs to a particular page if the form field's ref is in that page's Annots array.
I created an example script to demonstrate how this works:
// ...imports omitted...
const getAcroFieldRefs = (pdfDoc) => {
if (!pdfDoc.catalog.getMaybe('AcroForm')) return [];
const acroForm = pdfDoc.index.lookup(pdfDoc.catalog.get('AcroForm'));
if (!acroForm.getMaybe('Fields')) return [];
const acroFields = pdfDoc.index.lookup(acroForm.get('Fields'));
return acroFields.array;
};
const pdfDoc = PDFDocumentFactory.load(fs.readFileSync('./form.pdf'));
const fieldRefs = getAcroFieldRefs(pdfDoc);
console.log('REFS:', fieldRefs.map(String));
const pages = pdfDoc.getPages();
const page1AnnotsRaw = pdfDoc.index.lookupMaybe(pages[0].getMaybe('Annots'));
const page1Annots = page1AnnotsRaw ? page1AnnotsRaw.array : [];
const page2AnnotsRaw = pdfDoc.index.lookupMaybe(pages[1].getMaybe('Annots'));
const page2Annots = page2AnnotsRaw ? page2AnnotsRaw.array : [];
console.log('PAGE_1_ANNOTS:', page1Annots.map(String));
console.log('PAGE_2_ANNOTS:', page2Annots.map(String));
fieldRefs.forEach((fieldRef) => {
if (page1Annots.includes(fieldRef)) {
console.log(`${fieldRef.toString()} belongs to page 1`);
}
if (page2Annots.includes(fieldRef)) {
console.log(`${fieldRef.toString()} belongs to page 2`);
}
});
Here's the output of the script:
REFS: [ '46 0 R', '18 0 R', '47 0 R', '19 0 R' ]
PAGE_1_ANNOTS: [ '46 0 R', '47 0 R' ]
PAGE_2_ANNOTS: [ '18 0 R', '19 0 R' ]
46 0 R belongs to page 1
18 0 R belongs to page 2
47 0 R belongs to page 1
19 0 R belongs to page 2
And here's the form.pdf used in the script. It has one text field and one radio button per page (so 2 text fields and 2 radio buttons total).
I hope this helps. Please let me know if you have any additional questions!
That is fabulous! Thank you very much sir, that's definitely what I was after.
Is there a updated version of this for 1.0?
Plus 1 for updated version @Hopding
Hi @Hopding looks like the code snippet you posted for associating form fields with pages is outdated. Could you point me on how to accomplish the same with the latest API? Thanks a bunch!
In case anyone is looking for the updated version.
const fields = doc.getForm().getFields()
const page1AnnotsRaw = pages[0].node.lookupMaybe(PDFName.of('Annots'), PDFArray)
const page1Annots = page1AnnotsRaw ? page1AnnotsRaw.asArray() : [];
page1Annots.includes(fields[0].ref)
Most helpful comment
Hello @sdfereday!
There is indeed such a relationship. A given form field belongs to a particular page if the form field's ref is in that page's
Annotsarray.I created an example script to demonstrate how this works:
Here's the output of the script:
And here's the
form.pdfused in the script. It has one text field and one radio button per page (so 2 text fields and 2 radio buttons total).I hope this helps. Please let me know if you have any additional questions!