These forums are now Read Only. If you have an Acrobat question, ask questions and get help from one of our experts.

Text Field values as number? Adds extra characters...

ronlg
Registered: Oct 1 2008
Posts: 22

I am new to writing JavaScript for PDF's and am looking for some help with a problem I have been trying to solve.

The scenario:
I have multiple text fields that have their own unique values. However, there is one text field called "serial number" that has the same value on multiple areas of the PDF.

I have chosen to make a separate text field with it's own name. I know that you can have many of the same instances with the same name and it'll automatically populate the value throughout the document. I did not want it to work like this because the other instance(s) needed to be "read-only". These text fields have a maximum character limit of "18" and a minimum of "11". Here is the JavaScript I wrote to handle this task:

/* on Blur */

var sNum = this.getField("SERIAL1");
var cNum = this.getField("SERIAL2");

if (event.value.length < 11)
{
var msg = "Please enter more than 11 characters for the serial!";
app.alert(msg, 1, 0, "Character Limit Error");
sNum.fillColor = color.red
cName.value = "";
}

else
{
sNum.fillColor = color.transparent;
cNum.value = sNum.value;
}

/*end code*/

Well, it works... kind of. The problem I am running into is that the cNum (SERIAL2) value doesn't have the correct value if it is an all number value. However, if I add in an ASCII character, it works perfectly.

Is there a way to convert the text fields to display the true value?

Does any of this even make sense? ;)

Any help would be appreciated!

Regards,
Ron

My Product Information:
Acrobat Pro 8.1.2, Windows
George_Johnson
Expert
Registered: Jul 6 2008
Posts: 1876
ronlg wrote:
Well, it works... kind of. The problem I am running into is that the cNum (SERIAL2) value doesn't have the correct value if it is an all number value. However, if I add in an ASCII character, it works perfectly.
Can you give an example of a number you enter in SERIAL1 that does not copy over correctly to SERIAL2. Include what value does appear in SERIAL2.

George
ronlg
Registered: Oct 1 2008
Posts: 22
SERIAL1: 111111111111111111
SERIAL2: 111111111111111100

-another try-

SERIAL1: 555555555555555555
SERIAL2: 555555555555555600

-and another-

SERIAL1: 444444444444444444
SERIAL2: 444444444444444400



Looks like it is rounding to the nearest 100th; why?
George_Johnson
Expert
Registered: Jul 6 2008
Posts: 1876
That's an interesting problem. I would suggest modifying this code to the following:

var cNum = getField("SERIAL2"); if (event.value.length < 11) {var msg = "Please enter more than 11 characters for the serial!";app.alert(msg, 1, 0, "Character Limit Error");event.target.fillColor = color.red;cNum.value = "";} else {event.target.fillColor = color.transparent;cNum.value = event.value;}

Also, you'd normally use the Validate event for stuff like this, as opposed to the On Blur event. You can use the same code in the Validate event.

George
ronlg
Registered: Oct 1 2008
Posts: 22
Okay, I used it in Validate... same problem.


Now, this is ONLY if it is ALL numbers, if I put a letter or other character in there, it will come out proper.
George_Johnson
Expert
Registered: Jul 6 2008
Posts: 1876
Did you try the code I suggested?

George
ronlg
Registered: Oct 1 2008
Posts: 22
Yes - I forgot to mention that. Sorry! :)

Same issue with your suggested code.
ronlg
Registered: Oct 1 2008
Posts: 22
Okay, I started a new document and used 2 fresh text fields... they are working fine now.

What the heck?


Thank you for your time though - I really appreciate it!
gkaiseril
Online
Expert
Registered: Feb 23 2006
Posts: 4307
Set the length maximum length to 11 and use the following script for the validation:

// show what is going onconsole.show();console.clear();console.println("Serial 1 value: " + event.value);console.println("Serial 1 value length: " + event.value.length);console.println("Serial 1 value.toString(): " + event.value.toString() );console.println("Serial 1 value.toString() length: " + event.value.toString().length);console.println("(sNum.value.length < 11) : " + (event.value.length < 11) );console.println("(sNum.value.toString().length < 11) : " + (event.value.toString().length < 11) ); // set default statethis.getField(event.target.name).fillColor = color.transparent;var cNum = this.getField("SERIAL2");cNum.value = '';// test for correct length only when there is a value for the eventif (event.value.toString().length < 11 & event.value.toString() != ''){// error messageapp.alert("Please enter more than 11 characters for the serial!", 1, 0, "Character Limit Error");// highlight fieldthis.getField(event.target.name).fillColor = color.red;// set event return code for failure of testevent.rc = false;} elsecNum.value = event.value.toString();

You have to use the correct object for a given action and be careful about JavaScript's converting strings to numbers and numbers to strings. Sometimes this conversion depends on the user's version.

George Kaiser

George_Johnson
Expert
Registered: Jul 6 2008
Posts: 1876
In case you are wondering about the cause of your original problem, it has to do with the way numbers are represented internally in JavaScript. The short story is that the largest integer that is guaranteed to be represented exactly is 2^53, which is 9007199254740992. If you want the long story, read up on IEEE-754 floating point numbers.

What your original code was doing was getting the value of the field. Since it was a number, it was given a data type of number, as opposed to string. When you went to copy it to the other field, JavaScript got the value of the number, which it did not represent exactly, and set the other field's value to this inexact representation.

When you get the value of a field (by accessing a field's value property), the result can be one of several data types, including boolean, number, string, and even object (if it's an array). However, the data type of event.value in a field event will always be of type string. This is what the revised code does, so the text that is entered in SERIAL1 is copied correctly to SERIAL2 since it is copied as a string.

An alternative to using the value property is to use the valueAsString property, which will always be a string, but I thought it was better to spruce up the code a bit than to suggest this.

If you ever need to get the value of a field that may have leading zeroes or may be greater than 2^53, and if it might contain only digits, then you should use the valueAsString property if you want an exact copy.

George