Copy link to clipboard
Copied
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;});
Copy link to clipboard
Copied
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;
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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;
}
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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;
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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;
Copy link to clipboard
Copied
Thank you for replying, Bernd. I added your code and it had no syntax error, so that's good. Trying it out has no result. Here are two screen shots showing an attempt to click the two boxes before the total with no results, and a shot with the script in place pointing at the correct field.
Also, I see you added "ar" to the array spot in the function. I assume that was a critical spot, and I must have understood wrong that that spot was optional on one reference I was checking. Is "Number" not a good variable name? I see you used "total" instead and declared it differently. I was basing the use of "Number" on a different script successfully used to calculate a sum on a different page in this document.
Copy link to clipboard
Copied
Check the console for errors.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Looking at the errors in the Javascript Debugger, I'm not sure what to make of it. A variation of the top part of the script where I split the target name, pop the ends, join the "value" back to it in order to get the target array (guaranteeing that this page or any other spawned page with different prefixes from the field names works correctly) works perfectly without a hitch on another page in this document so I know that setup is proper.
Here is the other script that I'm referring to, and you can see that's it pretty much the same structure for collecting fields and it works perfectly in a setup for summing all text fields...
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) + Number(a.value);});
So since this works, I don't see why the script we're working on wouldn't work. oColFldList should not be empty, and this.getField should also have info. You can see on the screen shot three replies up that the column structure is set up properly with "check1.value.row" as the column, and that is guaranteed consistent because of InDesign's repeating actions when duplicating.
Copy link to clipboard
Copied
The script works for me:
Copy link to clipboard
Copied
I was going to extract a copy of the page and send it to you and then I got a warning "an incorrect file structure was found in the PDF file". That made me wonder if that was the reason why it wasn't working. I had to import the PDF file into a "combine files" document and resave it to fix that. I had to copy-paste the field group into the new document and..... IT WORKS! So it was my corrupt document holding it back.
And thanks to you mentioning debugging, I learned how to do and fixed three improperly labelled fields on my other complicated javascript form, so you helped me fix another upcoming problem. THANK YOU.
Copy link to clipboard
Copied
Successful final result....
And here is the final tally field's code to calculate the bottom rows. The Total days field is labled, "check13.calc.total" for reference. It loops through check1 to check12...
var total = 0;
for (var i=1; i<=12; i++) {
var aNameParts = event.targetName.split(".");
aNameParts.pop();
aNameParts.pop();
aNameParts.pop();
var strColName = aNameParts.join(".");
total+=Number(this.getField(strColName+"."+"check"+i+".calc.total").valueAsString);
}
event.value = total;
Copy link to clipboard
Copied
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-661a...
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now