CUSTOM INDESIGN DIALOGS

The hardest part of writing a script is often experienced in creating the user interface. Adobe InDesign provides a fairly robust dialog object for creating a modal dialog for this purpose. As you may remember, a modal dialog, once displayed, prevents any other activity within the application until it is closed.

To create a dialog, you first need to know what information the script will need from the user. This may evolve as the script is written. For this reason, you may want to start your script with all variable values hard-coded and placed at the top. Once the script is finalized, and tested, the dialog can be added to replace the hard-coded values.

Once you have a list of the information needed for your script, determine the type of field to use for each piece of information: text box, dropdown, checkbox, radio button group, or other.

Sketch – It may be helpful to sketch out how you want your dialog to look. Put yourself in the user’s shoes and organize the fields accordingly.

Start Simple – Start writing the dialog portion of the script as its own stand-alone script. This will allow you to test often and correct any errors before the script becomes too cumbersome to test efficiently.

Template – Use a template to reduce the amount of actual coding required. You might find the following template for creating a custom dialog handy. Copy the code for the template provided below and paste it in a new document for the AppleScript Editor. Save a copy of the script as DialogTemplate.scpt in a protected area of your computer for later use.

Dialog Template

   set dialogName to "Name of Dialog Here"
   tell application "Adobe InDesign CC 2015"
      activate
      --make sure user interaction level is set to interact with all
      set origLevel to user interaction level of script preferences
      set user interaction level of script preferences to interact with all
      --create the dialog, place reference to dialog in a variable
      set dlgRef to make dialog with properties {name:dialogName, can cancel:true, label:""}
      --create parent column inside which all other dialog fields will be created
      tell dlgRef
         set colRef to make dialog column
         tell colRef
            --add fields for collecting information here
         end tell
      end tell
      --show dialog and get whether user clicks cancel or OK
      set willContinue to show dlgRef
      if willContinue then
         --place values from dialog fields in variables
      end if
      --destroy the dialog
      destroy dlgRef
      --reset script preferences
      set user interaction level of script preferences to origLevel
      --if user cancelled, create error and return
      if not willContinue then error "User Cancelled"
         --place values returned from dialog fields in list
      return {}
   end tell --application

OS X LION OR LATER

With version 10.7 of the OS, AppleScript Editor has a new item in the File menu: New From Template which allows you to choose a script template from its menu item flyout.

AppleScript New from Template menu

To have your dialog template script available from this menu, save the script as “DialogTemplate.scpt” some place on your computer that is easy to find. Then use the following script:

Save Script Template

   set macHD to path to application support as string
   set templatePath to macHD & "Script Editor:Templates:InDesign Templates"
   set scriptFile to (choose file) as string
   tell application "Finder"
	copy file scriptFile to folder templatePath
   end tell
   set folderList to list folder templatePath

When you run the script, choose the DialogTemplate.scpt file you just saved. The result of running the script should list your script along with other templates that may have been provided for InDesign. (By default, OS 10.7 installs a script named “AnimationStarter.scpt” in the InDesign Templates folder.)

You can now start your next InDesign custom dialog using your DialogTemplate template. Choose from Script Editor’s File menu:

   File > File from Template > InDesign Templates 

Select the template from the list. When the template opens, rename it using File > Rename.

RUN YOUR SCRIPT

If you run the script created from the template at this point you will get a dialog with the buttons OK and Cancel. (If you do so, make sure InDesign is running before launching the script.)

START CREATING YOUR USER INTERFACE

Enter a name for your dialog as the value for the variable dialogName at the top of the script. You might also want to change the value for can cancel to false in the statement that creates the dialog:

   set dlgRef to make dialog with properties {name:dialogName, can cancel:false, label:""}

This will create a dialog with the OK button only.

DIALOG FIELDS

From here you can start creating the user interaction fields for the dialog. For each field you will need a label and a dialog widget. InDesign provides a number of dialog widgets. For our purpose here, we will look at two: a text editbox and a dropdown.

Create Text Entry Field

To create a label for a field, the static text object is used

   make static text with properties {static Label:"Label Here:", min width:100, static alignment: left align}

If the static alignment property is omitted, the label will align flush right by default.

