Skip to main content
Known Participant
May 13, 2016
Question

How do I convert the following Document level JS into a script in the document?

  • May 13, 2016
  • 12 replies
  • 2706 views

Here is the DLJ (Document Level Javascript) I want to convert to a script in a field in the document:

function getRanksValue(doc, name) {

    var rank = doc.getField(name).value;

    var value = 0;

    if (rank < 1) {

        value = -25;

    } else if (rank > 20) {

        value = 10 * 5 + 10 * 2 + (rank - 20);

    } else if (rank > 10) {

        value = 10 * 5 + (rank - 10) * 2;

    } else {

        value = rank * 5;

    }    return value;

}

The following is the script in a "Consolidated Script" field, where line 2 has the script that calls that DLJ:

for (var i=0;i<115;i++)

  this.getField("Rank Bns."+i).value = getRanksValue(this, "Ranks"+i);

  for (var ii=0;ii<115;ii++)

  this.getField("Total Bns."+ii).value = Number(this.getField("Rank Bns."+ii).value) + Number(this.getField("Stat Bns."+ii).value)

  + Number(this.getField("Spec Bns."+ii).value);

  this.getField("Total Bns.44").value = Number(racialStatMods[this.getField("Race").value][10])

  + Number(this.getField("Rank Bns.44").value) + (this.getField("Stat Bns.44").value) + Number(this.getField("Spec Bns.44").value);

  this.getField("Total Bns.45").value = Number(racialStatMods[this.getField("Race").value][11])

  + Number(this.getField("Rank Bns.45").value) + Number(this.getField("Stat Bns.45").value) + Number(this.getField("Spec Bns.45").value);

  this.getField("Total Bns.46").value = Number(racialStatMods[this.getField("Race").value][12])

  + Number(this.getField("Rank Bns.46").value) + Number(this.getField("Stat Bns.46").value) + Number(this.getField("Spec Bns.46").value);

It works as is but I am thinking it might be a little faster if I were to convert the DLJ to work in place of the script in the second section of line 02 above where it calls the DLJ. It would remove the need to call the DLJ. I have been trying to figure this out not for a few hours and I have not gotten anywhere.

I hope someone can help me.

This topic has been closed for replies.

12 replies

Participant
June 12, 2016

Support for all video players options

Legend
May 14, 2016

The point is that the script as written expects something called "doc" and something called "name". You just need to be sure that these names exist. It's easy to overlook, for example, that inside a procedure you have a variable called "date" but it was called with "date_today". In unwrapping you just need to double check these things. I haven't.

MadmaxneoAuthor
Known Participant
May 14, 2016

There is nothing called doc nor anything called name in the document whatsoever. But that same script works fine as a DLJ. In that script I believe that doc is referring to the document and name is referring to the actual name of the field it is using to the number from.

Karl Heinz  Kremer
Community Expert
Community Expert
May 14, 2016

That is exactly the point that TSN tried to make. Let me try to explain it coming from a different angle:

You have a function that you define as follows (this is the code that you posted):

  1. function getRanksValue(doc, name) {   
  2.     var rank = doc.getField(name).value;   
  3.     var value = 0;   
  4.     if (rank < 1) {   
  5.         value = -25;   
  6.     } else if (rank > 20) {   
  7.         value = 10 * 5 + 10 * 2 + (rank - 20);   
  8.     } else if (rank > 10) {   
  9.         value = 10 * 5 + (rank - 10) * 2;   
  10.     } else {   
  11.         value = rank * 5;   
  12.     }    return value;   
  13. }

As you can see, your function takes two arguments: The first one is called "doc", the second one is called "name". These parameters declare local variables in this function, which means that you can use the "doc" and "name" variable, as long as you are within the function code (from the "{ to the "}" characters in line 1 and 13. Outside of this function, there are no variables named "doc" or "name" (that is, unless you declare them in a different scope).

You call this function using these two lines:

  1. for (var i=0;i<115;i++)   
  2.   this.getField("Rank Bns."+i).value = getRanksValue(this, "Ranks"+i); 

In line #2, you specify how the local variables from above should be set: The first one ("doc") is set to "this", and the second one ("name") is set to "Ranks"+i

When you unroll the function in order to move it into a field local script, you do no longer have access to "doc" and "name" - you need to replace them with the data that you pass into the function call (this and "Ranks"+i).

This is based JavaScript, and has nothing to do with Acrobat, or with how JavaScript is integrated in Acrobat. Do yourself a favor and learn about the syntax of the core JavaScript language. This is not something you can learn by just copying and pasting code snippets that you find on the internet.

Legend
May 13, 2016

Don't forget that the original procedure had parameters doc and name. You need to allow for this in the code; somehow make sure doc and name are correct.

MadmaxneoAuthor
Known Participant
May 13, 2016

Now that is kind of confusing. I am not sure why I would need the doc and name part because it is in the script on the document.

Legend
May 13, 2016


Yes, that's the first step. It may seem that {} have some obscure function to do with procedures and if statements, but all they really do is take a list of commands (with ; between them) and let you treat them as just one command.  So

if ( this )

do_one_thing; do_another_thing;

only does the first thing for the if, and does the other thing always. So you can use

if ( this )

{ do_one_thing; do_another_thing; }

