################
Using JavaScript
################

Adding JavaScript Actions
=========================

For advanced usage, Advanced Publishing supports the connection of JavaScript actions to fields and buttons within the PDF document.

Adobe JavaScript for Acrobat 3D is a separate JavaScript interface provided by Adobe for 3D Annotations, although it can be called from the standard Adobe Scripting engine via the JavaScript  Annot3D.context3D property. To find more resources search for "JavaScript for Acrobat 3D" on the Adobe Developer network. **If viewing pages in Adobe Livedocs it is a good idea to turn on display of the contents pane using the button at the top left of the page.**

Advanced Publishing does not document the JavaScript interface and Tech Soft 3D does not warrant support for it.

To familiarize yourself with the Adobe JavaScript for Acrobat 3D we suggest reading the "JavaScript for Acrobat 3D Annotations API Reference" (js_3d_api_reference.pdf) available on the Adobe Developer website.

The *AnimWorkinstruction* example on the Advanced Publishing download demonstrates how to attach JavaScript to buttons and lists to animate different portions of an animation as well as displaying different details regarding the current portion selected.

.. code-block:: c

    char* myjs = "thisfield = this.getField(\"ListInstructions\");\n"
                "if(thisfield)\n"
                "{\n"
                "  idx = thisfield.currentValueIndices;\n"
                "  selectstep(idx+1);\n"
                "}\n"
    iRet = A3DPDFPageFieldSetActionJavaScriptFromString(pPage, "ListInstructions", myjs);
    CHECK_RET;

Another example would be to attach JavaScript to a button to cause pre-defined View in the model to be executed when the button is pressed.

.. code-block:: c

    char* myjs1 = "c3d = this.getAnnots3D( 0 )[0].context3D; "
                  "c3d.runtime.setView(\"View_1\", true);";
    iRet = A3DPDFPageFieldSetActionJavaScriptFromString(pPage, "Button1", myjs1);
    CHECK_RET;

The JavaScript code in myjs1 gets the first 3D annotation on the first page to retrieve the 3D context for that annotation. Note that the function parameter in GetAnnots3D is the zero-based page number, whilst the array index is the zero-based 3D annotation number on the page.

The runtime object represents an instance of the playback engine which manages event processing. The runtime.setView method sets the current view for the annotation, with the Boolean value indicating whether to animate to the view when it is set.


Setting a JavaScript Action on a Field
--------------------------------------

Customers can design fields to invoke JavaScript when the field is triggered by the end user. To store JavaScript so that it is invoked when the user triggers a widget, see the following code snippet:

.. code-block:: c

    char myjs[1024]="c3d=this.getAnnots3D(0)[0].context3D;c3d.runtime.setView(\"View_3\",true);";
    iRet = A3DPDFPageFieldSetActionJavascriptFromString(pPage, "Button", myjs);

Note: JavaScript variables or functions can be defined at a document level. To store JavaScript at a document level, use the function ::A3DPDFDocumentAddJavascriptFromString.

The action event is different depending on the type of the field.

* drop-down list (combo box): the JavaScript is launched when the end user selects an item in the list. For drop-down lists, the JavaScript should be as follows. Note that only the item value can be retrieved from the JavaScript, the export value is not enabled here.

.. code-block:: c

    if( event.willCommit )
    {
        if(!event.value == "")
        {
           // TODO: write your JavaScript
           // you can use the following JavaScript to get information on the list item selected:
           // value of the selected item: "event.value"
           // code example: write the list item to a text field
           f = this.getField("TheTextField");
           f.value = event.value;
        }
    }

* list boxes: the JavaScript is launched when the end user selects an item in the list. For list boxes, the JavaScript should be as follows. Note that only item value can be retrieved from the JavaScript, the export value is not enables here.

.. code-block:: c

    // this should be replaced with the name of the current field
    thisfield = this.getField("MyListBox");
    if (thisfield)
    {
        // TODO: write your JavaScript
        // you can use the following JavaScript to get information on the list item selected:
        // index of selected item: "idx = thisfield.currentValueIndices"
        // value of selected item: "thisfield.getItemAt(idx, true)"
        // export value of selected item: "thisfield.getItemAt(idx, false)"
        // code example: write the list item to a text field
        f = this.getField("TheTextField");
        f.value = thisfield.getItemAt(idx, true);
    }

For documentation on the JavaScript supported by Acrobat, please consult Adobe documentation.


Populating List Boxes and Combo Boxes
-------------------------------------

