Search code examples
itext7

How to detect which signature field is linked to the corresponding btn at run time?


I'd a document document.pdf which has some signature fields and their corresponding btn visible on the document. Using iText7, while iterating over the fields I can see both the sign btns and signature fields. How I can detect that which signature field is linked to corresponding sign btn at run time?


Solution

  • How I can detect that which signature field is linked to corresponding sign btn at run time?

    There is no link between button and signature field in the sense of a simple and specified entry in the button dictionary.

    All there is, is the JavaScript code executed when a button is clicked, e.g. for btn_sign:

    //Make sure the form is valid and then allow the signature.
    if (ValidateForm() == true)
    {
        if (this.dirty == true)
        {
            app.alert("Please save the form before signing, to ensure the proper saved name!");
        }
        else
        {
            app.alert("Please click anywhere in signature field to sign the form!\nThis will automatically save the form!", 3);
        
            //Enable the field
            this.getField("signature1").readonly = false;
            this.getField("signature1").display = display.visible;
    
            //Set focus
            this.getField("signature1").setFocus();
    
            //Disable the save button
            this.getField("btn_sign").readonly = true;
        }
    }
    

    Here you see that after some sanity checks the field signature1 is made active (not read-only anymore), visible, and in-focus. At the same time the button itself is made inactive (read-only).

    Similarly the JavaScript code executed when btn_sign2 is clicked, makes signature2 active, visible, and in-focus, and btn_sign2 itself inactive.

    To determine this interaction between button fields and signature fields in your document, you have to analyze the associated JavaScript code.

    You can retrieve the JavaScript code from a button field with iText 7 / Java like this:

    try (
        InputStream resource = getClass().getResourceAsStream("form_field_document.pdf");
        PdfReader pdfReader = new PdfReader(resource);
        PdfDocument pdfDocument = new PdfDocument(pdfReader);
    ) {
        PdfAcroForm pdfAcroForm = PdfAcroForm.getAcroForm(pdfDocument, false);
        PdfFormField btnSignField = pdfAcroForm.getField("btn_sign");
        PdfDictionary actionDictionary = btnSignField.getWidgets().get(0).getAction();
        if (PdfName.JavaScript.equals(actionDictionary.getAsName(PdfName.S))) {
            PdfObject jsObject = actionDictionary.get(PdfName.JS, true);
            if (jsObject instanceof PdfString) {
                System.out.print(((PdfString)jsObject).getValue());
            } else if (jsObject instanceof PdfStream) {
                PdfStream jsStream = (PdfStream)jsObject;
                System.out.print(new String(jsStream.getBytes()));
            }
        }
    }
    

    (ReadButtonAction test testReadSignButtonAction)