Use Google to find help fast. For example, search on "xpressdox choosefromlist".

The SetWebInterviewMinimumHeight Command

The interview in the browser can vary in height depending on the existence of tabs and other factors. The template author can control the minimum height of the web interview with the SetWebInterviewMinimumHeight command.

«SetWebInterviewMinimumHeight(200)»

This will set the minimum height of the web interview to 200 pixels.

This feature is available from Version 10.4 onwards.

Show the result of Date arithmetic in the interview

When entering dates for a contract, it is important to get them right during the interview. It might be possible to control this via the Rule command, but often it is very useful to reflect this to the user as they are typing into the interview.

For the purposes of this example, we start off with one date, called StartDate, which the user will capture in the interview, and then allow the user to enter a number of years, months and days to define the duration of the contract. During the entry of these data elements, we want to be able to show the end date of the contract, in the interview, which will change as the user changes the various values. The example will use the OnExitSet command, the Script command, and various date manipulation functions.

Step 1. Capture the date and a number of years.

Here is the XpressDox code to capture the date (StartDate) and the number of years (Years) and show the result of adding the number of years (IncrementDate) to that start date in a Heading on the Place Holder called Show_EndDate:

«PlaceHolder(Show_EndDate)»
«Heading(Show_EndDate,|@Red/Microsoft Sans Serif/8.2@ )»
«CaptureDataElement(StartDate,Date)»
«OnExitSet(Years,Show_EndDate,HeadingText,(), FormatDate(IncrementDate(IncrementDate(StartDate,Years,'Y'),-1,'d'),'d MMM yyyy'),,EvenWhenNotEmpty)»

If you copy and paste this code into a template and run that template, see what happens after you enter a number into the Years and press Tab.

Note that there are two IncrementDate functions – the second subtracts one day, because the last day of a contract is always the duration less one day.

Step 2. Capture the number of months and days as well as the years.

This gets a bit more complicated, but the principle is the same. Now we want the number of Years, Months and Days to be added to the StartDate whenever we change the values of any of those three durations. This means we need an OnExitSet for each of the 3 duration elements. Here is the OnExitSet for the Years data element:

«OnExitSet(Years,Show_EndDate,HeadingText,(), FormatDate(IncrementDate(IncrementDate(IncrementDate(IncrementDate(StartDate,Years,'Y'),Months,'M'),Days,'D'),-1,'d'),'d MMM yyyy'),,EvenWhenNotEmpty)»

This OnExitSet will add the Years, Months and Days to the StartDate, subtract 1 day and set that value into the heading of the ShowEnd_Date placeholder.

Diversion: Chaining functions

One obvious point to make is that the syntax of this OnExitSet is quite difficult to read (and quite difficult to write!), because of the need to nest the function calls. To address this complexity, the concept of “function chaining” was introduced with version 10.2 of XpressDox. Using this concept, the above OnExitSet can be re-written as:

«OnExitSet(Years,Show_EndDate,HeadingText,(),
IncrementDate(StartDate,Years,'Y')->IncrementDate(^,Months,'M')->IncrementDate(^,Days,'D')->IncrementDate(^,-1,'d')->FormatDate(^,'d MMM yyyy'),
,EvenWhenNotEmpty)
»

The “->” symbol can be read as “pass the result into”, or “goes into”.

This means that the entire set of commands needed to show the result of adding all three duration elements to StartDate (and then subtracting one day) and showing the value in the interview is:

«PlaceHolder(Show_EndDate)»
«Heading(Show_EndDate,|@Red/Microsoft Sans Serif/8.2@  )»
«CaptureDataElement(StartDate,Date)»

«OnExitSet(Years,Show_EndDate,HeadingText,(),
IncrementDate(StartDate,Years, 'Y')->IncrementDate(^,Months, 'M')->IncrementDate(^,Days, 'D')->IncrementDate(^,-1, 'd')->FormatDate(^,'d MMM yyyy'),
,EvenWhenNotEmpty)
»

«OnExitSet(Months,Show_EndDate,HeadingText,(),
IncrementDate(StartDate,Years, 'Y')->IncrementDate(^,Months, 'M')->IncrementDate(^,Days, 'D')->IncrementDate(^,-1, 'd')->FormatDate(^,'d MMM yyyy'),
,EvenWhenNotEmpty)
»

