Copy link to clipboard
Copied
Hi all,
Is there a way to remove an event from a form field (under the Actions tab) in Acrobat Pro DC (Mac) using JavaScript?
I’ve set events like
MouseUp, MouseDown, MouseEnter, MouseExit, OnFocus and OnBlur
with
setAction()
For some cases, I need to clear/remove the event completely.
Right now, I can do something like:
fieldName.setAction("OnBlur", " ");
This works, but feels more like a workaround than a true removal.
Is there a proper way to delete an existing action via JavaScript?
Thanks!
Copy link to clipboard
Copied
Hi. if you look at the JavaScript in the pdf file, I think what you are doing is fine.
//<AcroForm>
//<ACRO_source>Text1:Annot1:OnBlur:Action1</ACRO_source>
//<ACRO_script>
/*********** belongs to: AcroForm:Text1:Annot1:OnBlur:Action1 ***********/
console.println('onblur1')
//</ACRO_script>
//</AcroForm>
This is the code after the set action and
//<AcroForm>
//<ACRO_source>Text1:Annot1:OnBlur:Action1</ACRO_source>
//<ACRO_script>
/*********** belongs to: AcroForm:Text1:Annot1:OnBlur:Action1 ***********/
//</ACRO_script>
//</AcroForm>
so it is successful in doing what you mean, obviously if you create a function that would also need to be removed.
Copy link to clipboard
Copied
There is no way to use Acrobat JavaScript to remove an event script from a form field. You are correct that the only thing that can be done from JavaScript is to set the event script to an empty string. This is an easy and acceptable solution.
Here are 4 ways to remove the actual event script.
Copy link to clipboard
Copied
Hi. if you look at the JavaScript in the pdf file, I think what you are doing is fine.
//<AcroForm>
//<ACRO_source>Text1:Annot1:OnBlur:Action1</ACRO_source>
//<ACRO_script>
/*********** belongs to: AcroForm:Text1:Annot1:OnBlur:Action1 ***********/
console.println('onblur1')
//</ACRO_script>
//</AcroForm>
This is the code after the set action and
//<AcroForm>
//<ACRO_source>Text1:Annot1:OnBlur:Action1</ACRO_source>
//<ACRO_script>
/*********** belongs to: AcroForm:Text1:Annot1:OnBlur:Action1 ***********/
//</ACRO_script>
//</AcroForm>
so it is successful in doing what you mean, obviously if you create a function that would also need to be removed.
Copy link to clipboard
Copied
Thanks
Copy link to clipboard
Copied
There is no way to use Acrobat JavaScript to remove an event script from a form field. You are correct that the only thing that can be done from JavaScript is to set the event script to an empty string. This is an easy and acceptable solution.
Here are 4 ways to remove the actual event script.
Copy link to clipboard
Copied
Thanks
Copy link to clipboard
Copied
Please note that in some cases, replacing the script with nothing or with a blank space does not work (doc level script, doc action scripts...).
That is why I prefer to replace scripts with two slashes, which works everywhere.
fieldName.setAction("OnBlur", "//");
Copy link to clipboard
Copied
Thanks @JR Boulay ,
A graphical user interface (GUI)-based Acrobat JavaScript utility has been developed to streamline the workflow for manipulating dynamic PDF form files. This add-on, integrated into the Tools pane of Acrobat Pro, enables users to perform folder-level batch processing. This functionality allows for the simultaneous injection or deletion of JavaScript code or scripts into multiple fields form documents, thereby automating a repetitive task that would otherwise require manual entry into individual fields or forms within each document.
var addToolButtonTrusted = app.trustedFunction(function() {
app.beginPriv();
try {
app.removeToolButton({ cName: "FormScriptUtility" });
} catch (e) {
// Ignore error if button doesn't exist
}
app.addToolButton({
cName: "FormScriptUtility",
cLabel: "Set Form Scripts",
cTooltext: "Set or remove custom scripts for multiple form fields",
cEnable: "event.rc = (app.doc != null);",
cExec: "launchFormScriptUtility();",
nPos: -1
});
app.endPriv();
});
addToolButtonTrusted();
var launchFormScriptUtility = app.trustedFunction(function() {
app.beginPriv();
var doc = app.activeDocs.length > 0 ? app.activeDocs[0] : this;
if (!doc) {
app.alert("No active document found.");
app.endPriv();
return;
}
if (doc.xfa && doc.xfa.form) {
app.alert("Dynamic XFA forms not supported.");
app.endPriv();
return;
}
// Build prefix list
var names = [];
try {
doc.syncAnnotScan();
for (var i = 0; i < doc.numFields; i++) {
var n = doc.getNthFieldName(i);
if (n) names.push(n);
}
} catch (e) {
app.alert("Error reading form fields: " + e);
app.endPriv();
return;
}
if (!names.length) {
app.alert("No fields found.");
app.endPriv();
return;
}
var prefixMap = {};
names.forEach(function(n) {
var m = n.match(/^(.+?)(?:\.(\d+))?$/);
prefixMap[m ? m[1] : n] = true;
});
var listItems = Object.keys(prefixMap).sort();
var dialog = {
initialize: function(dialog) {
dialog.load({
"ftxt": listItems.join("\n") || "No fields found",
"fpre": "",
"snum": "",
"enum": "",
"actn": "",
"scpt": "",
"delact": false
});
},
commit: function(dialog) {
var results = dialog.store();
this.fieldText = results["ftxt"] || "";
this.fieldPrefix = results["fpre"] || "";
this.startNum = parseInt(results["snum"] || "0", 10);
this.endNum = parseInt(results["enum"] || "0", 10);
this.action = results["actn"] || "";
this.script = results["scpt"] || "";
this.deleteAllActions = results["delact"] === true;
},
description: {
name: "Set Form Scripts",
elements: [{
type: "view",
width: 736,
height: 600,
align_children: "align_left",
elements: [
{ type: "static_text", name: "Step 1: Available Form Field Name Prefixes Lists", width: 736, height: 20, alignment: "align_center" },
{ type: "edit_text", item_id: "ftxt", width: 736, height: 110, multiline: true, readonly: true },
{ type: "static_text", name: "Enter the Field Name Prefix to Inject Code:", width: 736, height: 20, alignment: "align_center" },
{ type: "edit_text", item_id: "fpre", width: 150, height: 20 },
{ type: "view", align_children: "align_row", elements: [
{ type: "static_text", name: "Start Number:", width: 70, height: 20 },
{ type: "edit_text", item_id: "snum", width: 50, height: 20, char_width: 4 },
{ type: "static_text", name: "End Number:", width: 70, height: 20 },
{ type: "edit_text", item_id: "enum", width: 50, height: 20, char_width: 4 }
]},
{ type: "static_text", name: "Step 2: Enter Target Action (Validate, Calculate, Keystroke, Format, MouseUp, MouseDown, MouseEnter, MouseExit, OnFocus, OnBlur):", width: 736, height: 20, alignment: "align_center" },
{ type: "edit_text", item_id: "actn", width: 150, height: 20 },
{ type: "static_text", name: "Step 3: Enter JavaScript Code (leave empty to delete action):", width: 736, height: 20, alignment: "align_center" },
{ type: "edit_text", item_id: "scpt", width: 736, height: 250, multiline: true },
{ type: "check_box", item_id: "delact", name: "Delete ALL actions from selected fields (overrides above settings)", width: 736, height: 20 },
{ type: "cluster", alignment: "align_right", elements: [{ type: "ok_cancel", ok_name: "OK", cancel_name: "Cancel" }] }
]
}]
}
};
if (app.execDialog(dialog) === "ok") {
var fieldPrefix = dialog.fieldPrefix || "";
var fieldPrefixes = fieldPrefix.split(",").map(function(p) { return p.trim(); }).filter(function(p) { return p; });
var startNum = dialog.startNum;
var endNum = dialog.endNum;
var action = dialog.action || "";
var script = dialog.script;
var deleteAllActions = dialog.deleteAllActions;
if (fieldPrefixes.length === 0) {
app.alert("Field Prefix cannot be empty.");
app.endPriv();
return false;
}
if (isNaN(startNum) || startNum < 0) {
app.alert("Start Number must be a valid non-negative number (0 or greater).");
app.endPriv();
return false;
}
if (isNaN(endNum) || endNum < 0) {
app.alert("End Number must be a valid non-negative number (0 or greater).");
app.endPriv();
return false;
}
if (startNum > endNum) {
app.alert("Start Number must be less than or equal to End Number.");
app.endPriv();
return false;
}
if (!deleteAllActions && !action) {
app.alert("Please enter a valid Target Action (e.g., Validate, Calculate, OnFocus).");
app.endPriv();
return false;
}
var validActions = ["Validate", "Calculate", "Keystroke", "Format", "MouseUp", "MouseDown", "MouseEnter", "MouseExit", "OnFocus", "OnBlur"];
if (!deleteAllActions && validActions.indexOf(action) === -1) {
app.alert("Invalid Target Action. Please use one of: " + validActions.join(", "));
app.endPriv();
return false;
}
var totalSuccessCount = 0;
var errorMessages = [];
fieldPrefixes.forEach(function(prefix) {
if (!prefix || typeof prefix !== "string") {
errorMessages.push("Skipping invalid prefix: " + prefix);
return;
}
var successCount = 0;
for (var i = startNum; i <= endNum; i++) {
var fieldName = prefix.endsWith(".") ? prefix + i : prefix + "." + i;
var field = doc.getField(fieldName);
if (field) {
try {
if (deleteAllActions) {
validActions.forEach(function(act) {
try {
field.setAction(act, " ");
field.setAction(act, "");
} catch (e) {
errorMessages.push("Error clearing " + act + " for " + fieldName + ": " + e);
}
});
successCount++;
} else if (script) {
field.setAction(action, script);
successCount++;
} else {
field.setAction(action, " ");
field.setAction(action, "");
successCount++;
}
} catch (e) {
errorMessages.push("Error " + (deleteAllActions ? "deleting all actions" : script ? "setting script" : "deleting script") + " for " + fieldName + ": " + e);
}
} else {
errorMessages.push("Field not found: " + fieldName);
}
}
totalSuccessCount += successCount;
});
if (totalSuccessCount === 0 && errorMessages.length === 0) {
app.alert("No fields were updated. Please provide a script or select 'Delete ALL actions'.");
app.endPriv();
return false;
}
if (errorMessages.length > 0) {
app.alert("Some fields could not be updated:\n" + errorMessages.join("\n"));
} else {
app.alert((deleteAllActions ? "All actions successfully deleted from " : script ? "Scripts successfully applied to " : "Scripts successfully deleted from ") +
totalSuccessCount + " fields across prefixes: " + fieldPrefixes.join(", "));
}
app.endPriv();
return true;
} else {
app.endPriv();
return false;
}
});
function getField(name) {
var doc = app.activeDocs.length > 0 ? app.activeDocs[0] : this;
return doc.getField(name);
}
Copy link to clipboard
Copied
It looks like a great tool, I will try it.
Thanks
Copy link to clipboard
Copied
Dear @JR Boulay @Thom Parker ,
We could perhaps further develop this utility. For example, instead of manually entering fields other than the Range and Code input text fields, we could use a drop-down menu to enter them.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now