Introduction:
Capturing a user’s handwritten signature directly within an Oracle APEX application is a powerful way to streamline approvals, confirmations, and form submissions without relying on paper-based processes. By building a digital signature pad using only JavaScript for the drawing interface and PL/SQL for storing the signature data, we can create an entirely browser-based solution that works across devices. This approach allows signatures to be drawn on a touchscreen or with a mouse, saved instantly into the database (as a BLOB), and retrieved later for display or verification — all without requiring third-party plug-ins or complex integrations.
Why we need to do:
In many business workflows — such as approvals, delivery confirmations, consent forms, and internal audits — a handwritten signature is essential for authenticity and compliance. Traditionally, this involves printing, signing, scanning, and uploading documents, which is slow, error-prone, and inconvenient. A digital signature pad in Oracle APEX eliminates these inefficiencies by:
- Speeding up Processes– Capture and store signatures instantly during form submission.
- Reducing Paper Usage– Move towards a paperless, eco-friendly workflow.
- Enhancing User Experience– Allow signatures directly on mobile devices or desktops.
- Improving Data Security– Store signatures securely in the database for future verification.
- Supporting Remote Work– Enable approvals from anywhere without physical presence.
By integrating the signature pad directly into APEX, we make the process seamless, secure, and user-friendly.
How do we solve:
Create a Static Content Region Go to the page where you want to capture the signature. Create a new Region ->Type: Static Content ->Template: StandardIn the Source section, paste the following HTML:
<canvas id=”signature-pad” style=”border:1px solid black; width:100%; height:300px;”></canvas>
- Create a Hidden Page Item
Create a hidden page item:
Name: P552_SIGNATURE_BASE64
This will store the Base64 value of the signature image.
- Add Buttons
Create three buttons:
CAPTURE → stores the signature.
CLEAR → clears the canvas.
SAVE → submits the signature into the database.
Set the Static IDs:
SAVED → for the Capture/Save button.
customClearButton → for the Clear button.
- JavaScript for Signature Drawing
Go to Function and Global Variable Declaration in your page and paste:
window.onload = function () {
var canvas = document.getElementById(‘signature-pad’);
var context = canvas.getContext(‘2d’);
var drawing = false;
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
canvas.addEventListener(‘mousedown’, function (e) {
drawing = true;
context.beginPath();
context.moveTo(e.offsetX, e.offsetY);
});
canvas.addEventListener(‘mousemove’, function (e) {
if (drawing) {
context.lineTo(e.offsetX, e.offsetY);
context.stroke();
}
});
canvas.addEventListener(‘mouseup’, function () {
drawing = false;
});
document.getElementById(‘SAVED’).addEventListener(‘click’, function () {
var signatureData = canvas.toDataURL();
if (signatureData && signatureData !== “data:,”) {
$s(“P552_SIGNATURE_BASE64”, signatureData);
apex.submit({
request: “SAVE_SIGNATURE”,
set: { “P552_SIGNATURE_BASE64”: signatureData }
});
} else {
alert(‘Please sign the field before saving!’);
}
});
loadSignatureImage();
};
5. Load Signature on Page Load
Add this Function and Global Variable Declaration
function loadSignatureImage() {
var signatureData = $v(“P552_SIGNATURE_BASE64”);
if (signatureData && signatureData !== “data:,”) {
var canvas = document.getElementById(“signature-pad”);
var context = canvas.getContext(“2d”);
var image = new Image();
image.onload = function () {
context.drawImage(image, 0, 0, canvas.width, canvas.height);
};
image.src = signatureData;
}
}
6. Clear Canvas and Page Item
In Execute When Page Loads, and Paste:
document.getElementById(“customClearButton”).addEventListener(“click”, function () {
var canvas = document.getElementById(“signature-pad”);
var context = canvas.getContext(“2d”);
context.clearRect(0, 0, canvas.width, canvas.height);
$s(“P552_SIGNATURE_BASE64”, “”);
});
7. PL/SQL Process to Save Signature
Create a PL/SQL Process with Request = SAVE_SIGNATURE and paste:
plsql
CopyEdit
DECLARE
v_signature_blob BLOB;
v_base64_data CLOB;
l_sign_id NUMBER;
l_mime_type VARCHAR2(100);
l_filename VARCHAR2(200);
BEGIN
SELECT NVL(MAX(SIGN_ID), 0) + 1 INTO l_sign_id FROM KS_SIGNATURES;
l_mime_type := ‘image/png’;
l_filename := ‘-sign-‘ || TO_CHAR(SYSDATE, ‘YYYYMMDDHH24MISS’) || ‘.png’;
IF :P552_SIGNATURE_BASE64 IS NOT NULL AND LENGTH(:P552_SIGNATURE_BASE64) > 0 THEN
v_base64_data := REGEXP_REPLACE(:P552_SIGNATURE_BASE64, ‘^data:image/png;base64,’, ”);
v_signature_blob := UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW(v_base64_data));
INSERT INTO KS_SIGNATURES (
SIGN_ID, SIGN_NAME, SIGN_TYPE, SIGN_DATE, CREATION_DATE, CREATED_BY, SIGN_FILE
) VALUES (
l_sign_id, l_filename, l_mime_type, SYSDATE, SYSDATE, :APP_USER, v_signature_blob
);
ELSE
RAISE_APPLICATION_ERROR(-20002, ‘Base64 string is null or empty.’);
END IF;
END;
Conclusion:
This implementation enables you to seamlessly capture and store digital signatures within Oracle APEX using a simple yet effective combination of HTML5 Canvas, JavaScript, and PL/SQL. Users can draw their signatures directly on the page, clear them when necessary, and save them as Base64-encoded images, which are then securely stored as BLOBs in the database. The process is lightweight, requiring no third-party plugins, and is highly reusable for various application scenarios such as approvals, acknowledgments, and confirmations. By integrating this feature, your application becomes more interactive, user-friendly, and efficient, while promoting a secure, paperless workflow.