Reverting a Keystroke Event?

Forum for the PDF-XChange Editor - Free and Licensed Versions

Moderators: PDF-XChange Support, Daniel - PDF-XChange, Chris - PDF-XChange, Sean - PDF-XChange, Paul - PDF-XChange, Vasyl - PDF-XChange, Ivan - Tracker Software, Stefan - PDF-XChange

Zaragon
User
Posts: 4
Joined: Fri Aug 21, 2026 3:59 pm

Reverting a Keystroke Event?

Post by Zaragon »

Been working with this software for a couple years now and have finally hit something that I cannot figure out how to do and can't Google an answer anywhere to save my life.

I've got a document that needs to take different layouts based on the value in a specific dropdown field. These layouts are controlled by layers (OCGs). So I created a JavaScript function to do what I need. This function needs to be called on Document Open (because PDF apparently doesn't save layer visibility) and whenever the value in the dropdown box is changed.

I use the same script for both (checking for this.event.name === "Open" or this.event.willCommit). If the former is hit, I get the value of the dropdown box, skip all validations (assuming a saved document is in a valid state), and set the layer visibilities accordingly. Works fine.

If the latter is hit, though, I need to do some validations, because the layout change needs to be allowed/prohibited based on the contents of certain other fields. Think prohibiting changing to a layout that hides certain fields if those fields have values in them (that's not exactly what's going on, but close enough). The actual validation doesn't really matter because I have that part working too; it checks what it needs to check, and if it fails, provides a pop-up box letting you know what the problem is. (Interestingly enough, while that pop-up is displaying, the dropdown box shows the old value.)

