Tracking Mouse Clicks
I just recently received another comment from Zack. This time, he was wondering about how one would go about tracking mouse clicks on an image field.
I had never attempted to do that so I took it on as a challenge and thought I would share the results in this post.
I knew from the start that XFA alone wasn’t going to be able to handle this simply because (to my knowledge) it doesn’t provide any information as to the position of the mouse pointer when an event occurs. The most logical place I thought would’ve provided the information — the Event Pseudo Model (the xfa.event object available in all XFA events) — didn’t live up to my expectations. Thankfully, XFA at least provides a Click event so that I could know when the image got clicked.
The next logical place to look was in Acrobat’s Scripting Object Model (in the AcroForm Objects). In the Acrobat Document object, I found what I was looking for: the mouseX and mouseY properties which provided the location of the mouse with respect to the document window.
The last thing I needed was information about the dimensions and location (within the Acrobat Document Object’s coordinate space) of the image field and the Acrobat Field object’s rect property would give me just that.
The combination of the XFA Click event, the Acrobat Document object’s mouseX and mouseY properties and the Field object’s rect property was just what I needed to get this to work.
Of course, I soon discovered that I had another problem to figure-out: The behaviour of an image field in a PDF form running in Acrobat is that when clicked, it opens a browse dialog that lets you pick the content for the field. Unfortunately, there isn’t any way to suppress that dialog other than making the image field read-only or by using a static image object but then both alternatives prevent the Click event from firing. So I needed some clever way to capture a mouse click over an image (whether it was a field or a static object) and I decided to use a button with a transparent fill and no border (so it was essentially transparent). Since buttons are fields just like image fields, the mouseX, mouseY and rect properties would still be available for the button and if I sized the button to fit the image and placed it over-top, I would essentially end-up with an HTML <map>.
Minimum Requirements: Designer 7.1, Acrobat 7.0.5.
The first challenge was getting an instance of the Acrobat Field object which represents the button using the
event.target.getField
method. That was easily accomplished by using the script I provided on my AcroForm Field Name Generator article.
The next problem to be solved was the fact that the default behaviour, in Acrobat, for a button when it’s clicked is to invert its content area. Since I was trying to hide the button, I needed a way to suppress the inversion so that clicking on the button would give no visual feedback to the user. That way, it would give the impression that the user was actually clicking on some sort of hyperlink on the image itself. That was easily solved by using the highlight property of the Acrobat Field object representing the XFA button in its Enter event (had to be Enter and not Initialize because Initialize is too early in the form’s initialization process for the association between the XFA button and it’s Acrobat Field counterpart to be established):
event.target.getField(ScriptObject.GetFQSOMExp(this)).highlight =
highlight.n;
The last problem was with respect to calculating the coordinates of the hot spots on the button that would trigger a reaction (in this sample, I was just going to set the value of a text field somewhere else on the form to reflect the area that was clicked). The problem there was that while I had the mouse location and the button’s dimensions all in the same coordinate space (Acrobat Document), the coordinates were specified with (0,0) set to the document’s lower left corner.
While this may not seem like a big deal to some of you, it really messes me up when (0,0) isn’t at the top left corner (with the maximum (x,y) set to the bottom right corner). I guess that’s a result of years of writing code for Windows where an MFC CWnd’s coordinate space places (0,0) at the top left corner. Anyway, after lots of hair pulling, I finally figured-out how to properly calculate the hot spots in this strange — no, alien — coordinate system.
Zack, if you have any other questions, please post a comment.
Posted by Stefan Cameron on August 4th, 2006
Filed under AcroForm Objects,Scripting,Tutorials