Parentheses only are used on expressions, which are a smaller thing than a statement. If that's confusing: you can't have a semi-colon in an expression, so you can't have one inside parentheses. (Yes, oversimplification)

MadmaxneoAuthor
Known Participant
May 13, 2016

I originally tried that. I will again and post if it worked or not and what I tried tonight when I get home. Thanks for the help so far!

Legend
May 13, 2016

It's a multiline function. If you must "unwrap" it, to put in the for loop, then it has to be in { ... } . Curly brackets, not round brackets. Some languages will do exactly what you want, JavaScript cannot.

MadmaxneoAuthor
Known Participant
May 13, 2016

Hmm. So should I place the script in parenthesis "( )", or simply replace all the curly line brackets with parenthesis?

EDIT: I meant to say "I should put it in curly line brackets then?"

Legend
May 13, 2016

You can't write

something =

lots of lines ;

with semicolons ;

because the assignment (something = ...) will always, always end at a semicolon. You have to do the calculation in order and assign at the end.

MadmaxneoAuthor
Known Participant
May 13, 2016

That is what I figured. I tried it with "( )" amongst other things but still can't get it to work.

Just to reiterate I am trying to convert the following DLJ:

  1. function getRanksValue(doc, name) { 
  2.     var rank = doc.getField(name).value; 
  3.     var value = 0
  4.     if (rank < 1) { 
  5.         value = -25
  6.     } else if (rank > 20) { 
  7.         value = 10 * 5 + 10 * 2 + (rank - 20); 
  8.     } else if (rank > 10) { 
  9.         value = 10 * 5 + (rank - 10) * 2
  10.     } else
  11.         value = rank * 5
  12.     }    return value; 

To replace the call to that DLJ in the second part of line 02 (getRanksValue) in this script:

  1. for (var i=0;i<115;i++) 
  2.   this.getField("Rank Bns."+i).value = getRanksValue(this, "Ranks"+i); 
Legend
May 13, 2016

This script

for (var i=0;i<115;i++) 

this.getField("Rank Bns."+i).value =  

var rank = this.getField("Ranks"+i).value; 

var value = 0

if (rank < 1) {value = -25;}  

else if (rank > 20) {value = 10 * 5 + 10 * 2 + (rank - 20);}  

else if (rank > 10) {value = 10 * 5 + (rank - 10) * 2;}  

else {value = rank * 5;}; 

See line 2 is just " this.getField("Rank Bns."+i).value = "

so this merges with line 3 to get

"this.getField("Rank Bns."+i).value =  var rank = this.getField("Ranks"+i).value;"

Which doesn't seem (to me) to make sense.

And then the loop is finished, as I hope you can see. The first line after the loop is "var value=0;"

MadmaxneoAuthor
Known Participant
May 13, 2016

Ok so this if for the script I am attempting to write. This starts the script:

this.getField("Rank Bns."+i).value = 

This is the complete calculation script for that line:

  1.   var rank = this.getField("Ranks"+i).value; 
  2.     var value = 0
  3.     if (rank < 1) {value = -25;}

But it doesn't work like it should.

That last line goes into the rest of the script which references the first line.

I am not sure how to correct it.

Any suggestions?

Legend
May 13, 2016

I think something is cut off at the of line 2 as well.

MadmaxneoAuthor
Known Participant
May 13, 2016

Test Screen Name wrote:

In your final block of 8 lines, line 1 is a "for" statement. The only line that is repeated 115 times is line 2. Not what you hoped for I think.

Test Screen Name wrote:

I think something is cut off at the of line 2 as well.

Nope all the script is there. But which line 2 are you talking about? Is it one of the original scripts or the one I am trying to make?

Legend
May 13, 2016

In your final block of 8 lines, line 1 is a "for" statement. The only line that is repeated 115 times is line 2. Not what you hoped for I think.

MadmaxneoAuthor
Known Participant
May 13, 2016

Well that part is not really that slow as it is almost instantaneous. In a way that calculation for each of the 115 fields needs to be active because it needs to keep track of the total all the time.

Inspiring
May 13, 2016

Do you always update fields by using the "Calculation" option?

It might be possible to perform some of the field updates by using another action. For example. if I have 3 fields for the first name, middle initial and the last name and I want to combine them into one field like full name, instead of using a calculation script in the last name field, I could use the on blur action in the 3 name fields that would update the full name field. This would prevent the full name field from being updated each time the form is recalculated. You should be aware the form is recalculated each time any field used in a calculation is changed. So since the full name only needs to be updated when one of the name fields is updated there is no need to updated each time any field is updated. In a form with lots of calculations removing unnecessary calculations could significantly speed up the updating of the form.

If you have a large number of calculations and have them consolidated into on calculation script, you might want to turn off the auto calculations at the start of the script and turnit back on at the end of the script. As a script is run it updates each field with a calculation, does take some time, by turning the calculations off all this updating field displays is delayed until the auto calculation is turned on again.

The reason for consolidating a large number of calculations into a limited number of fields is that each field with a calculation needs to have the script opened, and interpreted over and over. There is some overhead with this processing of each form field so by consolidating all the code into a few fields removes some of the overhead.

Using document level scripts converts the text script into tokenized code once and not every time a calculation if processed.