Recently, we looked at how to use the ADD and CLEAR instructions in HotDocs to dynamically create an option for widows and widowers, so that regardless of gender of our client, the user was always presented with a gender appropriate reference, that still had an identical option under the hood. This time, we’re going to look at the real power of these instructions: with dynamic repeating content. For this article, we’re going to look at a situation where we have to address a single letter to multiple vendors and have those vendors specified by the user during the interview. Here’s the pieces:
VENDOR RPT – repeating dialog that collects vendor data
VENDS Name Full TE – the full name of the vendor on VENDOR RPT
VENDS Addr Block CO – a computation that calculates for address block for each vendor (code not listed, it could just as easily be a text/memo field that is filled in)
LETT Vendors MS – a multi select, multiple choice variable that will ask the user which vendors they wish to send a letter to (dynamically created)
flt LETT Vendors CO – a filter that will look at the user selections in LETT Vendors MS, and filter out the ones that weren’t selected.
COUNTER – the HotDocs system variable that will return the number (as a number) of the current repeating dialog. This can ONLY be used inside a repeat instruction.
Here are the steps:
1) Clear LETT Vendors MS and ADD all vendors to it
2) Present LETT Vendors MS to the user for selection
3) REPEAT VENDORS RPT in the template with the appopriate filter, so only those vendors selected in LETT Vendors MS appear in the resulting document.
Firstly, somewhere in your interview process (you DO use interview computations to calculate, control and regulate data collection for your templates, right?), you will have ASKed the user to fill in the vendor details. Presuming that we have already collected our vendor details, we now need to build the multiple choice variable. So somewhere in your interview computation, but AFTER you have ASKed VENDOR RPT, we do this:
ASK NONE
CLEAR LETT Vendors MS //clear first, then ADD
REPEAT VENDOR RPT
ADD "«COUNTER»|«VENDS Name Full TE»" TO LETT Vendors MS //the option is the counter, the prompt is their name
//you could wrap the add instruction inside an IF statement, if you are uncertain as to whether VENDS Name Full TE is ANSWERED() or some other logic particular to your system
END REPEAT
ASK DEFAULT
We now have LETT Vendors MS containing a full list of all vendors. So at somepoint after the above script runs, you would ASK LETT Vendors MS, most likely as part of a dialog that relates to the letter we are drafting. Now for what our FILTER looks like.
"«LETT Vendors MS::a|b|c»" CONTAINS "«COUNTER»"
This is a little tricky. Multiple choice variables store their results as text, but multi-select multiple choices store their values as an ARRAY of text – much like a repeat. Because of this, a multi-select variable cannot be directly compared to a straight line of “regular” text. Additionally, no multi choice variable can be compared directly to a number. So there are three solutions in that one line of code. The value of LETT Vendors MS is converted to a REGULAR line of text, using the chevrons embedded inside double quotes. That’s the first solution. The second solution is to use a custom list format, “a|b|c”, which means that each selection is split by a pipe | character. I’ll explain this in a later! The third solution was to wrap COUNTER in chevrons and quotes, which takes COUNTER – a numeric value, and converts it to a string. With all of this going on, we can now use CONTAINS to correctly compare the selections of LETT Vendors MS and the value of COUNTER.
Now, for the template….
«REPEAT VENDOR RPT::::flt LETT Vendors CO»
«VENDS Name Full TE»
«VENDS Addr Block CO»
Dear «Some Variable Here»
Some letter content here....
{-- conditional page break --}
«END REPEAT»
This instruction will repeat the template infinitely whilever there are iterations inside VENDOR RPT, but will ONLY include iterations where the filter is true. For the sake of this article, lets say there are three vendors: 1) John Doe 2) Jane Doe and 3) Billy Blogs. When presented with LETT Vendors MS, it looks like this (brackets contains options):
(1) John Doe
(2) Jane Doe
(3) Billy Blogs
Lets say the user selects 1 and 3. Here’s what our FILTER looked like:
“«LETT Vendors MS::a|b|c»” CONTAINS “«COUNTER»”
Here’s what happens when our template repeats:
Repeat #1: “1|3” CONTAINS “1” (evaluates to TRUE, John is included)
Repeat #2: “1|3” CONTAINS “2” (evaluates to FALSE, Jane is excluded)
Repeat #3: “1|3” CONTAINS “3” (evaluates to TRUE, Billy is included)
Congratulations. Your multi select multiple choice variable has allowed you to quickly present a list of ALL vendors to the user and ask them which one gets a letter. No databases (although you could use one), nothing too heavy; simply collect the vendors, build the multiple choice variable in HotDocs, ask which vendors get the letter, then repeat and filter for the selected values.
Now, I promised a bit more explanation on the whole “a|b|c” thing. To do that, lets look at a concept called DELIMITING. Delimiting is simply putting a specific character between each value you want to look at. Common delimters are commas and pipes. I prefer pipes, as they aren’t ever used in names, addresses and other pieces of data – they truly do identify the end of one bit of data and the start of the next one. But lets say we DIDNT delimit our selections from LETT Vendors MS. Lets say we have 14 vendors (wow!), and the user selected 1, 4, 5, 6, 12. The value might look like this:
145612
That’s right – its just a string of numbers. This would mean our filter would “break” when repeating vendor #14. Because the text “14” appears inside “145612”, even though the user did not selection option #14. However, with delimiters, our value looks like this:
1|4|5|6|12
And 14 does NOT appear in that value, so the comparison is run correctly.
Clear as mud? Its a bit to get your head around, but when comparing multiple selections in multiple choice options, it is definitely best practice to delimit your strings and use CONTAINS instructions.