«OnExitSet(Days,Show_EndDate,HeadingText,(),
IncrementDate(StartDate,Years, 'Y')->IncrementDate(^,Months, 'M')->IncrementDate(^,Days, 'D')->IncrementDate(^,-1, 'd')->FormatDate(^,'d MMM yyyy'),
,EvenWhenNotEmpty)
»

Step 3. Introduce a Script with Parameters

It is fairly obvious that the three OnExitSets are going to do the job, but it does seem a bit clumsy. The creation of the three would probably be done with copy-and-paste from the first, and change the Years to Months and Days in the second two, respectively.

It would also be nice, in future, to re-use this code for other dates, maybe even in the same template, without the copy-and-paste issues.

Looking at the three OnExitSets, the code is exactly the same, except for the trigger data element in each case, and so now the common code is put into a Script, with the trigger data element name being a parameter, like this:

«Script(ShowDateOnExit,DateElement)»
«OnExitSet(&DateElement&,Show_EndDate,HeadingText,(),
IncrementDate(StartDate,Years,'Y')->IncrementDate(^,Months,'M')->IncrementDate(^,Days,'D')->IncrementDate(^,-1,'d')->FormatDate(^,'d MMM yyyy'),
,EvenWhenNotEmpty)
»
«ScriptEnd()»

And instead of the three, long-winded, OnExitSets, we now have:

«ShowDateOnExit(Years)»
«ShowDateOnExit(Months)»
«ShowDateOnExit(Days)»

Notice how it is not necessary to use «UseScript(ShowDateOnExit, Years)» (although this will have the same effect). The syntax for invoking the Script is similar to that of any other XpressDox command.

The full set of XpressDox code to define the PlaceHolder, Heading and the OnExits looks like this:

«Script(ShowDateOnExit,DateElement)»
«OnExitSet(&DateElement&,Show_EndDate,HeadingText,(),
IncrementDate(StartDate,Years,'Y')->IncrementDate(^,Months,'M')->IncrementDate(^,Days,'D')->IncrementDate(^,-1,'d')->FormatDate(^,'d MMM yyyy'),
,EvenWhenNotEmpty)
»
«ScriptEnd()»

«PlaceHolder(Show_EndDate)»
«Heading(Show_EndDate,|@Red/Microsoft Sans Serif/8.2@ )»
«CaptureDataElement(StartDate,Date)»

«ShowDateOnExit(Years)»
«ShowDateOnExit(Months)»
«ShowDateOnExit(Days)»

The MaximumRepeats Command

There are times when you have a repeater but you do not want the user to be able to add more than a certain number of instances of the repeater in the interview.

You could use a Rule command, but then the user will only get the message once they have pressed the “OK”, or “Assemble” button.

The command

«MaximumRepeats(Child,3)»

would prevent the user from entering more than 3 Child instances in the interview.

The command is very flexible, and supports a function or data element in the second argument. This makes it possible to have a different MaximumRepeats for different situations.

For example, you could say that if there is no Parent value, then the number of children should be zero, otherwise the maximum should be 2, like this:

«MaximumRepeats(Child,IIf((Parent = ''),0,2))»

For completeness sake – the Required command will ensure that at least one Child is entered, if that’s what is needed:

«Required(Child)»«MaximumRepeats(Child,3)»

This would ensure that at least one but at most 3 Child elements would be input in the interview.

The PdfUserPassword Function

This function gives you the ability to provide a user password to a PDF that is created by running a template. In other words, a person wanting to open the PDF file produced will have to supply the password to the application (e.g. Adobe Acrobat) which is being used to open the document.

As an example:

«PdfUserPassword(FormatDate(DateOfBirth,'yyyyMMdd'))»

This will create the user password which is the date of birth provided in the interview.

The template will also need the «SaveAsPDF()» command to be present in order for the feature to take effect.

The DateAsNumber Function

