Skip to main content
Inspiring
April 14, 2020
Answered

Calculating Check Boxes in columns to total at the bottom

  • April 14, 2020
  • 4 replies
  • 3401 views

I have a page with 12 columns of 31 checkboxes that are to be tabulated at the bottom of each column.

 

My field structure has the following naming convention:

 

check1.row    check2.row    check3.row...

check1.row1  check2.row1  check3.row1...

check1.row2  check2.row2  check3.row2....

...and so on down to row30 (which is the 31st row)

 

the bottom tabulation row goes like this...

check1.total   check2.total   check3.total....

 

I have a code from a recent similar situation I used as a start. I set the bottom total field as the target field. First I get the column names with a split and pop, then I get the array for the column. The loop starts by not adding the target field, and loops through the array to see if the checkbox value is not "Off" which will add one to the value if it counts. This would put the event value in the total. I'm not getting any syntax errors but it's not working.

 

I'm newer at this. I referenced another solution here for counting checkboxes and adding assorted scores to a total. Obviously there's something I'm missing here.

 

var aNameParts = event.targetName.split(".");
aNameParts.pop();
var strColName = aNameParts;
var oColFldList = this.getField(strColName);
oColFldList.getArray().forEach(function(a,i)
{if(a != event.target) event.value=Number(i?event.value:0);
if (a.value!="Off") Number+=1;});

 

 

 

This topic has been closed for replies.
Correct answer Bernd Alheit

Number++ looks not correct.

 

Try this:

var aNameParts = event.targetName.split(".");
aNameParts.pop();
aNameParts.pop();
aNameParts.push("value");
var strColName = aNameParts.join(".");
var oColFldList = this.getField(strColName);
var total = 0;
oColFldList.getArray().forEach(function(a,i,ar){if (a.value!="Off") total++;});
event.value = total;

4 replies

Inspiring
May 14, 2020

The correct answer also takes into account that spawnable pages of the form will create different prefixes on the field names. That need isn't evident in my original question.

JR Boulay
Community Expert
Community Expert
May 10, 2020

You use a very complicated way to reinvent the wheel when you don't even need JavaScript to do this type of calculation.

The creation of the attached document took me less than 3 minutes, each checkbox have a "1" export value, each "total" field uses only one calculation (Acrobat's buit in calculation), the "grandTotal" field too.

The only difference compared to your request is that I named the fields "total" in a more logical way.

 

See this great sample PDF: https://documentcloud.adobe.com/link/track?uri=urn%3Aaaid%3Ascds%3AUS%3A1c732995-09a8-4dc3-ab3b-661aa1d3f1ab

 

Acrobate du PDF, InDesigner et Photoshopographe
Inspiring
May 10, 2020

Oh it's a good example, JR, but I cannot use the built-in calculation because this document is going to have spawnable pages from a template to make copies, and each spawned page will have different field name prefixes. So I have to use the javascript code to take those different prefixes into account on new pages. If this was a one-pager situation then yes, I would have used the built-in calcation.

Inspiring
May 8, 2020

I'm back to this project after a delay. I have redone my column field structure to the following:

 

 

 

 

check1.value.row      check2.value.row      check3.value.row
check1.value.row 1    check2.value.row 1    check3.value.row 1
check1.value.row 2    check2.value.row 2    check3.value.row 2
"
"
check1.value.row 30   check2.value.row 30   check3.value.row 30
check1.calc.total     check2.calc.total     check3.calc.total

 

 

 

The "value" fields are checkboxes, the "calc" fields are text boxes for the results of the number of boxes.

 

I'm doing a spawnable template setup for adding pages. Those pages will add on more field names to the front, so the following script pops off the last two names to use the assorted possible front name combinations, joins "value" to the name, and is to get the array of checkboxes in the column and tally if they're on and add the totals. The script below goes in the "calc" fields.

 

I have the script set up, but when I paste into the custom calculation script I get a syntax error on the last line where it's assigning the total to the event.value. I do not understand why this is a wrong syntax. I have other projects with "event.value = total" in them.

 

 

 

 

var aNameParts = event.targetName.split(".");
aNameParts.pop();
aNameParts.pop();
aNameParts.push("value");
var strColName = aNameParts.join(".");
var oColFldList = this.getField(strColName);
var total = 0;
oColFldList.getArray().forEach(if (this.value!="Off")) total++;
event.value = total;

 

 

 

  

Inspiring
May 10, 2020

Okay, I figured out that I wasn't using forEach properly. It needed a function. So here is the new version. But I'm still getting a "syntax error 7: at line 8". 

 

 

var aNameParts = event.targetName.split(".");
aNameParts.pop();
aNameParts.pop();
aNameParts.push("value");
var strColName = aNameParts.join(".");
var oColFldList = this.getField(strColName);
oColFldList.getArray().forEach(function(a,i){event.value=Number(i?event.value:0) + (if (a.value!="Off") Number++;)});

 

 

I'm not getting something right. I look at the function line and to me it says, "Get the array from the chosen fields, and for each of them do this function (value, index): get the event value by using 'Number' and starting at zero, then go through the array items and see if an item's value as a checkbox is not 'Off'. If so, then add one to the total of 'Number' .)

 