The **DemoFunctionalities** example creates a three page PDF. The first page creates a simple Hello World form programmatically, and pages two and three are based on a single template that contains a list box and a combo box placed at the same position on the form i.e. on top of each other.

Page two hides the list box so the combo box is shown, whilst page 3 hides the combo box so the list box is shown. Each lists each view in the 3D annotation. In both cases the sample shows how to add JavaScript to respond to selection change events, and how to access a separate text field, "SelectedItemValue" and set the selected value as the label for that field.

When used in a multi-page PDF the field names from the template have the page number appended, so that "My3DWindow" becomes "My3DWindow_2" and "My3DWindow_3" respectively.

Note that this naming convention is supplied by Advanced Publishing, as Acrobat requires each field name in a PDF to be unique within the document, not just the page.

Note that the same API call is used to populate both the list box and combo box, but the JavaScript to control them is slightly different.

.. code-block:: c

    iRet = A3DPDFPageFieldSetVisibility(pPage, "MyListbox_2", false);
    iRet = A3DPDFPageFieldListAddItem(pPage, "MyDropdown_2", "View_1", "My View 1");
    iRet = A3DPDFPageFieldListAddItem(pPage, "MyDropdown_2", "View_2", "My View 2");
    iRet = A3DPDFPageFieldListAddItem(pPage, "MyDropdown_2", "View_3", "My View 3");
    iRet = A3DPDFPageFieldListAddItem(pPage, "MyDropdown_2", "View_4", "My View 4");
    char* myjscombo = "if( event.willCommit )\n"
           "{\n"
           "  if(!event.value == \"\")\n"
           "  {\n"
           "    f=this.getField(\"SelectedItemValue_2\");\n"
           "       f.value=event.value;\n"
           "       activateview(2,0,f.value);\n"
           "  }\n"
           "}";
    iRet = A3DPDFPageFieldSetActionJavaScriptFromString(pPage, "MyDropdown_2", myjscombo);

In the JavaScript, SelectedItemValue_2 represents a separate text field in which the result of the selection is shown. The function activateView is defined at the PDF Document level using the code:

.. code-block:: c

    // js on the doc
    char* myjsondoc = "function activateview(pgidx, annotidx, viewname)\n"
           "{\n"
           "      // in getAnnots3D, page index starts from 0\n"
           "      c3d = this.getAnnots3D(pgidx-1)[annotidx].context3D;\n"
           "      c3d.runtime.setView(viewname, true);\n"
           "}";
    iRet = A3DPDFDocumentAddJavascriptFromString(pDoc, "MyFns", myjsondoc);

The code for the third page is similar, except the mechanism to get the current selection in the list box is slightly different - in the case of the combo box the JavaScript responds to an event indicating a possible change in selection, in the case of the list box Advanced Publishing also sets the code so it is executed when the selection changes, but in this case the index of the current item is obtained to extract the item's value:

.. code-block:: c

    // page 2 : only populate list box
    iRet = A3DPDFPageFieldSetVisibility(pPage, "MyDropdown_3", false);
    iRet = A3DPDFPageFieldListAddItem(pPage, "MyListbox_3", "View 1", "View_1");
    iRet = A3DPDFPageFieldListAddItem(pPage, "MyListbox_3", "View 2", "View_2");
    iRet = A3DPDFPageFieldListAddItem(pPage, "MyListbox_3", "View 3", "View_3");
    iRet = A3DPDFPageFieldListAddItem(pPage, "MyListbox_3", "View 4", "View_4");
    char* myjslistbox = "thisfield = this.getField(\"MyListbox_3\");"
           "if (thisfield)\n"
           "{\n"
           "  idx = thisfield.currentValueIndices;\n"
           "  console.println(\"thisfield.index: \" + idx);\n"
           "  console.println(\"thisfield.value: \" + thisfield.getItemAt(idx, true));\n"
           "  console.println(\"thisfield.exportvalue: \" + thisfield.getItemAt(idx,false));\n"
           "  f=this.getField(\"SelectedItemValue_3\");\n"
           "  f.value=thisfield.getItemAt(idx, true);\n"
           "  activateview(3,0,f.value);\n"
           "}";
    iRet = A3DPDFPageFieldSetActionJavaScriptFromString(pPage, "MyListbox_3", myjslistbox);

How and when the JavaScript is executed for each type of Page Field is documented in the JavaScript section of the Advanced Publishing Programming guide.

Note also the console.println statements that can be used for debugging when the PDF is opened in Adobe Acrobat. To view the debugger select Tools->JavaScript->JavaScript->Debugger within Acrobat.