If you want to compare two dates, then typically you want to know whether one date is later than another. The default way that dates are stored in XpressDox is in the format yyyy-MM-dd (e.g. 2018-05-02), but can also be understood by XpressDox in other formats, like “May 2, 2018”. The hyphens or other non-numeric characters inside the date means that the only comparison that can be made between two dates is whether they are equal or not. In order to compare two dates to see which one is before or after the other, the dates need to be made into numbers.

This could be be done by the following:

«If(FormatDate(Date1, ‘yyyyMMdd’) < FormatDate(Date2, ‘yyyMMdd’))»Date1 is less than Date2«End()»

The DateAsNumber function is a shortcut for the above (which is open to "finger trouble" and mis-typing), as follows:

«If(DateAsNumber(Date1) < DateAsNumber(Date2))»Date1 is less than Date2«End()»

Saving Assembled Documents into iManage

Configuration

All that is needed for this feature to be enabled is that a drive letter be configured to refer to the iManage system.  This configuration operation can be accomplished by a user with a Supervisor license, which will give the user access to the Foreign File Systems tab in the XpressDox configuration screen.

 

Choose the Foreign File Systems tab, click the Add New button on the left, and then enter the name and drive letter that you would like to use. The name is purely a description, and any drive letter that you know is unused can be chosen.  You will see that two file systems are currently supported, i.e. Windows and iManage – but Windows is disabled as this is the default and it is not necessary to define the Windows file system for any drive letters.  But you do need to choose the iManage radio button.

It is then necessary to click the Use File System’s Editor button which will present you with a form to complete.

 

Notice that the various fields can contain the <> syntax – in the above example the values of the iManageUserName and iManagePassword data elements which are active at the time access to the iManage system is done will be filled in.

After saving the configuration, you can then press the Test button to make sure the information has been configured correctly.

Addressing the iManage System

Once this configuration has been done, saving assembled documents into iManage is done just by specifying the path to the folder or sub-folder and using normal syntax for a file path for the Windows file system. For example

The file name will be provided either by a command in the template, or will default to the template file name with a .docx extension.

There are many “profile properties” that can be set for a document in the iManage system.  XpressDox will default some of them, but all of the defaults, plus the custom properties, can be set inside the template using the SetCustomDocumentProperty command, as in the following examples, that set the custom1 and custom3 properties for the document:

«CreateDataElement('Custom1','MYCUSTOM1-2')»

«SetCustomDocumentProperty(XDFsProf-custom1,<Custom1>-1)»
«SetCustomDocumentProperty(XDFsProf-custom3,MYCUSTOM3-1)»

Note that XpressDox will regard custom document properties with the name starting with XDfsProf- as being applied to document management systems, and the part of the name following that prefix is the name of the DMS profile property.

 

The GetDataset Function

This function was introduced to enable the entire dataset to be saved as a BLOB in a data base.

Typically, this function will be used in the context of a SetDataSourceData function, something like this:

«SetDataSourceData(‘StagingDataSource’,Guid(), 'XMLBlob',GetDataset(), 'Description',Name)»

In the above, the value of the Guid() function would be used as an arbitrary, unique, ID of a staging table, XMLBlob is the name of the BLOB column into which the data set (from GetDataset()) is written, and the Description and Name are the name and value (respectively) to be written into another column in that row in the table.

The ApplyRulesToDataset Command

It may be that all, or at least some, of the data set to be used to assemble a document comes from some place other than the interview.  For example, it might be that the data are in a data base, or retrieved from a web service or some other data source.  Often data sets like this can contain data elements which are wrongly formatted or which in some other way do not conform to the business rules for the template that is being run.  In this case it might cause a dangerously inaccurate document to be assembled from the data and template.

The ApplyRulesToDataset command will cause all the Rule commands to be executed against the data set, regardless of whether there is an interview or not.

The Rules will be evaluated just before the data set is passed to the assembly engine where the data set is merged into the template. If any of the rules fail, then an error message will be displayed and the assembly terminated.

The ApplyRulesToDataset takes one argument, with the following meanings:

  1. «ApplyRulesToDataset(Yes)»: the command will be applied.
  2. «ApplyRulesToDataset(IgnoreSoftRules)»: any “soft” rules (see Tips and Hints using the Rule Command) will be ignored.
  3. «ApplyRulesToDataset(No)»: the command is ignored completely.