This seems sound. But apparently, it's not.

Bernd Alheit
Community Expert
Bernd AlheitCommunity ExpertCorrect answer
Community Expert
May 10, 2020

Number++ looks not correct.

 

Try this:

var aNameParts = event.targetName.split(".");
aNameParts.pop();
aNameParts.pop();
aNameParts.push("value");
var strColName = aNameParts.join(".");
var oColFldList = this.getField(strColName);
var total = 0;
oColFldList.getArray().forEach(function(a,i,ar){if (a.value!="Off") total++;});
event.value = total;
Thom Parker
Community Expert
Community Expert
April 15, 2020

So are is the idea to count the number of checked boxes? Or to add up the export values?

 

I would suggest that since you are a beginner you write the code as a For Loop instead of using the shortcut "forEach" function. The loop makes it more explicit so you can follow what is happening in the code. 

In fact, I think you should write out the exact steps needed to accomplish the required task as a hierarchal list.

Before you can even begin to code you need to be able to follow your written list of steps to accomplish the goal. 

Thom Parker - Software Developer at PDFScriptingUse the Acrobat JavaScript Reference early and often
Inspiring
April 15, 2020

Hi Thom,

Thanks. What I'm wanting to do is count the number of "on" checkboxes and put the total in the bottom field. These are for dates of the month to be tabulated when an event happened for users. 

 

So I wrote up my need in commented form and did the coding within it. It seems sound what I've written but I have a syntax error message in the Calculation script window of "missing ; after for-loop initializer 11: at line 12". I looked up the Mozilla reference on for-loops and it looks like I have the proper ; between the initialization and the condition. I read I don't need a final expression (optional), and that's good because both of my if statements below cover the target field as getting 0 and if the field is not "off" so the field gets counted.

 

// the total field has the same prefix as the checkboxes above it of check1.total, checkboxes are check1.row, etc. Split and pop off the end for the name of the column
var aNameParts = event.targetName.split(".");
aNameParts.pop();
//put the column name in a variable
var strColName = aNameParts;
//get the fields of the column and put in variable
var oColFldList = this.getField(strColName);
//take the array of fields from the column list
oColFldList.getArray();
//go through the list, if the field value is not Off, then add one to the count, the event target gets a value of 0
for (let i = 0 ; i < oColFldList.length;) {
    if(thisField!= event.target) event.value=Number(i?event.value:0);
    if(a.value!="Off") Number+=1;
}
Thom Parker
Community Expert
Community Expert
April 16, 2020

You're comments are just fine up to the point where it really counts, and then it all falls apart. It is the bit being done in the loop you need to think through.

So the "i" in the for statment is never incremented. Which means that the loop will just run forever.

Next, there is no "thisField" defined anywhere, so the first if doesn't do anything. The event.value initailization and handling is ok, but for a counting loop this could be handled much better by using a counting variable and assigning event.value at the end. 

To continues, there's no "a" defined, so "a.value" doesn't mean anything. And there is no "Number" variable defined anywhere, so that code doesn't do anything either. 

Thom Parker - Software Developer at PDFScriptingUse the Acrobat JavaScript Reference early and often