Copy link to clipboard
Copied
I'm pretty new to JavaScript so I have very little idea how to achieve this. But I'm learning. 🙂
I have three (3) dropdown boxes on a PDF form where the user can select a series of courses. All dropdown boxes contain the same list of courses, for example...
Course A - Design widgets
Course B - Assemble widgets
Course C - Test widgets
Course D - Paint widgets
Course E - Pack widgets
When a selection is made in one of the dropdowns (Course1) an adjacent textbox (NominalHours_Course1) needs to display the number of hours that the course typically runs for (e.g. 5, 8, 12, 15, etc.). This is a predetermined value for each course and needs to be retrieved from a table... (I assume stored somewhere in the document?).
I'm after the same sort of functionality as the MS Excel VLOOKUP function.
Reading some of the posts on this forum, it looks like the relationship between course and hours should be in a document level script, allowing the "Nominal Hours" values to be referenced by any of the dropdown boxes and textboxes. This would also make it easier to change values if required since the changes would only need to be made in the one location.
I have no idea where to start with this. I have tried working through the JavaScript Tutorials on w3schools.com but I think I might be trying to bite off more then I can chew (being such a beginner at JavaScript).
Hoping someone can help.
Sure. OK, so you can place this code as your doc-level script:
var courseData = {
"Course A - Design widgets" : 5,
"Course B - Assemble widgets" : 8,
"Course C - Test widgets" : 12,
"Course D - Paint widgets" : 15,
"Course E - Pack widgets" : 21
};
function calcCourseHours(dropdownFieldName) {
var v = courseData[this.getField(dropdownFieldName).value];
if (v) event.value = v;
else event.value = "";
}
And then as the custom calculation of your text field enter this code:
...calcCourseHours("Course1");
Copy link to clipboard
Copied
There are a couple of ways of doing it.
You can hard-code the values into your code and then refer to them with your script, or you can use a text file that contains this data, attach it to the PDF and then parse it when the file is opened and use the information from it in your code.
The former is easier to set up, but a bit trickier to maintain, as it requires editing the actual code. The latter is a bit more complicated to set up, but once it's working all you need to do in order to update the values is to open that attached text file, edit it and save it, and you're done.
I can explain how to do the former, if you wish.
You can do the latter using this tool I've developed, with some additional code I can help you with: Custom-made Adobe Scripts: Acrobat -- Import Items from a Text File to a Combo-Box or List Field
Copy link to clipboard
Copied
The form needs to be distributed via email so I assume it would be better not to have a separate text file associated with it, or am I missing what you mean by "attach it to the PDF"?
Copy link to clipboard
Copied
It will be a part of the PDF file. You will only need to distribute one
file.
Copy link to clipboard
Copied
It is unlikely that I will need to change anything on a regular basis so I think the first option would be best.
If you wouldn't mind providing the code (with an explanation of what each part does so I can learn this stuff) it would be greatly appreciated.
Thanks.
Copy link to clipboard
Copied
Sure. OK, so you can place this code as your doc-level script:
var courseData = {
"Course A - Design widgets" : 5,
"Course B - Assemble widgets" : 8,
"Course C - Test widgets" : 12,
"Course D - Paint widgets" : 15,
"Course E - Pack widgets" : 21
};
function calcCourseHours(dropdownFieldName) {
var v = courseData[this.getField(dropdownFieldName).value];
if (v) event.value = v;
else event.value = "";
}
And then as the custom calculation of your text field enter this code:
calcCourseHours("Course1");
Pretty straight-forward...
Copy link to clipboard
Copied
One more thing: Make sure you tick the option to commit the selected value of the drop-down field immediately.
You'll find it under the field's Properties, Options tab.
Copy link to clipboard
Copied
Thanks so much for you help. I'll give it a go, but I'll also try to understand what is happening with this script so I don't keep asking the same simple questions. 🙂
Copy link to clipboard
Copied
If you're having problems with it post here again...
Copy link to clipboard
Copied
Seems to be working perfectly.
Just to confirm, the courses in the dropdown boxes are not meant to be populated from the information in the document level script. This would only be the case if I used the other method you mentioned (attaching a text file).
As I had previously added all of the courses to the dropdown list manually (I created the first one and then cloned it to create the others), the numeric text box is just looking up the string in the dropdown box and returning the associated number. Is this correct?
So if I want to add a course to the dropdown boxes, I will need to add it to each of the dropdown boxes, and then add an associated line in the document level script. Is this correct?
Copy link to clipboard
Copied
That's all correct, yes.
However, it is possible to populate the drop-down fields using the values in the doc-level script, so you won't need to do it manually each time, and if you update the script it will also update all of those drop-downs, all at once.
Copy link to clipboard
Copied
Too advanced for me?
Copy link to clipboard
Copied
Possibly, but I can help... I'll post again in a bit.
Copy link to clipboard
Copied
Are your fields named Course1, Course2, etc.?
Copy link to clipboard
Copied
You mean the dropdown boxes?
If so...
Unit_1
Unit_2
Unit_3
Unit_4
Unit_5
Unit_6
Unit_7
Unit_8
Copy link to clipboard
Copied
Didn't you say it was called "Course1" before?
Copy link to clipboard
Copied
Yes. Sorry, that was for ease of explanation. They're actually called "units of competence".
I adapted your code to suit...
var unitData = {
"UEENEEA113A - Mount and wire control panel equipment" : 9,
"UEENEEE104A - Solve problems in d.c. circuits" : 18,
etc...
};
function calcCourseHours(dropdownFieldName) {
var v = unitData[this.getField(dropdownFieldName).value];
if (v) event.value = v;
else event.value = "";
}
Copy link to clipboard
Copied
And the code for the textbox...
calcCourseHours("Unit_1");
Copy link to clipboard
Copied
OK. So use this code as the doc-level script instead of what you have now:
var unitData = {
"UEENEEA113A - Mount and wire control panel equipment" : 9,
"UEENEEE104A - Solve problems in d.c. circuits" : 18,
// etc.
};
var items = [""];
for (var i in unitData)
items.push(i);
for (var i=1; i<=8; i++) {
var f = this.getField("Unit_"+i);
var oldValue = f.valueAsString;
f.setItems(items);
try {
f.value = oldValue;
} catch (e) {
console.println("Can't apply the old value \"" + oldValue + "\" to the field: " + f.name);
}
}
function calcCourseHours(dropdownFieldName) {
var v = unitData[this.getField(dropdownFieldName).value];
if (v) event.value = v;
else event.value = "";
}
Copy link to clipboard
Copied
How do the 8 dropdown boxes know to use this data?
Is this the line that does it?
var f = this.getField("Unit_"+i);
And do I need to clear out the "Item List" under Options for each dropdown?
Copy link to clipboard
Copied
They get populated with it each time the file is opened and the script is executed, through the new code I added.
Copy link to clipboard
Copied
The line that actually does it is line #14 in the code above.
No, you don't need to clear them yourself. It will happen automatically the next time you open the file, or when you paste the code.
Copy link to clipboard
Copied
Brilliant.
I've noticed an anomaly in my form that may or may not have been introduced as part of these changes.
Each "Unit" has a fee that is calculated using the following script...
event.value = (this.getField("Unit_1_Nom_Sess").value * 90);
...where "Unit_1_Nom_Sess" is the lookup hours from the document level script and 90 is the cost per hour.
The fee calculates OK for each Unit, but the total fee at the bottom of the form doesn't update correctly (it's always one operation later than expected).
I'm calculating the Total Fee field using the following...
event.value = Number(this.getField("Unit_1_Fee").value) + Number(this.getField("Unit_2_Fee").value) + Number(this.getField("Unit_3_Fee").value) + Number(this.getField("Unit_4_Fee").value) + Number(this.getField("Unit_5_Fee").value) + Number(this.getField("Unit_6_Fee").value) + Number(this.getField("Unit_7_Fee").value) + Number(this.getField("Unit_8_Fee").value);
Copy link to clipboard
Copied
That sounds like a classic Fields Calculation Order issue. You need to set that order (which is NOT the same as the tab order) so that the total field is calculated after the Unit Fee fields it's dependent on.
What's your version of Acrobat?
Copy link to clipboard
Copied
Found the "Set Field Calculation Order" option under the "More" link in "Prepare Form". Strange I've never seen this before. I must have previously fluked the correct order by chance. Thanks for the heads up. Works perfectly now.
One last question, and then I'll stop annoying you (for now anyway)
I plan to add another numeric box on each line (i.e. for each Unit) where the user can enter a reduced number of hours for the Unit if they elect to complete some of the training in their own time (e.g. online).
These fields would be called "Unit_1_Req_Sess", "Unit_2_Req_Sess", etc... up to "Unit_8_Req_Sess".
I would like the "Unit Fee" for each unit to be initially calculated and displayed based on the Nominal Sessions (e.g. "Unit_1_Nom_Sess") but then updated to a lesser amount if the user enters a value in the Reduced Hours box against that Unit.
How would I change the Custom Calculation Script below to check if the user has entered something in this field, and to use this number in the calculation instead of the standard number of sessions? I assume there is some sort of IF statement involved?
event.value = (this.getField("Unit_1_Nom_Sess").value * 90);