PDF form calculations with radio buttons

I am creating a form which calculates a total based on options selected on radio buttons.

However, the sets / groups of radio buttons have different values which depend on other radio buttons.
I am guessing it would need to be some kind of an “if” statement?

Any help or advice would be greatly appreciated,
thank you so much


The calculation basically needs to be :

Code:

If "Section A" is selected, then the value of radiobutton1 is 50;
                                           radiobutton2 is 60;
                                           radiobutton3 is 70;
                                           "Grandtotal" is 50+60+70 = 180
----- If "Section B" is selected, then the value of radiobutton1 is 100;
                                           radiobutton2 is 120;
                                           radiobutton3 is 130;
                                           "Grandtotal" is 100+120+130 = 350

So far I have the following calculation script which works fine to add up the options IF no section is specified

Code:

// Custom Calculate script
(function () {

    // Get the field values
    var v1 = getField("Options Single").valueAsString;
    var v2 = getField("GrandTotal").value;

    switch (v1) {
    case "1" :
        event.value = 50;
        break;
    case "2" :
        event.value = 60;
        break;
    default :  // Neither radio button is selected (v1 === "Off") which may not ever happen
        event.value = "";
    }

})();

Hey there,

Not sure if this is the kind of solution you’re after, but I just kind of ran with it :slight_smile:

From what I understand, the key to your problem is that you need to be able to change the value of a set of options based on something that was selected before.

Luckily, there is (IMO) a very simple solution - we can use a small matrix to represent the different values.

e.g.


    // our value matrix
    matrix = [
        [ 50, 60, 70 ], //Section A
        [ 100, 120, 130 ] //Section B
    ];

This means we can set values on section a/b and the options 1/2/3 - these values can correspond with the indexes of the matrix and take away a lot of the pain.

We’ll use some functions to get the indexes of the section and option, we can then figure out which entry in the matrix we’re after.

I’ve assumed some basic HTML:


<form id="someForm">
    <fieldset>
        <p><input type="radio" id="sect_1" class="sectionField" name="section" value="0" checked/><label for="sect_1"> Section A</label></p>
        <p><input type="radio" id="sect_2" class="sectionField" name="section" value="1" /><label for="sect_2"> Section B</label></p>
    </fieldset>

    <fieldset>
        <p><input type="radio" id="option_1" class="optionField" name="chosenOption" value="0" checked/><label for="option_1"> Option 1</label></p>
        <p><input type="radio" id="option_2" class="optionField" name="chosenOption" value="1" /><label for="option_2"> Option 2</label></p>
        <p><input type="radio" id="option_3" class="optionField" name="chosenOption" value="2" /><label for="option_3"> Option 3</label></p>
    </fieldset>

    <fieldset>
        <p>Value of selected option: <input type="text" id="value" /></p>
    </fieldset>

</form>&#8203;

As for the JavaScript:

Step 1 - some basics




(function(){
    "use strict";


    //declare vars
    var form,
        sectionFields,
        sectionFieldsLen,
        optionFields,
        optionFieldsLen,
        matrix;


    // our value matrix
    matrix = [
        [ 50, 60, 70 ], //Section A
        [ 100, 120, 130 ] //Section B
    ];


    //get access to our DOM elements
    form = document.getElementById("someForm");


    sectionFields = form.getElementsByClassName("sectionField");
    sectionFieldsLen = sectionFields.length; //don't forget to cache the length


    optionFields = form.getElementsByClassName("optionField");
    optionFieldsLen = optionFields.length;

Now that we have references to our DOM elements, we can create some functions to help us out

Step 2 - getting the section and option values


    /**
     * Get Current Section index
     */
    function getSection() {


        for (var i = 0; i < sectionFields.length; i++) {
            if (sectionFields[i].checked) {
                return parseInt( sectionFields[i].value, 10);
            }
        }


        return false;
    }


    /**
     * Get current option index
     */
    function getOption() {


        for (var i = 0; i < optionFields.length; i++) {
            if (optionFields[i].checked) {
                return parseInt( optionFields[i].value, 10);
            }
        }


        return false;
    }

Great, nice and simple - we can now get the indexes required to access our matrix.

Of course there is a small function to add the value to the “value” element:
Step 3 - Setting the value somewhere

    /**
     * Put the value of the selected option in the field
     */
    function setValue() {
        var sectionIndex = getSection(),
            optionIndex = getOption(),
            theValue;


        //set the value using the matrix we declared
        theValue = matrix[ sectionIndex ][ optionIndex ];


        document.getElementById("value").value = theValue;
    }

Ok, so how to we get things happening? We need to set up an event handler for the change event on those radio buttons.
Rather than setting up a bunch of event handlers, I’ve opted to watch the “change” event on the form, this way
we have only one event handler and we can just work out what the target was to know whether we need to do something.

Sounds complicated, but it really isn’t:
Step 4 - Handling the change event


    /**
     * Handle the change event on section/option fields
     *
     * @param {Event} e
     */
    function changeHandler(e) {
        var target,
            className;


        target = e.target;
        className = target.getAttribute("class");


        // make sure we only process the rest of the event handler
        // if we're dealing with either a sectionField or an optionField
        if (className.match(/sectionField|optionField/)) {
            setValue();
        }
    }


    form.addEventListener("change", changeHandler);

Of course in my HTML example, I’ve set the first items to checked (not required, but can be handy) - if you’re also doing this, you might want to call setValue() at the end to make sure the initial value is set.
Step 5 - finishing up




    setValue(); //optionally set the value initially.
}());

I’ve posted a complete solution on JS Fiddle: http://jsfiddle.net/GeekyJohn/2Eqe2/

Let me know how you get on :slight_smile:

Hey there :slight_smile:

Thank you so much for your detailed reply with explanations. I really appreciate your help.
I am trying to implement what you have given me, however am slightly confused (my apologies for my ignorance) - how could I “adapt” this for the use in a PDF form instead of for an html form?

Thank you again for your great help :slight_smile:

Ah yes of course that is an excellent point. The big difference between the HTML and PDF version is how you interact with elements like form fields, since PDFs don’t have a DOM like HTML pages do.

The main bits you’ll have to change in my example are the way you reference the fields (and get/set their values I assume) and the event listener to watch for form changes. Other than that I don’t think there is much else that needs to change.

Luckily Adobe have a fairly comprehensive API document that can help you out :slight_smile: (plus a few [URL=“http://www.adobe.com/devnet/acrobat/javascript.html”]other JavaScript related things)