AcroTeX PDF Blog - Formatting Numbers: Problems, Bugs ...



AcroTEX PDF Blog Formatting Numbers Problems, Bugs, Thoughts, and Solutions

D. P. Story

The following text fields, formatted to receive a number, are discussed in the article. The fields use comma (,) as the decimal point, for example 1234,56.

Enter a number:

(1)

(unprotected format script)

(2) 1234.56

(protected with try/catch)

(3) 1234.56

(protected by if)

(4) 1.234,56

(using setTimeOut trick)

(5) 1.234,56

(complete solution)

(6) 1.234,56

(using AFNumber methods)

These fields are referenced by number in the body of the article.

Copyright ? 2013 dpstory@ AcroTEX PDF Blog July 23, 2013

Published: July 23, 2013

Table of Contents

1 Introduction

3

1.1 The problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 ? Problem 1: Formatting is hidden . . . . . . . . . . . . . . . . . . . . . . . 3

? Problem 2: Field not formatted correctly for editing . . . . . . . . . . . . 4

? Problem 3: Document JavaScript loaded late . . . . . . . . . . . . . . . . 5

? Problem 4: The initialization problem . . . . . . . . . . . . . . . . . . . . 5 ? Problem 5: Time of loading of document JavaScript varies . . . . . . . . 6

2 Solutions

7

2.1 Problems 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

? Fields not on the opening page . . . . . . . . . . . . . . . . . . . . . . . . 7 ? Fields on the opening page . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.2 Problem 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.3 Using space as a block delimiter . . . . . . . . . . . . . . . . . . . . . . . . . 11

3 Final comments

12

Introduction

3

1. Introduction

Throughout this article ? unless otherwise noted ? all text fields are formatted in the 1.234,56 style; that is, period (.) is used as the block delimiter of the digits and comma (,) is used for the decimal point. The keystroke formatting allows the use of comma (,), but does not allow the use of period (.). Numbers are entered in the style of 1234,56 and are formatted to 1.234,56.

The use of a comma for a decimal place raises challenging problems for the script developer. The internal value of the text field must be maintained with the traditional period (.) as the decimal place, but the user must always be allowed to see and to use the comma (,) for the decimal place.

This article address problems associated with the custom formatting of number fields of this type. The user interface of Acrobat offers several number formats with or without a currency symbol. These number formatting styles are supported by the built-in methods AFNumber_Keystroke and AFNumber_Format provided by the AA/AR during installation.1 By setting the arguments for these JavaScript functions appropriately, each of the formats offered by the user interface may be obtained. Throughout this article, the arguments we use are

AFNumber_Keystroke(2, 2, 0, 0, "", true); AFNumber_Format(2, 2, 0, 0, "", true);

which correspond to comma for decimal place, period for block delimiter, and no currency symbol. For further reading on these built-in functions, see my article on my AcroTEX Blog:



There, beginning on page 8, formatting numbers is discussed and all the options available are given. The arguments for AFNumber_Keystroke and AFNumber_Format are documented there.

1.1. The problems

It is sometimes desired to write custom formatting methods that extend these builtin methods. There are several problems, however, associated with using the built-in methods as part of custom formatting methods.

? Problem 1: Formatting is hidden

When AFNumber_Keystroke is used within the keystroke script, the script becomes inaccessible through the user interface. Number format category appears on the Format tab of the Text Field Properties dialog box. Once you enter your custom script, you cannot access it again. Below is a simple-minded example.

Enter a number:

(Example: 1234,56)

After entering a number, check the console window, I've written some messages to it concerning the values variables keypage and forpage. Where are these messages

1Adobe Acrobat/Adobe Reader

Console

Introduction

4

coming from? If you open the Format tab of the Text Field Properties dialog box, you see the number format being used (1.234,56), but nothing else. My custom formatting his no longer accessible.

The text field above has the following script associated with it:

Keystroke Script:

var keypage = 4; if (event.willCommit)

console.println("The value of keypage is " + keypage);

AFNumber_Keystroke(2, 2, 0, 0, "", true);

Format Script:

var forpage = 4; console.println("The value of forpage is " + forpage); AFNumber_Format(2, 2, 0, 0, "", true);

This is the script, though you can't see it through the user interface. This is one problem.

? Problem 2: Field not formatted correctly for editing

If the built-in JavaScript functions AFNumber_Keystroke and AFNumber_Format are placed within enclosing functions at the document level, the field may not edit correctly.

At the document level, this document has the following functions defined:

function myNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend) { AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend)

} function myNumber_Format( nDec, sepStyle, negStyle, currStyle,

strCurrency, bCurrencyPrepend) { AFNumber_Format(nDec, sepStyle, negStyle, currStyle,

strCurrency, bCurrencyPrepend); }

The new formatting functions, myNumber_Keystroke and myNumber_Keystroke, simply pass their arguments to AFNumber_Keystroke and AFNumber_Keystroke without change. Wrapping the built-in functions like this causes several problems. For example, enter the number 1234,56 into the field below and commit the number by exiting the field by clicking outside the field, or tabbing away, or pressing the Enter key. Now, click on the text field and bring it into focus. What happens to the decimal point (,)?

Enter a number:

(Example: 1234,56)

Answer, it becomes a period decimal point (.). If you try to edit the number again by backspacing over the last digit, AA/AR complains. The period decimal point (.) should not be there in this format. You have delete the period (.) then you can edit the number.

The script for this field is visible, on the positive side, as can be verified by inspecting the format tab of the field properties dialog box.

Introduction

5

? Problem 3: Document JavaScript loaded late You may or may not have noticed the problem when you opened this file in Acrobat, an exception was thrown; it reads,

ReferenceError: myNumber_Format is not defined 3:Field:Format

It is generated by the text field (1) on the title page. At the time the file is first loaded, Acrobat formats all fields on the opening page using their defined formats. At this time, the Document JavaScripts have not been read yet. This problem occurs only when there are formatted fields on the opening page. You can see when the Document JavaScripts are read from the messages in the console window.

One fix is to enclose the formatting script in a try/catch pair. Refer to text field (2) on the cover page.

The text field (2), which has an initial and default values of 1234,56, has the following script associated with it:

Console

Format Script: try { myNumber_Format(2,2,0,0,"",true); } catch(e){}

Now, the exception is thrown for this field it is caught, no message appears in the console, but the field, text field (2), is not correctly formatted (1234,56 instead of 1.234,56).

An alternate approach is to protect the format function using an if operator:

Format Script: if (typeof myNumber_Format == "function") myNumber_Format(2,2,0,0,"",true);

This is the approach I favor later in the article. In any case, one problem partially solved. Contrast the behavior of text field (2) with this one:

Enter a number: 1.234,56

This text field uses AFNumber_Keystroke and AFNumber_Format directly. The initial value for the field is properly formatted and you can edit the number field as well.

? Problem 4: The initialization problem

As discussed in Problem 3, even when we protect the formatting function with try/ catch, the value is not formatted correctly. This is a problem even when the formatting function is defined! Consider the following text field

Enter a number: 1234.56

(Example: 1234,56)

Here on page 5, it is not necessary to protect the formatting function with the try/catch pair. No exception is thrown, yet the field is still not initialized properly. Now, press the Fmt Fld button in the right margin; the JavaScript should properly initialize the field.

Fmt Fld

var f=this.getField("AFNum10"); f.delay=true; f.delay=false;

Introduction

6

By setting Field.delay to true then to false, we force the AA/AR to (re-)format the field, even though there has been no change. That does the trick!

This initialization problem seems to be a bug. AA/AR do not behave consistently when it comes to the built-in functions and custom functions.

BUG!

? Problem 5: Time of loading of document JavaScript varies As noted in Problem 3, you may or may not have noticed the exception thrown for text field (1). Sometimes this exception is thrown and sometimes it is not. Now, assuming there is a custom formatted field on the opening page (usually the first page), we make the following observations.

? Exception thrown: Open the Acrobat application. Either drag and drop this file onto the Acrobat window, or open it through the menu system; the exception for text field (1) is thrown.

1 (1) Cover page text field 2 ReferenceError: myNumber_Format is not defined 3 2:Field:Format 4 (2) Cover page text field 5 (3) Cover page text field 6 (4) Cover page text field 7 !!! Using alternate approach 8 (5) Cover page text field 9 Processing myNumber_Format: AFNum5 10 Scanning Document JavaScripts! 11 (4) Cover page text field 12 Processing myNumber_Format: AFNum4 13 ...

Acrobat ? actually, the underlying JavaScript engine ? tries to format text field (1) on the cover page and throws an exception on line (2). Why? Because, Acrobat does not scan the Document JavaScripts until line (10). Line (7) is a hint of a fix in place for text field (4) discussed in section 2.1. The alternate approach manifests itself in lines (11) and (12).

? Exception not thrown: With the Acrobat application not open, double click on this file's icon on your desktop. Acrobat opens, the file appears, and no exceptions are thrown on the opening page.