My problem is that after the validation has failed, I can avoid making any changes to the layout (by skipping the section of the code that does the visibility changes), but I cannot find a good way to stop the update to the value in the dropdown box itself (which happens after the pop-up box is dismissed). For example, if the dropdown box is set to "Layout A", and I then change it to "Layout B" (which then fails the subsequent validation), the actual document layout will correctly remain "Layout A"--but the dropdown box will change to have "Layout B" as the value. If I then save and reload the document, then "Layout B" will take effect, because that was the value in the dropdown box when the document was saved (because it didn't revert).

What I need to know is, how do I stop it from updating the dropdown if the validation fails (or failing that, revert the dropdown value back to the original at the end of the Keystroke Action script)? I can use the following code to get the original (pre-changed) value of the field, and it works fine:

Code: Select all

let myFieldName = this.event.target.name;
let myField = this.getField(myFieldName);
let myOriginalValue = myField.value;
However none of the following work to change the field back (not that I expected the last one to, I was just trying anything I could think of):

Code: Select all

this.event.change = myOriginalValue;
this.event.changeEx = myOriginalValue;
this.event.value = myOriginalValue;
myField.value = myOriginalValue;
No matter what, it still updates to the new value. Printing out all the event object's keys at the end of the KeystrokeAction script shows the values I assigned (the new value is gone and the original is present), so I don't even understand where it is even getting the new value at that point.

Anyone have any suggestions on what might actually work for this?
User avatar
Daniel - PDF-XChange
Site Admin
Posts: 13155
Joined: Wed Jan 03, 2018 6:52 pm

Re: Reverting a Keystroke Event?

Post by Daniel - PDF-XChange »

Hello, Zaragon

Thank you for the post - someone else on the forums here may have a swifter answer for you, but I have raised this with the Dev team for review and assistance, when they are able.

Kind regards,
Dan McIntyre - Support Technician
PDF-XChange Co. LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
[email protected]
User avatar
Vasyl - PDF-XChange
Site Admin
Posts: 2496
Joined: Thu Jun 30, 2005 4:11 pm

Re: Reverting a Keystroke Event?

Post by Vasyl - PDF-XChange »

Hi Zaragon.

Can you provide a minimal example-pdf that demonstrates the problem?

Cheers.
PDF-XChange Co. LTD (Project Developer)

Please archive any files posted to a ZIP, 7z or RAR file or they will be removed and not posted.
Zaragon
User
Posts: 4
Joined: Fri Aug 21, 2026 3:59 pm

Re: Reverting a Keystroke Event?

Post by Zaragon »

Took me a little bit to code a minimal version. This should adequately demonstrate the issue--the idea is that Layout 1 is the default, and selecting Layout 2 should hide the data field and its label as long as it is empty. If the data field is not empty, it should refuse to hide the data layer, throw an alert, and revert the layout field back to Layout 1. As mentioned above, the code will not hide the layer and will throw the alert, but it is completely unable to revert the value in the Layout field. As a result, if the document is saved and reopened, it will hide the data layer even though it should have never allowed the layout to be set to Layout 2 in the first place.

I would recommend having the Javascript console open when changing the Layout value as the code has quite a bit of println debugging that ought to help diagnose the issue.
Layout Revert Bug.zip
You do not have the required permissions to view the files attached to this post.
User avatar
Vasyl - PDF-XChange
Site Admin
Posts: 2496
Joined: Thu Jun 30, 2005 4:11 pm

Re: Reverting a Keystroke Event?

Post by Vasyl - PDF-XChange »

Thanks for the sample pdf. We found the reason why your script doesn't work properly. You need to use the standard way of cancelling the keystroke event, via:

this.event.rc = false;

See documentation for event.rc.

By the way, in your script you used features of a newer version of the JS engine that we have in Editor, which will not work in Acrobat/Reader because they use much older version of the JS engine. So, instead of "let" and "includes(subStr)" it is better to use "var" and "indexOf(subStr)!=-1".
PDF-XChange Co. LTD (Project Developer)

Please archive any files posted to a ZIP, 7z or RAR file or they will be removed and not posted.
User avatar
Mathew
User
Posts: 895
Joined: Thu Jun 19, 2014 7:30 pm

Re: Reverting a Keystroke Event?

Post by Mathew »

Zaragon wrote: Fri Aug 21, 2026 9:09 pm This function needs to be called on Document Open (because PDF apparently doesn't save layer visibility)
In PDF XChange (not Reader) one can set the .initState property of the OCGs thus (I think there's a typo on the adobe page):

Code: Select all

// Set an initial state of an OCG to off
var ocgs = this.getOCGs();
ocgs[0].initState = ocgs[0].constants.states.off
https://opensource.adobe.com/dc-acrobat-sdk-docs/library/jsapiref/JS_API_AcroJS.html#initstate
Zaragon
User
Posts: 4
Joined: Fri Aug 21, 2026 3:59 pm

Re: Reverting a Keystroke Event?

Post by Zaragon »

Vasyl - PDF-XChange wrote: Mon Aug 24, 2026 7:04 pm Thanks for the sample pdf. We found the reason why your script doesn't work properly. You need to use the standard way of cancelling the keystroke event, via:

this.event.rc = false;

See documentation for [url=https://opensource.adobe.com/dc-acrobat-sdk-docs/library/jsapiref/JS_API_AcroJS.html#rc]event.rc[/url].
I have tried doing it this way, and while it does cancel the commit, it yanks the focus back to the field in question, which is quite jarring. Do you know why it does this? I would much prefer that it not do that, considering that since the value was already reverted, what I actually need to do is go to whatever field it is that is preventing the layout change.
Vasyl - PDF-XChange wrote: Mon Aug 24, 2026 7:04 pm By the way, in your script you used features of a newer version of the JS engine that we have in Editor, which will not work in Acrobat/Reader because they use much older version of the JS engine. So, instead of "let" and "includes(subStr)" it is better to use "var" and "indexOf(subStr)!=-1".
I don't really use Acrobat; I quit using it a long time ago for FoxIt and then moved to PDF-XChange when that stopped meeting my needs. I don't even have access to Adobe's Editor (it is not even remotely worth 20 USD/mo to me), and I don't usually have the Reader installed anywhere because it is a slow, bloated mess (so typical Adobe, really). I suppose I will have to install it on some machine somewhere, load the document in it, and fix what it complains about. Figuring out ahead of time what isn't allowed just seems like too much work when this is literally the only project I have ever used JavaScript in, especially since I am working with my code in VS code and copying it in to PDF-XChange Editor instead of using its built-in JavaScript editor.
User avatar
Mathew
User
Posts: 895
Joined: Thu Jun 19, 2014 7:30 pm

Re: Reverting a Keystroke Event?

Post by Mathew »

Seems to work if you change the keystroke action to set event.rc (or you can set it within the function):

Code: Select all

event.rc = changeLayout(event)
and return the appropriate rc from the function:

Code: Select all

function changeLayout(evt) {

...

		if (myRequirementsMet) {
		...
		} else {
		console.println("changeLayout: Reverting layout to ".concat(myOriginalValue, "..."));
		app.alert("Requirements not met.", 0);
		// this example is actually belt and suspenders: You can set the event.rc here and not have to set it directly on the keystroke:
		evt.rc = false;
		}
	}
  return evt.rc;
}
If you also set initState for the OCG, I think you can avoid running the script at document load, because it will show the initState at document load:

Code: Select all

          myLayer.state = true;
          myLayer.initState = myLayer.constants.states.on;
          
 ...
 
          myLayer.state = false;
          myLayer.initState = myLayer.constants.states.off;
Layout Revert Bug.pdf
You do not have the required permissions to view the files attached to this post.
Zaragon
User
Posts: 4
Joined: Fri Aug 21, 2026 3:59 pm

Re: Reverting a Keystroke Event?

Post by Zaragon »

Mathew wrote: Mon Aug 24, 2026 10:37 pm In PDF XChange (not Reader) one can set the .initState property of the OCGs thus (I think there's a typo on the adobe page):

Code: Select all

// Set an initial state of an OCG to off
var ocgs = this.getOCGs();
ocgs[0].initState = ocgs[0].constants.states.off
https://opensource.adobe.com/dc-acrobat-sdk-docs/library/jsapiref/JS_API_AcroJS.html#initstate
It works in a licensed version PDF-Xchange Editor, anyway... I haven't tried it in an unlicensed version. I did install a version of Acrobat Reader (god, that user interface...) and you are correct, it does not work there. Pops up a JavaScript console with a security error. Not even turning off all security and adding the document specifically to the trusted document list makes any difference.

Edit: Also, I have now tested it, and setting the event.rc does not seem to work in Acrobat Reader. It never reverts the field that I can see. I know it is triggering that code branch because I get the app.alert, but the Layout value doesn't reset like it does in PDF-XChange (jarring focus behavior aside). The Layout change itself works fine after wrapping the initState setting in a try/except (though of course it does not change the initial state like it does in PDF-XChange Editor).

I attached a newer version of the PDF to this post, maybe someone can see what I'm doing wrong?
Layout Revert Bug.pdf
You do not have the required permissions to view the files attached to this post.