Search This Blog

Monday, 28 October 2013

Using app.execDialog() in an Adobe Designer Form

Adobe Designer forms can use the app.execDialog() method to show a custom dialog.  The dialog is defined by a JavaScript object literal and this sample is an Adobe Designer form that allows you to add controls, preview your dialog and generate the required object literal.  This is far from a what-you-see-is-what-you-get interface but it does allow you to build up a hierarchy of controls and achieve some complicated dialogs.

To start lets have a look at a very simple dialog, this dialog


Is produced by the following

  description:
  {

   name: "Errors in form",
   elements: [
    {
     type: "view",
     align_children: "align_row",
     elements: [
      {
       type: "static_text",
       name: "Please enter your name",
      },
      {
       type: "ok",
      }
     ]
    }
   ]
  }


Unfortunately for security reason when used within a Designer form you can't specify the dialog title and you also get a "Warning JavaScript Window".  From the console or a Folder Level script you get the dialog without the warnings.



These dialogs can also be used for input (note the addition of a validate function), such as

  description:
  {
   elements: [
    {
     type: "view",
     elements: [
      {
       type: "static_text",
       name: "Please enter your name",
      },
      {
       width: 200,
       height: 22,
       type: "edit_text",
       item_id: "NAME",
      },
      {
       type: "static_text",
       item_id: "ERR1",
       name: "You must enter your name",
      }
     ]
    },
    {
     type: "ok_cancel",
    }
   ]
  },
  validate : function(dialog)
  {
   var isValid = true;
   var elements = dialog.store();
   if (elements["NAME"] === "")
   {
    dialog.visible({ERR1:true});
    isValid = false;
   }
   else
   {
    dialog.visible({ERR1:false});
   }
   return isValid;
  }


Which give this dialog, when the name has been left blank;


This sample, DialogSample.pdf, contains these two dialogs and also one that show most of the  controls available and the properties that go with them;



These dialogs have a hierarchy of controls, that is controls within container controls.  This quickly becomes a very big form.  A form to design a two level dialog contains 3,384 fields, which is enough to get the cooling fans on my computer spinning.  So I am posting two forms one that supports two levels of controls and one that supports one level (which is still 1,452 fields).

Dialog.pdf (3893k)
Dialog.L1.pdf (1936k)

The JavaScript code generated is written to an attachment of the form. There is a stub generated for the event handler of each field and a stub for the validate method.  Be careful writing code in the validate method as if there is no path that returns true then the only way out of the dialog is using the task manager.

These two samples support a number of controls and properties that are not listed in the manual, but are very useful (in these cases I have made note in the tooltips).  Some of the things not documented are;
    • link_text: a hyper link control
    • mclv: a multi-column list view (or grid)
    • slider: a slider but I have not got this to return a value.
    • ok_help, ok_cancel_help, ok_other_help, ok_other_cancel_help controls
    • separator: draw a line horizontal or vertical with optional caption
    • Heading and Title fonts about 10pt and 12pt respectively
    • margin_width, margin_height properties for the view control
    • back_color, gradient_direction, gradient_type for the view control
    • A Dialog.setForeColorRed() method
    • A Dialog.visible() method to show/hide controls
In this sample controls that support a click event also support some actions, such as enabling/disabling other controls, showing/hiding other controls and setting focus on other controls.  Hopefully there will be enough instructions in the form to show you what I mean.

Images

This form started life to generate the hex encoded string.  This is a representation of a 4 channel (ARGB) 8-bits per channel image, that is 8 JavaScript characters per dot.  So images can start to take up a lot of space.  You can get the hex encoded string using the importIcon, getIcon and iconStreamFromIcon methods.  This sample imposes a size limit an image to about 50,000 dots, this is because Designer has trouble with very long lines and this sample uses an XSLT stylesheet to generate the JavaScript literal and the XSLT processor has a limit of 100 levels of recursion. 

Fragments

Each dialog control is defined by a fragment and each fragment is used in three levels, and have a smaller width at each level.  To override the properties of a fragment you need to use the XML Source view and type in the properties you want to override.  For example if the Image fragment had a Border subform and the Border subform had a Propertoes subform then I could override the width values by adding the highlighted XML.

<subform usehref=".\Fragments\ImageControl.xdp#som($template.#subform.Image)" w="162.299mm">
    <subform name="Border" w="169.298mm">
        <subform name="Properties" w="147.299mm"/>
    </subform>
</subform>

One down side of this approach is you will now get the warning message "This fragment reference has local overrides to one or more properties of the source fragment".

ToolTips

As there a many fields that use the same tooltip I have created a separate dataset and used the setProperty element to assign them to the correct field.  This is done in the XML Source view by adding XML under the xfa:dataset element and referencing them in each form field like "
<setProperty target="assist.toolTip" ref="!toolTips.value.[name==&quot;dialogName&quot;]"/>
", which you also need to add using the XML Source view.

Source

The source template, including all the fragments is in the zip file.  Dialog.zip