Designing forms
The Design tab holds your forms and server datasets. A form is an XLSForm workbook (.xlsx or .xlsm): Joripo compiles it itself and serves it to phones, web forms and the tester. A form only reaches phones once it is deployed.
Upload a form
- Use a [+] bar in the list (or Upload form definition) and drop your workbook (.xlsx or .xlsm).
- Turn on Attach files and add the form's attachments in the same upload, as many as it has, all at once: images, audio, video, preload .csv files, field plug-ins (
<name>.fieldplugin.zip) and .zip packages of any of them. An .xlsx data file is converted to the .csv the form reads. - Tick any server datasets the form should be able to
pulldata()from.
Each form in the list shows whether it is Live (phones and web forms get it), how many submissions it has and when the last one arrived, and how many attachments it carries. Details under it gives the form ID, the deployed version and the attachment packages; file sizes are in the form's Attachments panel.
Joripo checks the workbook, compiles it and deploys it as one step. What happened is said in a box over the page, closed with OK: if anything is wrong it lists each problem with its sheet, row and column, nothing that was already live changes, and the upload panel stays open with your files still chosen; once the form is deployed (with any warnings to check before collecting data) the panel closes and the form is in the list at once. The Attach files and Attach server datasets switches belong to that form's upload: they start off each time a form's upload panel is drawn, and turning one on opens its box at once. What you chose for one form never carries over to another.
A preload only works when three things line up: the form calls pulldata('name', ...), a file name.csv is attached, and the names match. File names are matched without regard to case, and the deploy message names any preload file nothing has attached. See Preloads.
Which file is the form, and which are its attachments
- The workbook you upload as itself (not inside a .zip) is the form, whatever the .zip files beside it hold.
- A .zip is unpacked and its files are attached. It stays one package, which can be downloaded as it was uploaded.
- A field plug-in (
<name>.fieldplugin.zip) is attached whole, wherever it is in the upload, and never unpacked. When a .zip holds a plug-in's source code (a folder with manifest.json, template.html and script.js) beside the built plug-in, the source code is left out. - A .zip that holds another form is not this form's package. The .zip a field plug-in's page gives for download is one: it carries the plug-in beside its sample form, its source code and its README. Only the field plug-ins in it are attached, and the deploy says what was left out.
- A workbook the form reads by name (
pulldata('name', ...),search('name', ...),instance('name')orname.csv) is its data file, even when it has a sheet calledsurvey. Two forms that do not read each other are refused: upload one form at a time. - With no workbook uploaded as itself, a .zip that holds the form and its media is the form's package, and the form is taken from inside it.
To add files to a deployed form without a new version, use Add files in its Upload panel: several files at once, by the same rules. Phones get them at their next refresh.
When a form is refused
A refused upload changes nothing on the server: the version that was live stays live, and the upload panel keeps your files chosen. The box over the page lists every problem, each with the sheet, row and column to look at (the row number Excel shows), and How to fix this beside a problem opens the part of this help that explains it. Copy copies the whole list, to send to a colleague.
- Row 12, relevant: ... and the like: an expression or a cell Joripo cannot read. The sentence says what is wrong; owners and managers also see the expression as written and the form engine's own words under Technical details.
- form_id and version problems: see Versions.
- ... which is not attached: a file the form reads is missing: see Preloads.
- The upload holds 2 forms: two workbooks with a
surveysheet, and neither reads the other as a data file. Upload one form at a time, with its own attachments; see Which file is the form. - Your plan allows ... forms: the forms limit. New versions of the forms you have are always accepted; see Usage and limits.
Correct the workbook and upload it again. Every problem comes back at once, so one upload shows everything still to fix.
Warnings and notes
A deployed form can come with warnings: things that are probably not what you meant, worth correcting before you collect data, such as a constraint Joripo cannot read (so any answer is accepted), a picture the form shows that is not attached, or a timer that waits on a later question. The box lists them with their rows.
Notes say how a part of the form will behave, so nobody is surprised; there is nothing to correct. They are folded away under Notes in the box: for example a search() whose search type is read as contains, jr:choice-name() on a question that has no choices, or section timers that ODK Collect would record differently. More about this beside a note opens its explanation.
Preloads: pulldata() and search()
A form can read values from a CSV file attached to it, or from a server dataset attached to it:
pulldata('households', 'head_name', 'hhid', ${hhid})gives one value: thehead_nameof the row ofhouseholds.csvwhosehhidequals the answer tohhid.- A choice list whose appearance is
search('households', ...)lists rows of the file as its choices (below). - A
select_one_externalquestion takes its choices from a CSV named after its list.
The file is named without .csv, and names are matched without regard to case. A server dataset counts as attached when it is attached to the form: its file name is its ID with .csv. A file nothing has attached is named in the deploy's warnings, and its values read blank until it is attached.
search() in a choice list
search('file', 'type', 'columns', text, 'filter column', filter value):
- file: the attached CSV, without
.csv. - type:
contains,startswith,endswithormatches(an exact match). Any other word, such as'DISTRICT_CUSTOMER', is read ascontains, as ODK Collect reads it; the deploy says so in a note and refuses nothing. - columns: the column to search in, or several separated by commas (
'name, name_bn'); a row is listed when any of them fits. - text: what to look for, usually an earlier answer such as
${district}. While it is blank, every row is listed. - filter column and filter value, optional: a column the rows must also equal the value in, to list one district's upazilas only.
With only the file, search('location') lists every row. On the choices sheet, the list's row names the CSV columns to store (name) and to show (label).
For example, districts, then the upazilas of the district chosen:
search('location', 'matches', 'level', 'district')search('location', 'matches', 'level', 'upazila', 'district_code', ${district})
jr:choice-name()
jr:choice-name(${q}, '${q}') gives the label of the choice chosen for q, in the language the form is shown in. It means something only for a select_one or select_multiple question. On a question that has no choices (a text or integer question, say) there is no label to give: the field is stored blank, and the deploy says so in a note. To keep what was typed, use ${q} instead.
Timers (calculate_here)
A calculate_here field records something, usually the time (once(format-date-time(now(), '%Y-%m-%d %H:%M:%S'))), when the enumerator reaches it.
- Form-start timers: one before the first question records when the form was opened. That is what it is for, and nothing is said about it.
- Section timers: one placed later records when the enumerator got to it. Joripo Collect, web forms and the tester record each one when it is reached. ODK Collect cannot: it works a calculation out when the form opens, or when its group's relevance becomes true. The deploy names these timers in a note. Nothing to change if the form is filled on Joripo's own clients; if it will also be filled on ODK Collect, put each timer in its own group with the section's relevance.
- A timer waiting on a later question is a warning: its relevance depends on a question that comes after it, so when the enumerator reaches the timer its relevance cannot be true yet, and it stays blank or records a later moment. Move the timer below that question, or make its relevance depend on a question before it.
- Timers with no question between them are reached together, so they record the same moment.
Field plug-ins
A field whose appearance is custom-<name>(...) is drawn by a field plug-in, the file <name>.fieldplugin.zip attached to the form. In Joripo Collect, web forms and the tester such a field works whether or not that file is attached: it can be answered, and its answer is checked, saved and submitted like any other. ODK Collect runs no plug-ins and shows the field as its plain question. The deploy adds a note for each plug-in the form uses without its file, naming its fields and saying which case applies:
- Attached: when
<name>.fieldplugin.zipis attached, the plug-in draws the field. It runs in a closed frame that cannot reach the page, your sign-in or other forms, so attach only plug-ins whose source you trust. An attached file always comes first, even for the plug-ins Joripo draws itself, unless the plug-in does not take that type of question: then the field is drawn as below. - Built into Joripo, the ranking:
custom-rankingchoiceson a multiple-choice question needs no file, because Joripo draws it itself. The respondent moves each choice up or down, and the answer is every choice in ranked order (3 2 4 1;selected-at(${rank}, 0)is the first). Its parameters work as the plug-in documents them:numbers=0hides the rank numbers,allowdef=1accepts the starting order as the answer without a move, anddefaultsets the starting order. In the form builder it is the custom-rankingchoices switch on a multiple-choice question. - Built into Joripo, the table of choices:
custom-table-liston a single- or multiple-choice question needs no file either. The choices are a table, a row each, with a search box above it and headings that sort the rows.delimitersplits each choice label into columns andheadersnames them, in order: withcustom-table-list(delimiter='|', headers='Name, Gender, Age'), the labelJane Doe | Female | 27fills the three columns. Withoutheadersthe table has no heading row, and withoutdelimitereach label is one column. The respondent taps a row, or its button, to choose it, and the answer is the question's own: the chosen choices. In the form builder it is the custom-table-list switch. - Built into Joripo, the searchable list:
custom-search-select-oneon a single-choice question (also spelledcustom-search-select-single) andcustom-search-select-multipleon a multiple-choice question need no file. The question's own choices are shown with a search box above them: typing hides the choices whose label does not contain what was typed, and a chosen choice stays chosen while hidden. The answer is the question's own. The appearance wordautocompletegives any choice question the same search box. - Plain question: any other plug-in, when its file is not attached, is drawn as the field's own question with the field's other appearance words:
minimal custom-stars(max=5)on a single-choice question is a drop-down. So is a built-in plug-in on a type of question it does not take, such ascustom-table-liston a text question. Attach the plug-in's file to give the field the plug-in's own look. - Native in Joripo: the Rank question type puts the choices of a list in order. Use it for new forms; ODK Collect draws it too.
In the tester, the inspector's Field plug-in card says which case applies to the field on screen.
Versions
Each form's settings sheet carries a form_id and a version. To publish a new version, use that form's own Upload button: the workbook's form_id must be the form's, and its version must be a single whole number that is higher than the deployed one and has the same number of digits (devices compare versions as text, so 1000 would sort before 999). Untick Keep existing file attachments to ship only the files in this upload.
Every deployed version is kept. Download gives the workbook and compiled XForm of any version, a printable version, and a Stata .do template.
Attachments and datasets
A form's Attachments panel lists its files, shows previews of images, audio and video, adds or removes files, and downloads everything as one .zip. On the Design page, a form's Download panel lists its files, and Add files in its Upload panel adds more to the deployed version, several at once. A package you uploaded as a .zip (a folder of 400 images, say) stays one package.
A server dataset is a table held on the server and attached to any number of forms, so phones can look values up in it. Create one with Add server dataset (a .csv or .xlsx with a unique ID column), then attach it from a form's Attachments panel. Uploading new data can replace, append to or merge with what is there; phones get it on their next refresh. Detach takes a dataset off a form (on Datasets in Joripo 2.0, beside each form that uses it; under the form on the Legacy console's Design tab). A dataset no form uses can be deleted.
Dataset IDs
A dataset's ID is the name forms read it by: its file is the ID with .csv, so pulldata('village_list', ...) reads the dataset village_list. Leave Dataset ID empty and Joripo makes one from the title: lower-case letters, digits and underscores, accents dropped, so Village List (Round 2) becomes village_list_round_2. A title that starts with a digit gets dataset_ in front, and an ID another dataset already has gets _2, _3 added. The box shows the ID it will use as you type. An ID never changes once the dataset exists, because forms refer to it; to use another, create a new dataset.
Attaching a server dataset
Attach a dataset when you upload a form (Attach server datasets, then tick it), from the form's Attachments panel, or when you create the dataset (tick the forms that should use it). The form reads it under its file name, and phones get it, with any new data, on their next refresh.
- A dataset ... already exists: another dataset in this workspace has that ID. Choose another, or leave the ID empty for one made from the title.
- A form that reads a file nothing has attached says so when it is deployed: attach the dataset, or a CSV of that name.
- Detach takes the dataset off one form; that form's preloads read blank until something of that name is attached again.
A form with an enumerator field asks whoever fills it in who they are: they pick their name from a list, enter or scan their enumerator ID, or add themselves, and the phone or browser remembers them and only asks them to confirm next time. The list is the form's attachment enumerators.csv, with the columns id, name and, if you like, users (the sign-ins each enumerator is listed for). Make it a server dataset with the ID enumerators and attach it, and anyone who adds themselves is added to it when their form arrives. The answer is saved as "Name (ID)"; enumerator-id() and enumerator-name() give each part.
A dataset that names people (a household list with names, phone numbers or addresses) can be marked Identifying data: tick Contains identifying data when you create it, or use the Identifying data button on its row. Then only people with identity access to the workspace (Workspace › Privacy) can download it, open it from the form's attachments or see it in the attachments .zip, and every download is recorded. Phones and web forms still receive it with the form, because the form needs it. Only an owner, or a manager with identity access, can mark or unmark a dataset; the mark stays when new data is uploaded.
Build or edit in the browser
Start new form opens the form builder; a deployed form's Edit opens the same editor on its definition. It offers every question type Joripo runs (pick one by its plain name or its XLSForm keyword) and every column: open a question for Question (labels and hints per language, required, choices), Logic (relevance, constraint and its message, required message, calculation, default, choice filter) and Advanced (appearance, read only, parameters, media). Form settings holds the title, version, default language, instance name and languages; Spreadsheet view shows the sheets as in Excel. Download .xlsx gives the workbook without deploying; Deploy runs the same checks as an upload. Duplicate copies a form under a new ID and title.
Each label and hint has a Plain text / HTML switch. In Plain text the phone shows exactly what you type, even a <. In HTML you write the markup yourself (<b>, <i>, <span style="color:red">), with buttons for bold, italic, underline, a line break and a colour, and a preview drawn as the phone will draw it. A label that already holds markup opens in HTML.
Each media box has an Upload… button: the file goes with Deploy and is attached to the new version. A file with the name of one the form already has replaces it, for every question and choice that names it, and the box says so. A different file with the name of one chosen for another box gets a name of its own (image_2.png), since on the phone one name is one file.
Relevance, constraint, calculation, choice filter, repeat count and the other expressions are checked as you type, by the same rules Deploy uses: a problem is shown under its box in the words Deploy would refuse it with. A constraint that cannot be read is shown as a warning: Joripo deploys the form and does not check that answer.
Appearance shows the appearances the question's type takes as switches; you can still type any other, and the editor says when Joripo's form runtime does not use one.
Each question, note and group, and each choice (its picture button in the choice list), has an image, audio and video per language. Upload… picks the file: it is sent with Deploy and becomes an attachment of the new version, and the box says whether the form already has the file it names. A file chosen but not yet deployed is lost if you leave the page.
Move up and Move down move a question, or a whole group, one place at a time, into groups as well as out of them.
Edit cells in a table
For corrections, a deployed form's Table (in the Form Designer's toolbar, or Correct it in a table on the form's page) lists its questions and its choices with the cells people change most: the label, hint and constraint message in each language, name, type, required, relevance, constraint, calculation and appearance, and each choice's value and label. A hint or constraint message column with no language (or in a language the labels are not in) is shown as its own column, in your workbook's spelling. Owners and managers can use it, as they can upload a form; reviewers and data collectors cannot, and someone a workspace is shared with only when their role administers forms.
Click a cell (or move to it with the arrow keys and press Enter) and type. Enter keeps the change, Esc cancels it, Tab keeps it and moves to the next cell, and Shift+Enter starts a new line in a label. A changed cell is marked, with its own ↺ to undo it; the list of changes not saved yet is above the table, and Discard changes undoes them all. Each change is checked as you make it, by the same rules Deploy uses: a cell Deploy would refuse is outlined in red with Deploy's own words, and a warning (a constraint that cannot be read, which deploys and is not checked) in amber.
Save draft saves the changes as a new draft of the workbook. Nothing is deployed: phones and web forms keep the deployed version, and every version already deployed stays exactly as it was. The draft is the workbook you opened with only the cells you changed altered; every other cell, column, sheet, the settings sheet, media names, the column names as your workbook spells them (relevance, label:English), widths, fonts and colours stay as they are. A cell that held an Excel formula keeps the value it showed, without the formula, and pictures pasted onto a sheet are not kept. A save that would add a problem Deploy refuses is not made; a problem the form already had is listed but does not stop a correction.
While a save or deploy is under way the cells cannot be edited. Deploy draft deploys the saved draft as the next version, with the same checks as an upload, and is refused if another version was deployed after the draft was saved; until then Download .xlsx gives the draft. If someone saves a draft or deploys a version while you are editing, your save is refused and says who changed the form and when: your changes stay listed on the page, so reload the table and make them again. A draft that a newer deployed version has overtaken is kept and can be downloaded from the table, but it is no longer what the table opens. The full editor says when a draft is waiting, since a version deployed from there leaves the draft behind.
Test before you field
Test opens the form in the browser exactly as phones run it. See Testing a form.
Quality-check fields
Joripo's quality checks need to know which questions hold the enumerator, start and end times, GPS and stratum. A form's HFC checks (under its Tools, or on Monitor) opens its quality-check settings: Which question holds what shows what was detected for the form and lets you correct it, and below it are the checks that run and their thresholds. Tools › Quality-check fields opens the same page. If the checks seem to do nothing, look there first. See Monitoring quality.
Groups and deleting
Group forms and datasets with a [+] bar's group option or Organize; only the grouping changes. Delete moves a form, with all its versions and data, to the workspace's trash; download a copy of its files first if you may need them.