To instruct docassemble to store user input in a variable in
response to a question, you need to include in your
variable name within a directive that indicates how
you would like docassemble to ask for the value of the variable.
Variable names are Python identifiers, which means they can be any
sequence of uppercase or lowercase letters, digits, and underscores,
except the first character cannot be a digit. No spaces are allowed
and no punctuation is allowed except for the underscore,
The following are valid variable names:
nyancat(variables are case-sensitive, so this is not the same as the above)
__f645456DG_greij_43(but why would you use something so ugly?)
USER_PHONE_NUMBER(ok, but why are you yelling?)
The following are not valid variable names, and if you try to use such variable names you will may get an error or unexpected results:
8th_plaintiff(you can’t begin a variable name with a number; Python will say “invalid syntax”)
Nyan-Cat(this is arithmetic:
fried.fish1(this is valid code, but Python will think you are referring to the attribute
fish1of the object
user's_phone_number(apostrophes are not allowed; Python recognizes them as single quotes)
favorite animal(spaces are not allowed)
beneficiary#1(punctuation marks other than
_are not allowed)
applicant_résumé(only plain alphabet characters can be used)
yesno statement causes a question to set a boolean (true/false)
variable when answered.
In the example above, the web app will present “Yes” and “No” buttons
and will set
True if “Yes” is pressed, and
False if “No” is pressed.
noyes statement is just like
yesno, except that “Yes” means
False and “No” means
Note that yes/no fields can also be gathered on a screen along with
other fields; to make screens like that, use
These statements are just like
noyes, except that they
offer a third choice, “I don’t know.” If the user selects “I don’t
know,” the variable is set to
None, which is a special
Python constant that represents the absence of a value.
question block with a
buttons statement will set the variable
field to a particular value depending on which of the
buttons the user presses.
buttons statement must always refer to a YAML list, so that
docassemble knows the order of the buttons.
If an item under
buttons is a YAML key-value pair (written in the
- key: value), then the key will be the button label that the
user sees, and the value will be what the variable identified in
will be set to if the user presses that button.
An item under
buttons can also be plain text; in that case
docassemble uses this text for both the label and the variable
In other words, this:
is equivalent to this:
A powerful feature of
buttons (which also works with
combobox) is the ability to use Python
code to generate button choices. If an item under
buttons is a
key-value pair in which the key is the word
docassemble executes the value as Python code, which is expected
to return a list. This code is executed at the time the question is
asked, and the code can include variables from the interview.
docassemble will process the resulting list and create additional
buttons for each item.
Note that the Python code needs to return a list of key-value pairs (Python dictionaries) where the key is what the variable should be set to and the value is the button label. This is different from the YAML syntax.
This is equivalent to:
You can mix choices that are specified manually with choices that are specified with code:
You can use
buttons as an alternative to
yesno where you want
different text in the labels.
To provide a multiple choice question with “radio buttons” and a
“Continue” button, use
field with a
You can specify a default value using
Another way to set a default is by adding
default: True to the
choice that you want to be the default.
You can also provide help text for a radio button using
These modifications can also be specified when building a list of choices using code:
To provide a multiple choice question with a dropdown selector, use
field with a
To provide a multiple choice question with a “combobox” selector, use
field with a
To add a decorative icon to a
buttons choice, use a key/value pair
image as an additional key.
This works with
choices as well:
It is not possible to decorate
combobox choices with
If you create the list of choices with
code, you can specify an image by including an additional
key/value pair within an item, where the key is
There is an additional feature available when you assemble buttons
code: you can use
DAFileList objects to indicate the image. This example uses an
uploaded image file as the source of the image for one of the buttons:
Multiple choice questions can embed
question blocks and
blocks. These questions are just like ordinary questions, except they
can only be asked by way of the questions in which they are embedded.
You embed a question by providing a YAML key-value list (a
dictionary) (as opposed to text) as the value of a label in a
question blocks can be useful sometimes, it is
generally not a good idea to structure interviews with a lot of
embedded questions. You will have more flexibility if your questions
stand on their own.
It is also possible for multiple-choice questions to embed
blocks that execute Python code. (If you do not know what
blocks are yet, read the section on code blocks first.) This can be
useful when you want to set the values of multiple variables with one
The question above tells docassemble that if the interview logic
calls for either
car_make, the question should be
tried. When the user clicks on one of the buttons, the code will be
executed and the variables will be set.
question with a
field and no
buttons will offer the user a
“Continue” button. When the user presses “Continue,” the variable
field will be set to
Users can upload files, and the files are stored as a variable in docassemble.
signature directive presents a special screen in which the user
can sign his or her name with the trackpad or other pointing device.
In this example, the
user_signature variable will be set to an
object of type
DAFile. This variable can be included in the same
way that a document upload can be included. For example:
or, if you want to control the width of the image:
On a small screen, users need as much of the screen as possible to
write their signature. For this reason, docassemble will reduce
the size of the navigation bar and put the
question text into the
navigation bar. For this reason, you should make sure your
question text is very brief – no longer than “Sign your name.”
You should also make the
subquestion text as brief as possible.
Although you may be developing your app on a desktop or laptop
monitor, your users are probably using smartphones, so test your app
on a smartphone.
Creating a list of fields
fields statement is used to present the user with a list of
fields must consist of a list in which each list item consists
of one or more key/value pairs. One of these keys
(typically) is the label the user sees, where the value
associated with the key is the name of the variable that will store
the user-provided information for that field. The other key/value
pairs in the item (if any) are modifiers that allow you to customize
how the field is displayed to the user.
These modifiers are distinguished from label/variable pairs based on the key; if the key is uses one of the names listed below, it will be treated as a modifier; if it is anything else, it will be treated as a label.
The following are the keys that have special meaning:
datatype affects how the data will be collected, validated and
stored. For a full explanation of how this is used, see the
required affects whether the field will be optional or required. If
a field is required, it will be marked with a red asterisk. The value
required can be
False. By default, all fields are
required, so you never need to write
required: True unless you want
Instead of writing
False, you can write Python code.
This code will be evaluated for whether it turns out to be true or
false. For example, instead of
False, you could use the
name of a variable that is defined by a
yesno question (as long as
that variable was defined before the screen loads; the red asterisk
cannot be toggled in real time within the browser).
You can guide users as to how they should fill out a text field by
showing greyed-out text in a text box that disappears when the user
starts typing in the information. In HTML, this text is known as the
placeholder. You can set this text for a text field by setting
hint. You can use Mako templates.
You can provide contextual help to the user regarding the meaning of a
field using the
help modifier. The label will be green to indicate
that it can be clicked on, and the value of
help will appear on the
screen when the user clicks the green text. You can use Mako
You can provide a default value to a field using
default. You can
also use Mako templates.
choices modifier is used with multiple-choice fields. It must
refer to a list of possible options. Can be a list of key/value pairs
(key is what the variable will be set to; value is the label seen by
the user) or a list of plain text items (in which case the label and
the variable value are the same).
choices indicates a list of objects from
which the user will choose. For more information about using objects
in multiple choice questions, see the
section on selecting objects, below.
If you have a multiple-choice question and you want to reuse the same
selections several times, you do not need to type in the whole list
every time. You can define a variable to contain the list and a
code block that defines the variable.
code to a field makes it a multiple-choice question. The
code itself refers to Python code that generates a list of
possible options for a multiple choice field.
The Python code runs at the time the question is asked. Therefore,
you can use the
code feature to create multiple-choice questions
that have dynamically-created lists of choices.
The Python code needs to be a single expression. The result of the expression can take several forms.
It can be a dictionary (in which case you cannot control the order of items):
It can be a list of text items (in which case the values and labels will be the same):
You can specify a default by including a three-element list where the
third element is
True if the choice should be selected by default.
You can include “help text” for a choice by including a fourth element in one of the lists, where the element contains the help text you want to be available. The user can see the help text by touching the question mark button.
If your code is a list of dictionaries, you can include a
'default' key in the dictionary indicating a true or false value
that represents whether the choice should be selected by default.
Similarly, you can include help text in a list of dictionaries by
'help' key in the dictionary indicating the help text
that should be available to the user.
If you build the list of choices with
code, you can exclude items
from the list using
exclude, where the value of
In this example, the value of
exclude is a single variable. If
given a list of things, it will exclude any items that are in the list.
If you use
datatype: checkboxes, then by
default a “None of the above” choice is added.
You can turn off the “None of the above” choice by setting the
none of the above option to
You can also change the phrase from “None of the above” to something
else, even a Mako expression. Just set
none of the above to the
text you want to be displayed.
If the list of choices for a multiple choice question is empty,
docassemble will try to deal with the situation gracefully. If
there is only a single field listed under
fields, or the question is
a standalone multiple choice question, then the
variable that will be set by the user’s selection will be set to
None, and the question (or the field, if there are other fields
fields) will be skipped.
checkboxes, the variable will be set to an
DADict (a type of dictionary specific to docassemble).
object_checkboxes, the variable will be set to
DAList (a type of list specific to docassemble).
You can use the
show if modifier if you want the field to be hidden
under certain conditions. There are three methods of using
which have different syntax.
Using the first method, the field will appear or disappear in the web
browser depending on the value of another field in the
Under this method,
show if refers to a YAML dictionary with two
variable refers to the variable
name of the other field, and
is refers to the value of the other
field that will cause this field to be shown.
This can be useful when you have a multiple-choice field that has an “other” option, where you want to capture a text field but only if the user selects the “other” option.
The second method is like the first, but is for the special case where
the other field in
fields is a yes/no variable. Under this method,
show if refers to the other field’s variable name. If that variable
is true, the field will be shown, and if it is not true, the field
will be hidden.
Under the third method, the field is either shown or not shown on the
screen when it loads, and it stays that way. You can use Python
code to control whether the field is shown or not. Unlike
the first method, you are not limited to using variables that are part
fields list; you can use any Python code; however, you
cannot refer to any of the variables that are defined by the current
question. Under this method,
show if must refer to a YAML
dictionary with one key,
code contains Python code.
The code will be evaluated and if it evaluates to a positive value,
the field will be shown.
This works just like
show if, except that it hides the
field instead of showing it.
disable others is set to
True, then when the user changes the
value of the field to something, all the other fields in the question
will be disabled.
The value of
note is Markdown text that will appear on the screen;
useful for providing guidance to the user on how to enter information.
If you use
no label as the label for your variable, the label will
be omitted. On wide screens, the field will fill more of the width of
the screen if the label is set to
To keep the width of the field normal, but have a blank label, use
"" as the label.
Instead of expressing your labels and variable names in the form of
Label: variable_name, you can specify a label using the
and the variable name using the
fields question, there are many possible
values, which affect what the user sees and how the input is stored in
a variable. The following sections describe the available
datatype: date provides a date entry input box. The style of the
input box depends on the browser.
Note that while input validation is applied, the resulting variable will be plain text, not a special Python date object. For more information about working with date variables, see the documentation for the date functions. These functions are flexible and will work correctly if you give them dates as text, as long as a date can be discerned from the text.
If you set a
default value for a date field, write the date in the
format YYYY-MM-DD. Many browsers have built-in “date pickers” that
expect dates to be in this format. See Mozilla’s documentation of
the date input field. If the browser uses a date picker, then your
interview will see text values in the form YYYY-MM-DD, but on other
browsers, like Firefox, the format may be some other format.
datatype: email provides an e-mail address input box.
datatype: currency indicates that the input
should be a valid numeric value. In addition, the input box shows a
currency symbol based on locale defined in the configuration.
The variable will be set to a number, just as if
was used. For information about how to display currency values, see
datatype: range shows a slider that the user can use to
select a number within a given range. The range must be supplied by
max values. An option
step value can also be
provided, the default of which is 1.
files datatypes within a
fields list, you can
allow users to upload one or more files.
datatype: file indicates that the user can upload a single file.
The variable is set to a
DAFileList object containing the
necessary information about the uploaded file.
datatype: files indicates that the user can upload one or more
files. The variable is set to a
DAFileList object containing the
necessary information about the uploaded files.
If your users upload digital photos
into your interviews, the uploads may take a long time. You can
configure an upload field so that images are reduced in size before
they are uploaded by modifying your field definition with a
maximum image size. The image will be reduced in size so that is
no taller than or wider than the number of pixels designated by
maximum image size.
In this example, images will be reduced in size to no more than 100 pixels in height or width:
Note that the image file type of the uploaded file may be changed to PNG during the conversion process. Different browsers behave differently.
If you have a lot of document upload fields, you can set a default
maximum image size on an interview-wide basis with the
maximum image size interview feature and on a site-wide basis with
maximum image size configuration directive. If you have a
default set up, but you want to override it for a particular field,
you can set the
maximum image size field modifier to
There are a few other data types that result in file uploads:
datatype: camera is just like
with an HTML5 input type that suggests using the device’s camera to take a
picture. On many devices, this is no different from
Whether these special data types do anything different from the
data type is dependent on the web browser. Mobile browsers are the
most likely to respond to these features.
datatype: yesno will show a checkbox with a label, aligned with
datatype: noyes is like
datatype: yesno, except
with True and False inverted.
Sometimes, when you are using a series of
these checkboxes, you might want to have a “none of the above”
selection. To do this, add a field for the selection, and associate
it with a variable. (Your interview does not need to use the
variable.) Then modify the field with
uncheck others: True.
This will cause the field to act as a “none of the above” field for
all the other yes/no checkbox fields on the page. If you want the
field to only relate to specific other fields, use a list of the
variable names of those fields instead of
datatype: checkboxes will show the
choices list as
checkboxes. The variable will be a
DADict (a type of dictionary
specific to docassemble) with items set to
depending on whether the option was checked. No validation is done to
see if the user selected at least one, regardless of the value of
As you can see in this example, the keys of the resulting dictionary
are the names of fruit, the values that are checked are
the values that were not checked are
In the example above, the keys of the dictionary are the same as the labels displayed to the user. If you want labels to be different from the keys, you can specify the choices in the following manner:
You can generate checkbox choices with code:
To set default values in a checkbox list, you have a few options.
If you want to select just one option, just indicate the name of the option:
If you want to select multiple options, indicate a YAML list:
You can also indicate your defaults in the form of a YAML dictionary:
You can also use Python code to generate the defaults:
datatype: object is used when you would like to use a variable to
refer to an existing object. You need to include
choices, which can be a list of objects.
datatype: object in combination with
you can create questions that either set the attributes of an object
or set the object equal to another object.
In this example, if the gardener and the cook are the same person, the interview effectively does the following in Python:
Please note that
datatype: object cannot be used with
generic object modifier if the variable being set is
For a fuller discussion on using multiple-choice object selectors, see the section on selecting objects, below.
datatype: object_checkboxes is used
when you would like to use a question to set the elements of an object
DAList (or a subtype thereof). The choices in
choices (optionally modified by
exclude) will be
presented to the user as checkboxes. The
.gathered attribute of the
variable will be set to
True after the elements are set. See
groups for more information.
You can also use
datatype: object_checkboxes on variables that
already exist in your interview. You would need to do this if you
wanted the variable to be a subtype of
DAList. If you use a
variable name that already exists, note that the
question will only
be used when the
.gathered attribute is needed. To avoid questions
False. For example:
Another advantage of using an already-existing variable is that the
choices in the question will default to the current elements in the
list. In this example, we use the
.append() method to initialize
the list of villains.
From the user’s perspective,
datatype: ml works just like
text (which is the default if no
datatype is indicated), and
datatype: mlarea works just like
From the interview author’s perspective, however, the variable that is set is not a piece of text, but an object representing a classification of the user’s input, based on a machine learning model that is “trained” to classify user input.
For more information about how to use machine learning variables, see the machine learning section.
Some datatypes, such as numbers, dates, and e-mail addresses, have validation features that prevent the user from moving to the next page if the input value does not meet the requirements of the data type. The jQuery Validation Plugin is used.
For some field types, you can require additional input validation by adding the following to the definition of a field:
numberdata types, require a minimum value. This is passed directly to the jQuery Validation Plugin.
numberdata types, require a maximum value. This is passed directly to the jQuery Validation Plugin.
minlength: require a minimum number of characters in a textbox, number of checkboxes checked, etc. This is passed directly to the jQuery Validation Plugin.
maxlength: require a maximum number of characters in a textbox, number of checkboxes checked, etc. This is passed directly to the jQuery Validation Plugin.
You can also use Python code to validate an input field. To do so,
validate directive to the field description that refers to the
name of a function that returns
True (or something that Python
considers “true”) if the value is valid, and
False (or something
that Python considers “not true”) if the value is invalid.
In this example, the function
is_multiple_of_four is defined as
The error message that the user will see is a generic error message, “Please enter a valid value.” In most cases you will want to explain to the user why the input did not validate. To provide a more descriptive error message, your function can raise an exception using the error message you would like the user to see. Both a false return value and an exception signal that the input is not valid.
In this example, the function
is_multiple_of_four is defined as
This Python code is in the
validationfuncstwo.py file. If 4
does not divide the input value into a whole number, then an exception
is raised. The text passed to
Exception() will be the text the user
sees if the value does not validate. If 4 does divide the input value
by a whole number,
True is returned.
One limitation of these validation functions is that they can only test for characteristics inherent in the variable being validated; they cannot compare the variable to other variables.
You can get around this restriction using the
Note that the code under
validation code is not within a function,
so it should not try to
return any values. If the code runs through
to the end, this indicates that the input for the question is valid.
If an exception is raised, the input for the question is invalid.
If the input is invalid, the user will see a message at the top of the
screen containing the error message passed to the
Here is a lengthy example that illustrates many of these features.
But what if you wanted to use a variable to refer to an object, such as a person? You could try something like this:
In this case,
tallest_person would be set to the name of the
client or the name of the
advocate. But what if you wanted to
then look at the birthdate of the tallest person, or some other
attribute of the person? If all you had was the person’s name, you
would not be able to do that. Instead, you would want
tallest_person to be defined as the object
client or the object
advocate, so that you can refer to
as you would refer to
You can accomplish this by setting
object within a
fields list, where the
choices are the names of the objects from
which to choose. (Optionally, you can set a
default value, which is
also the name of a variable.)
Note that this interview incorporates the
which defines objects that are commonly used in legal applications,
advocate. It also contains questions for
asking for the names of these people.
The interview above presents the names of the
client and the
advocate and asks which of these people is the villain.
If the user clicks the name of the advocate, then docassemble will
define the variable
villain and set it equal to
Note that because
advocate is an object,
villain will be an
advocate, not a copy of
advocate. If you
advocate.birthdate, you will immediately be able
retrieve that value by looking at
villain.birthdate, and vice-versa.
villain is an alias, if you refer to
villain.favorite_food and it is not yet defined, docassemble
will go searching for a question that offers to define
advocate.favorite_food. This is because docassemble objects
have an intrinsic identity, a unique name given to them at the time
they are created. (You can inspect this by referring to
villain.instanceName in a question and will see that it returns
advocate.) For more information about this, see the discussion in
the documenation for DAObject. (All docassemble objects are
subtypes of DAObject.)
If any of the objects listed under
lists of objects, such as
PartyList, those lists will be expanded and every item will
be included. You can also include under
choices Python code, such
Any variable name referenced in
[FIELD ...] must be one of the
variable names listed in the
fields: list. If a field is referenced
this way in the
subquestion, it will not be displayed the way that
fields are ordinarily displayed, but will be moved into the
subquestion, where it will be formatted differently. Any fields
fields: list that are not referenced in the
will appear on the screen in the normal fashion.
The label of an embedded field is used as the tooltip of the field.
When you are using embedded fields, you can
add the field modifier
inline width to change the initial width of
the field. For example, if you include
inline width: 15em, the
CSS will be altered so that the field is 15em wide. This modifier
has no effect when embedded fields are not being used.
You can use Python code to generate items inside a
fields. To do
so, simply add an entry under
fields that contains
nothing more). The contents of
code will be evaluated as a Python
The expression must evaluate to a list of dictionaries, and the format
must be the Python equivalent of a regular
fields item, which you
would normally express in YAML.
For example, if you want the fields to be like this:
you would write this:
Here is an example that asks for the names of a number of people on a single screen:
Note that it is necessary to use the
sets modifier on the question
to manually indicate that the question will define
people[i].name.first. Normally, docassemble automatically
detects what variables a question is capable of defining, but when the
fields are dynamically generated with code, it is not able to do so.
Note also that this example uses the
field method for
indicating the label and the variable name for each field. This is
not required, but it may make field-generating code more readable.
Dynamically-created lists of fields can be paired with
subquestion text that embeds the fields.
It is also possible to mix dynamic fields with non-dynamic fields:
Writing Python code that generates a list of fields can be pretty
complex. This should be considered an advanced feature. Note that
the code above uses the Python function
str() to reduce the
index of a list (which is an integer) into a string, for purposes of
constructing variable names like
If you work with dictionaries (
DADict objects) instead of lists
DAList objects), a useful function is the Python function
repr(), which returns a string containing a string with quotation
marks around it.
For example, suppose you want to replicate this:
You could do something like the following:
The alternative is to try to provide the quotation marks manually,
which can look messier, and then you have to worry about what to do if
key string contains an apostrophe; will that cause a syntax
repr() function takes care of this problem by
producing a robust Python representation of the string.
docassemble lets you write a single question that can be re-used throughout an interview.
For example, suppose you want to gather the following variables:
It would be tedious to have to write separate questions for each of these variables.
The special variable
x stands in for any object of type
You can nest iterators up to six levels, using the variables
n, but you have to use them in this order.
For more information about populating groups of things, see the groups section.
For more information about how docassemble identifies what question to ask in order to define a given variable, see the interview logic section.
In docassemble, you can allow users to click links or menu items
that take the user to a special screen that the user would not
ordinarily encounter in the course of the interview. You can create
such a screen using the
event statement acts just like
sets: it advertises to
docassemble that the question will potentially define a variable.
In the following example, the variable
show_date is never defined;
it is simply sought. The
task_not_yet_performed() function is
used to make sure that the dialog box only appears once.
event statement is important if you use the roles feature to
conduct multi-user interviews.
In the example above, the
event line tells docassemble that this
question should be displayed to the user if docassemble
role_event, which is a special “event” that can
happen in multi-user interviews. The event is triggered when the
interview reaches a point when a person other than the current user
needs to answer a question. For example, while a client is filling
out an interview, the interview logic might call for a variable that
can only be set by an advocate who reviews the client’s answers. In
this scenario, a
role_event will be triggered. When this happens,
docassemble will look for a
code block that
defines the variable
role_event, and it will find the example
This directive can also be used to create screens that the user can reach from the menu or from hyperlinks embedded in question text. For information and examples, see url_action(), process_action(), action_menu_item(), and menu_items.
review block allows interview authors to provide a screen where
users can review and edit their answers. Typically, the user will get
to this screen by selecting an option from the web app menu (e.g.,
“Review Answers”), or by clicking on a hyperlink within
text (e.g., “to review the answers you have provided so far, click
Here is an example of a
review block that is launched from the menu:
If you click “Favorite fruit,” you are taken to a
you can edit the value of
fruit. This has the same effect as
'fruit' or running an action on
'fruit'; whatever block in your interview offers to define
will be used. After the user edits the value of the variable, the
user will return to the
review screen again.
Note that the
review block does not show a link for “Favorite
fungus” because the variable
fungi has not been defined yet.
fungi is defined, the
review block would show it.
This behavior is different from the typical behavior of
docassemble blocks. Normally, referring to a variable that has
not yet been defined will trigger the asking of a question that will
define that variable. In the
review block, however, the presence of
an undefined variable simply causes the item to be omitted from the
You can provide the user with a review of answers and buttons that the user can press to revisit an answer:
In addition, the
review block, like the
fields block, allows you
If these are modified with the optional
show if modifier, they will
only be displayed if the variable referenced by the
show if modifier
has been defined. In addition, if any of these entries refer to a
variable that has not been defined yet, they will be omitted.
review block allows you to add
help text to an entry, in
which case the text is shown underneath the hyperlink. If this text
expects a variable to be defined that has not actually been defined,
the item will not be shown. Note: this is not available with the
button display format.
By default, the
review block puts a “Resume” button at the bottom of
the screen. If you want the label on the button to be something other
than the word “Resume,” add a
resume button label modifier.
The list of variables to display to the user in a
review block needs
to be specified by the interview author. There are several reasons
why this needs to be done manually as opposed to automatically:
- Variables in your interview may be interdependent. You do not
necessarily want to allow the interviewee to edit any past answer
at will because this may result in internal inconsistencies or
violations of the logic of your interview. For example, if your
interview has a variable called
eligible_for_medicare, which is set after the user answers a series of questions, you would not want the user to be able to go back and set his or her age to 30, at least not without a reconsideration of the definition of
eligible_for_medicare. Therefore, it is important that the interview author control what the user can edit.
- A list of answers already provided might not be user-friendly unless the interview author presents it in a logically organized fashion. The order in which the questions were asked is not necessarily the most logical way to present the information for editing.