Which product are you using?
PDF.js Express Plus
PDF.js Express Version
UI version: 8.4.1
Core version: 8.4.0
Build: NC8xMi8yMDIyfGI0OTc1YjFjZA==
WebViewer Server: false
Full API: false
Detailed description
How can I activate the SignatureWidgetAnnotation programmatically?
I would like to programmatically activate as if I were mouse-clicking the SignatureWidgetAnnotation.
I’ve tried something like this and it didn’t work:
const annots = annotationManager.getAnnotationsList().filter(
(annot: any) => annot instanceof Annotations.SignatureWidgetAnnotation,
);
annots[0].innerElement.click();
// or
const clickEvent = new Event('click');
annots[0].innerElement.dispatchEvent(clickEvent); // or with annots[0].firstChild, annots[0].firstChild.firstChild, ...
Thanks in advance!
Hello, I’m Ron, an automated tech support bot
While you wait for one of our customer support representatives to get back to you, please check out some of these documentation pages:
Guides:
APIs:
Forums:
Hello vicente,
What do you mean by ‘activate’ the SignatureWidgetAnnotation?
If you are trying to open the signature modal, you can do so like:
instance.UI.openElement('signatureModal')
Let me know if this works for you
Best regards,
Tyler Gordon
Web Development Support Engineer
PDFTron
Hello Tyler,
I would like to open the signature modal, but associated with the SignatureWidgetAnnotation that is already in the document, as if I were clicking the SignatureWidgetAnnotation with the mouse.
When I use “instance.UI.openElement('signatureModal')
”, a new Annotation is created without being associated with the pre-existing SignatureWidgetAnnotation.
So ‘activate’ would open the corresponding signatureModal of the SignatureWidgetAnnotation.
Programmatically simulate this click on “Sign here”:
Thanks,
Vicente.
Hello vicente,
Thank you for clarifying, this currently isn’t doable by just calling .click()
on the element, however you could customize the Sign Here
inner element to handle this using: PDFTron WebViewer Namespace: Annotations
Let me know if that works for you!
Best regards,
Tyler Gordon
Web Development Support Engineer
PDFTron
Hello Tyler,
Thanks for the reply!
I already customize it using Annotations.SignatureWidgetAnnotation.prototype.createSignHereElement
, but I basically do it for styling and text. How could I customize it for this purpose?
I saw that the setCustomCreateSignHereElementHandler
would give access to the Annotation, SignHereElement and Tool, but I already had access to them and didn’t know what to do.
Thanks,
Vicente!
Hello vicente,
Looking deeper into the backend of the code, it seems the modal is opened when the “locationSelected” event is triggered on the SignatureCreateTool. This means you can trigger it like so:
const signatureTool = documentViewer.getTool('AnnotationCreateSignature')
const signatureAnnotation = annotationManager.getAnnotationsList().filter( (annot) => annot instanceof Annotations.SignatureWidgetAnnotation);
signatureTool.addEventListener('locationSelected', ()=>{
console.log('triggered') // to double check the locationSelected event has been triggered
})
signatureTool.trigger(
'locationSelected',
[
{
x: signatureAnnotation[0].getX(),
y: signatureAnnotation[0].getY()
}, // this object being the pageCoordinates for the signature widget
signatureAnnotation[0] // the signature widget itself
]
)
Here are some links to the APIs used:
Let me know if this works for you!
Best regards,
Tyler Gordon
Web Development Support Engineer
PDFTron
Hello, Tyler!
The trigger signatureTool.trigger('locationSelected', ...)
is really opening the modal, unfortunately still not binding to the corresponding widget, but mainly not editing the signature location.
When I call the signatureTool.hasLocation()
function, it returns false
.
So when I try to call signatureTool.addSignature()
, I get the error: TypeError: this.location is null
;
I tried to do something like this:
signatureTool.addEventListener(
'locationSelected',
(pageCoordinates: any, annotation: any) => {
console.log('hasLocation', signatureTool.hasLocation());
},
);
signatureTool.addEventListener('signatureSaved', (annotations: any) => {
signatureTool.setSignature(annotations[0]);
signatureTool.addSignature();
});
signatureTool.trigger('locationSelected', [
{
pageNumber: signatureWidgetAnnotations[0].getPageNumber(),
x: signatureWidgetAnnotations[0].getX(),
y: signatureWidgetAnnotations[0].getY(),
},
signatureWidgetAnnotations[0],
]);
Look how is the flow:
Thanks,
Vicente.
Hello Vincente,
Whats needed before doing addSignature() is the .location of the tool, you could set the location of the tool to signature widget you are signing like so:
signatureTool.addEventListener('signatureSaved', (annotations) => {
signatureTool.setSignature(annotations[0]);
signatureTool.location = {
x: signatureAnnotation[0].getX(),
y: signatureAnnotation[0].getY(),
pageNumber: signatureAnnotation[0].PageNumber
}
signatureTool.addSignature();
});
Best regards,
Tyler Gordon
Web Development Support Engineer
PDFTron
Hello, Tyler!
Yes, that worked for me, but it’s still not binding the annotation
to the widget
. See in the gif I sent earlier that the annotation
and the widget
are at the same time in the document.
I’ve already tried looking for some property of the signatureTool
in the documentation like the .location
, but I couldn’t find it. I tried this link that has the types, but I didn’t find it either.
Is there any easy way to do this? So that when I delete the annotation
, the widget
reappears.
In the same way as in the normal flow:
Thanks,
Vicente.
Hello Vicente,
You can set the associated annotation to the widget with: setAssociatedSignatureAnnotation()
I was able create the behaviour here:
documentViewer.addEventListener('annotationsLoaded', ()=>{
const signatureTool = documentViewer.getTool('AnnotationCreateSignature')
const signatureAnnotation = annotationManager.getAnnotationsList().filter( (annot) => annot instanceof Annotations.SignatureWidgetAnnotation);
signatureTool.addEventListener(
'locationSelected',
(pageCoordinates, annotation) => {
console.log('hasLocation', signatureTool.hasLocation());
},
);
signatureTool.addEventListener('signatureSaved', async (annotations) => {
signatureTool.setSignature(annotations[0]);
signatureTool.location = {
x: signatureAnnotation[0].getX(),
y: signatureAnnotation[0].getY(),
pageNumber: signatureAnnotation[0].PageNumber
}
// set the associated signature annotation to the signature widget annotation
signatureAnnotation[0].setAssociatedSignatureAnnotation(annotations[0])
signatureTool.addSignature();
});
annotationManager.addEventListener('annotationChanged', (annotations, action) => {
if(action == 'delete') {
// check if the annotation that was removed was a signature
if(annotations[0].Subject == "Signature") {
// remove set the associated Signature annotation to null, **this sill show the 'Sign here' element**
signatureAnnotation[0].setAssociatedSignatureAnnotation(null);
}
}
})
signatureTool.trigger(
'locationSelected',
[
{
x: signatureAnnotation[0].getX(),
y: signatureAnnotation[0].getY()
},
signatureAnnotation[0]
]
)
})```
Let me know if this works for you,
Best regards,
Tyler Gordon
Web Development Support Engineer
PDFTron
Hello, Tyler!
No, unfortunately it didn’t work for me. In fact, when I use signatureAnnotation[0].setAssociatedSignatureAnnotation(null)
and delete the annotation
manually, the widget
is still styled display none
. Even if I follow the normal flow of clicking the widget
I noticed that the default behavior of PDF.js Express is to delete the annotation
of the document but still remain associated with the widget
. That is, even after deleting the annotation
and calling getAssociatedSignatureAnnotation()
, the annotation
will still be there, it will not be null
.
Thanks,
Vicente!
Hello vicente,
Can you try this code snippet?
const signWidget = () => {
const signatureWidget = annotationManager.getAnnotationsList()
.find(annotation => annotation instanceof Annotations.SignatureWidgetAnnotation);
const signatureTool = documentViewer.getTool('AnnotationCreateSignature')
signatureTool.addEventListener('signatureReady', async (annotation) => {
let signatureWidgetRect = signatureWidget.getRect();
// Get min scale to fit the signature widget
const hScale = signatureWidgetRect.getHeight() / annotation['Height'];
const wScale = signatureWidgetRect.getWidth() / annotation['Width'];
const scale = Math.min(hScale, wScale);
const resizeRect = new Core.Math.Rect(
signatureWidgetRect['x1'],
signatureWidgetRect['y1'],
signatureWidgetRect['x1'] + annotation['Width'] * scale,
signatureWidgetRect['y1'] + annotation['Height'] * scale,
);
annotation.resize(resizeRect);
signatureWidget.setAssociatedSignatureAnnotation(annotation)
});
signatureTool.location = {
x: signatureWidget.getX(),
y: signatureWidget.getY(),
pageNumber: signatureWidget.PageNumber
}
signatureTool.trigger(
'locationSelected',
{
pageNumber: signatureWidget.PageNumber,
x: signatureWidget.X,
y: signatureWidget.Y,
},
signatureWidget
)
}
I think there was a logic error in the one I sent prior
Best regards
Tyler Gordon
Web Development Support Engineer
PDFTron
1 Like
Hello, Tyler!
The code snippet helped me a lot. Thank you so much! I was also needing to resize the annotation
and now I can.
But it still doesn’t work like the normal flow of clicking the widget
. For that, I did two more things:
- I hid the widget after adding the annotation
signatureTool.addEventListener('signatureReady', async (annotation) => {
... // your code here
signatureWidget.innerElement.style.display = 'none';
});
- Listen for the delete annotation event and shows the widget again
annotationManager.addEventListener(
'annotationChanged',
(annotations, action) => {
if (action === 'delete') {
const signatureWidget = annotationManager
.getAnnotationsList()
.find( (annot) =>
annot instanceof Annotations.SignatureWidgetAnnotation &&
annot.getAssociatedSignatureAnnotation()?.Id === annotations[0].Id);
signatureWidget.innerElement.style.display = 'block';
}
},
);
I believe the problem is now resolved.
Thanks a lot again, it helped me a lot to get to know PDF.js Express better.
Best regards,
Vicente!