To create a text editbox, set values for the properties edit contents and min width. Be sure to place a reference to the field in a variable. Add the following to the script you created using the dialog template above. Place the code where indicated after the comment that reads: –add fields for collecting information here

   make static text with properties {static label:"File Name:", min width:200, static alignment:left align}
   set nameField to make text editbox with properties {min width:200, edit contents:""}

Get result of user interaction

In your script where it reads “place information from dialog fields into variables, add the following:

   set fileName to edit contents of nameField

Then change the return statement to read

   return {fileName}

Run the script at this point and verify the value returned.

Dialog with static label and text editbox

EXPERIMENT WITH SETTINGS

Try running the script without the static alignment property in the line that creates the static text.

   make static text with properties {static Label:"Label Here:", min width:100}

Also, you may want the field label and widget to be on the same line (row). For this, place them inside a make dialog row statement block, as follows:

   tell (make dialog row)
      make static text with properties {static label:"Name:", min width:100}
      set nameField to make text editbox with properties {min width:200, edit contents:""}
   end tell 

CHOOSE FROM LIST – DROPDOWNS

To allow the user to choose an item from a list, your script can provide a dropdown. The list of items to be shown in a dropdown requires a list of string values. Since this list is not likely to be changed, you may want to establish its values in a property statement at the top of the script.

   --at the top of the script
   property presetList: missing value
   --then for the tell statement 
   tell application "Adobe InDesign CC 2015"
      set presetList to name of PDF Export Presets 

After the code that creates the name field, add code to create the dropdown. For demonstration, we will place the static text and dropdown in the same row:

   --to create the dropdown
   tell make dialog row
      make static text with properties {static label: "PDF Export Preset", min width:100}
      set presetField to make dropdown with properties {string list: presetList, min width:200, selected index:0}
   end tell 

When it comes time to get the index of the item selected, the value of the user’s choice is a number value reflecting the index of the item chosen. Unlike most index values in AppleScript, indexing for this list begins with 0; not 1. For this reason the selected index value needs to have the value of one (1) added (incremented).

   --after the statement that sets the value for the variable fileName, add
   set presetIndex to (selected index of presetField) + 1

Next add the variable presetIndex to the list to be returned:

   return (fileName, presetIndex)

Be aware that the value for the presetIndex is a number, not the name of the preset. To get the name of the preset:

   set presetName to item presetIndex of presetList

To see how this comes into play, we will place the code to create the sample dialog into a handler. Remember, if the user cancels out of the dialog we need to call the dialog handler from inside a try/on error statement block.

TEST DIALOG CODE AS A HANDLER

To change the dialog code to a handler, change the top of your script to read as follows:

   property presetList: missing value
   set dialogName to "Test Dialog"
   try
      tell application "Adobe InDesign CC 2015"
         set presetList to name of PDF export presets
      end tell
      set userResult to customDialog (dialogName)
   on error errStr
      activate
      display alert errStr
      return
   end try
   --test for value returned
   userResult

To create the custom dialog handler, add an on statement for the handler. Place this before the original tell application statement (there is a tell statement inside the try/on error statement block and one inside the customDialog handler):

   on customDialog(dialogName)
      tell application "Adobe InDesign CC 2015"
         --rest of code that creates the dialog 

At the end of the template code (after the end tell statement), end the handler:

   end customDialog

TEST YOUR SCRIPT

At this point, make sure your script runs as expected. If you click the OK button, the values entered should display in the result panel for your script. This will include the name of the file and a number indicating the item chosen from the dropdown. If you cancel, an error message should be displayed.

To get the name of the PDF export preset for use in the script, you need to add code to get the preset’s name from the list. Change the statement that calls the customDialog handler and add a new statement so the two statements before the on error statement read as follows:

   set {fileName, presetIndex} to customDialog (dialogName)
   set presetName to item presetIndex of presetList

Change the last line of the script (that tests for value of the call to customDialog) to get the values for fileName and presetName:

   {fileName, presetName}

ONWARD AND UPWARD

In our next blog we will add security and watermark settings to our dialog for our final ExportPDFwPreset script. Meanwhile, if you have OS X 10.7 or higher, you might want to explore some of the templates provided for AppleScript and imagine the possibilities at your disposal now that you are getting familiar with AppleScript.