Hello Kevin Kim,
No, Here we are trying to achieve a sign page in which signature fields are already present on pdf. The thing we aretrying to achieve is user opens that page and sign the document. So in that page user should only be able to add signatures to the signature field he shouldn’t be able to modify those signature fields ( like move those signature fields or modify (delete) those signature fields but he should be able to add the signatures to signature fields. This is what i am trying to achieve. I tried different ways using the apryse documentation but i couldn’t achieve exact result for that page. So could you please help me find a solution or atleast point me a documentation of apryse webviewer which could helpful for me to make that work.
The problem with your suggested code this makes the user can only sign the signature field just one time. the user will not able to modify his signature once he signs the signature field but he can still delete the signature field. but i am not asking about the signature i am asking for the signature fields. Hoping that the code of our page would help the cause so i am pasting the code we are using in our sign page.
WebViewer(
{
path: "/webviewer/lib",
initialDoc: initialDocument,
fullAPI: true,
licenseKey,
disabledElements: [
"dropdown-item-toolbarGroup-Annotate",
"dropdown-item-toolbarGroup-Shapes",
"dropdown-item-toolbarGroup-Insert",
"dropdown-item-toolbarGroup-Edit",
"dropdown-item-toolbarGroup-Forms",
"dropdown-item-toolbarGroup-Drop",
"toolbarGroup-Annotate",
"toolbarGroup-Shapes",
"toolbarGroup-Insert",
"toolbarGroup-Edit",
"toolbarGroup-Forms",
"toolbarGroup-Drop",
"contextMenuPopup",
"textPopup",
"rubberStampToolGroupButton",
"freeTextToolGroupButton",
"crossStampToolButton",
"checkStampToolButton",
"dotStampToolButton",
"dateFreeTextToolButton",
"variables",
"freeHandToolGroupButton",
"menuButton",
],
},
viewer.current,
)
.then((instance) => {
wvInstance.current = instance;
const { UI, Core } = instance;
const {
documentViewer,
annotationManager,
Annotations,
Tools,
PDFNet,
} = Core;
setAnnotationManager(annotationManager);
UI.setToolMode("selectToolButton");
const signatureTool: any = documentViewer.getTool(
"AnnotationCreateSignature",
);
const handleSaveFile = async () => {
const doc = documentViewer.getDocument();
const xfdfString = await annotationManager.exportAnnotations({
widgets: true,
fields: true,
});
const data = await doc.getFileData({ xfdfString});
const arr = new Uint8Array(data);
const blob = new Blob([arr], { type: "application/pdf" });
instance.UI.loadDocument(blob);
const base64Data: any = await blobToBase64(blob);
localStorage.setItem(
`contract_pdf_${contract.FilePath}`,
base64Data,
);
toast.success("Signatures saved successfully!");
};
UI.setHeaderItems((header) => {
header.push({
type: "actionButton",
img:
theme === "dark"
? "/icons/wvsave_dark.svg"
: "/icons/wvsave_light.svg",
dataElement: "CustomSave",
onClick: handleSaveFile,
});
});
const checkDocumentHasSignature = async () => {
documentViewer
.getAnnotationsLoadedPromise()
.then(async () => {
const signatureWidgetAnnots = annotationManager
.getAnnotationsList()
.filter(
(annot) =>
annot instanceof Annotations.SignatureWidgetAnnotation,
);
let allFieldsHasSignature = false;
for (let i = 0; i < signatureWidgetAnnots.length; i++) {
const widgetAnnot = signatureWidgetAnnots[i] as any;
const isSigned =
(await widgetAnnot.isSignedDigitally()) as boolean;
if (!isSigned) {
allFieldsHasSignature = false;
break;
} else {
allFieldsHasSignature = true;
}
}
if (allFieldsHasSignature) {
instance.UI.disableElements([
"CustomSave",
"toolbarGroup-FillAndSign",
"annotationClearSignatureButton",
]);
}
})
};
const convertTemplatesToAnnotationString = async () => {
let xfdfString = await annotationManager.exportAnnotations({
links: false,
widgets: true,
fields: true,
});
await annotationManager.importAnnotations(xfdfString);
const annotationList = annotationManager.getAnnotationsList();
const signAnnots: Array<number> = [];
annotationList.map(async (annot, index) => {
if (annot instanceof Annotations.SignatureWidgetAnnotation) {
signAnnots.push(index);
annot.NoMove = true ;
annot.NoDelete= true;
}
});
setSignatureList([...signAnnots]);
};
documentViewer.addEventListener("documentLoaded", async () => {
checkDocumentHasSignature();
convertTemplatesToAnnotationString();
});
instance.UI.NotesPanel.disableAutoExpandCommentThread();
signatureTool.setSigningMode(
instance.Core.Tools.SignatureCreateTool.SigningModes.APPEARANCE,
);
const normalStyles = (widget: any) => {
if (widget instanceof Annotations.SignatureWidgetAnnotation) {
return {
border: "1px solid #000000",
};
}
};
const widgetAnnot: any = Annotations.WidgetAnnotation;
annotationManager.addEventListener(
"annotationChanged",
(annotations, action, { imported }) => {
if (imported && action === "add") {
annotations.forEach(function (annot: any) {
if (annot instanceof Annotations.WidgetAnnotation) {
widgetAnnot.getCustomStyles = normalStyles;
}
});
}
},
);
wvInstance.current = instance;
setIsInitialized(true);
})
.catch((error) => {
console.error("Error initializing WebViewer:", error);
});
}
};
void initWebViewer();
}, [contract, isInitialized, theme]);
Thank you.