1 Scanning Document JavaScripts! 2 (1) Cover page text field 3 (2) Cover page text field 4 ...

When the document is opened in this case, the Document JavaScripts are scanned early, line (1), no exception is thrown because my custom formatting functions are known; however, text fields (1) and (2) are still not properly initialized. Text field (4), which is properly formatted, contains a fix to this to this problem and is discussed in section 2.1.

7

This differences in timing are disturbing and represent an inconsistency and a problem for developers of formatting functions. We call it a bug. The crazy fix described is section 2.1 is would not be needed if the behavior of the first case matched the behavior of the second.

Problem 2 is a subproblem of Problem 5. The different loading times of the Document JavaScripts must be taken into consideration.

BUG!

2. Solutions

Essentially, there are two problems we address here, these are Problem 2 and Problem 4. Solutions must take into account the different loading times of the Document JavaScript for fields on the opening page. In this section we offer some proposed solutions to these two problems.

2.1. Problems 4

We look at the initialization problem with two cases: fields not on the opening page and fields on the opening page.

? Fields not on the opening page The Fmt Fld button seen during the discussion of Problem 4 is key to the solution I've chosen.

Enter a number: 1234.56

(Example: 1234,56)

If things go right, this field is correctly initialized to 1.234,56, yes? The verbatim listing for the custom format script is

1 console.println("formatting: "+ event.targetName); 2 myNumber_Format(2, 2, 0, 0, "", true); 3 event.target.delay=true; 4 event.target.delay=false;

Line (1) is for debugging purposes. Lines (3) & (4) force the reformatting for the field. You can also use this code:

1 console.println("formatting: "+ event.targetName); 2 event.target.delay=true; 3 myNumber_Format(2, 2, 0, 0, "", true); 4 event.target.delay=false;

In either case, the field is properly formatted with its initial value.

? Fields on the opening page

The problem is that the document level JavaScript have not necessarily been scanned when AA/AR initially formats the fields during the time when the document is being opened. The solution for this case is given in the formatting script of text field (4) on the cover page. The verbatim listing of the formatting script is given below.

Solutions

8

1 if (typeof myNumber_Format == "function"){

2

console.println("Processing myNumber_Format: "+event.targetName);

3

myNumber_Format(2, 2, 0, 0, "", true);

4

event.target.delay=true;event.target.delay=false;

5 } else {

6

console.println("!!! Using alternate approach");

7

var ofield4=event.target;

8

oTO4=app.setTimeOut('ofield4.delay=true;ofield4.delay=false;',250);

9}

Lines (1)?(5) is the solution to the previous case. Lines (5)?(10) is the proposed solution for this case. I've taken an approach different from using try/catch, instead, I test in line (1) whether the formatting function is defined: if yes, then lines (2)?(4) are executed; otherwise, lines (6)?(9) are executed.

When myNumber_Format is not a function (hasn't been loaded yet), we use the JavaScript method app.setTimeOut to wait a little while for the scripts to load, then we perform out trick of Field.delay=true followed by Field.delay=false, see line (8). The amount of delay for the time out method is 250 (milliseconds), this value can be made smaller. In line (2), we get the field object and save it as a variable for use 250 milliseconds later.

An alternative strategy to using app.setTimeOut is to use app.setInterval.

} else { console.println("!!! Using alternate approach"); var ofield4=event.target; oTO4=app.setInterval( 'if (typeof myNumber_Format == "function"){ ' + ' ofield4.delay=true;ofield4.delay=false;' + ' app.clearInterval(oTo4); }',25);

}

We can replace lines (5)?(9) in the previous numbered listing above with the code above. Here, every 25 ms we determine if myNumber_Format is defined, if it is, we use our Field.delay trick and terminate the interval polling. This code produces the initialization quicker. The app.setTimeOut code, on the other hand, waits a fixed length of time before using the Field.delay trick. If the document JavaScript have not been loaded after the this time, the initialization fails. I've set the waiting time at a generous 250 ms for this reason.

2.2. Problem 2

Now for some real craziness. The problem is to make the number editable, that is, when the field comes into focus, the decimal point presented is the comma. AA/AR does a lot of (undocumented) processing that, through trial and error, have been sussed out.

When a file is opened with a field on the page, any field that has format script, that format script is executed only. When using the built-in functions, AA/AR seems to set the field value as 1234.56 and the formatting value as 1.234,56 in some undocumented sort of way. When AFNumber_Keystroke and AFNumber_Format are exposed in the

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download