Upload form management¶
Upload forms define how users and external clients can submit data to a project. A form specifies its destination table, availability, access settings, supported clients, fields, validation rules, default values, and relationships between fields.
List of available forms¶
Existing forms can be selected for editing, deletion, or blocking.
Data cannot be uploaded using blocked forms, and these forms are not visible to clients in the list of forms. Offline clients cannot upload data using deleted forms, and deleted forms cannot be restored. By editing forms, you can change their scope (web, API or file upload), their relationship with database table fields, their description and access rules, as well as whether they operate in observation event or ad hoc mode.
Blocked forms appear with a grey background in the list.
Forms can also be set to read-only, which is indicated by a padlock icon in the list. (To do this, set the value of the ‘active’ field in the ‘project_forms’ table to 3.)
Form header definition¶
Destination table¶
Select the project table to which data submitted through the upload form will be written.
You can only select SQL tables registered by OpenBioMaps within the project, which contain the basic OpenBioMaps fields such as obm_id, obm_uploading_id, etc. The selected table cannot be changed afterwards, as the form fields are linked to the fields in the selected table.
The forms are sensitive to changes in the table structure. For this reason, it is strongly advised not to edit the tables using a tool other than OpenBioMaps, as this will cause the form to lose its link to the fields. In such cases, saving the changes to the form may resolve the inconsistency, but clients will not be able to upload the offline data!
Name of the form¶
Enter a name for the upload form. The name should be unique within the project (as the name is part of the unique identifier of the forms).
A form can be copied by renaming it. In this case, the original form retains its original name; in other words, it is not possible to rename a form, only to create a new one, which affects the operation of offline clients!
The name can be multilingual when a translation key with the str_ prefix
is used. For more information, see Translations.
Form access¶
Define who can view and use the form:
public users;
all logged-in users; or
only specified groups.
If only specified groups is selected, the user and group selection field becomes active, allowing access to be granted to selected users or groups.
Data access¶
Data uploaded through the form will be available only to the groups specified here. By default, the uploader can read and edit the uploaded data.
Form type¶
At least one of the following form types must be selected:
web form;
file-upload form; or
API form, for access by external clients such as the mobile application.
Form description¶
Enter a short or detailed description of the form. The description can provide instructions to contributors.
Form SRID¶
Select the spatial reference system used by data submitted through the form. Spatial reference systems can be looked up at https://spatialreference.org/. The default is EPSG:4326 (WGS 84).
If a list of spatial reference systems is specified, uploaders can select only from the listed options. Define the list as comma-separated EPSG identifiers and visible labels, using the following format:
4326:wgs84,23700:eov
Form grouping¶
Forms can be organised into groups in the web form-selection interface. Group names can be defined or selected here.
This option is not currently available in the mobile application.
Form publication¶
A form can be locked by publishing it with the orange publish button in the form-header area. Updating a published form creates a new version. Previous versions remain available to API clients such as the mobile application.
A draft can be created from a published form for testing by using the Create a draft version button at the bottom of the page. By default, the draft is available only to its creator. The draft can subsequently be published to the form’s published branch.
Observation event settings¶
For an explanation of observation events and the difference between occasional and event-based observations, see Observation events and occasional observations.
A time limit, expressed in minutes, can be set for an observation event. When the limit is reached, the mobile application alerts the user that the time has expired. The alert does not end the event, and the user can continue recording observations.
A forced observation event means that the form can be launched only in event mode. If observation-event support is enabled but not forced, the user can choose between event mode and occasional-observation mode.
Tracklog¶
This option enables automatic route-log recording while the form is being used. Tracklog recording can be mandatory or optional and is available only in event mode.
Periodic notification¶
At the specified interval, in minutes, the application reminds the observer to record a new observation. The timer runs continuously and restarts whenever the user records an observation.
Form column definitions¶
The column-definition section specifies which destination-table columns appear on the form and how submitted values are displayed and validated.
Included¶
If selected, the column appears on the form.
Column order¶
The small input field next to the Included option defines the order of the column on the form. It is empty by default.
Column¶
Two names are displayed: the visible name of the column, which can be edited for the form, and the original database-column name.
Obligatory¶
Three options are available: yes, no, and soft error.
Yes(burgundy)The form cannot be submitted without a value in this column.
No(grey)The form can be submitted with an empty value in this column.
Soft error(pink)Empty values or values that do not satisfy a restriction can be submitted, but the uploader must confirm every affected row.
Column description¶
Enter a short description of the field.
Column type¶
The following form column types are available:
textArbitrary text. Minimum and maximum lengths can be specified.
numericA numeric value. Minimum and maximum values or lengths can be specified.
listA drop-down list with one selectable item by default.
true-falseA Boolean false/true value. The order of the values can be controlled in the list-definition field, for example
false, true.dateA date with the year, month, and day separated by an accepted character. It is stored using a database date type.
date and timeA date followed by a space and a time in
hour:minute:secondformat. If seconds are omitted, the application automatically treats them as00and asks the uploader to accept the change. If minutes are omitted, the application treats them as00and also asks for confirmation. The value is stored using a database date-time type.time (timetominutes)A value in
hours:minutesformat that the application converts to an integer. It is stored using a database integer type.timeA value in
hours:minutesformat that is stored using a database time type.time interval (timeinterval)A time interval, for example
2014-02-25 12:00:00 2014-02-25 13:00:00. It is stored using a database time-interval type.autocompleteGenerates autocomplete suggestions from the SQL table column specified in the list-definition field. The documented shorthand syntax is
table_name.column. By default, the table is searched for in thepublicschema of thegisdatadatabase.autocompletelistSimilar to
autocomplete, but allows multiple autocomplete values to be entered in one field.photo idIf the photo module is enabled, the application stores uploaded photo identifiers in this field.
geometry: pointA point geometry represented as WKT
POINT(...).geometry: lineA line geometry represented as WKT
LINESTRING(...).geometry: polygonA polygon geometry represented as WKT
POLYGON(...).geometry: anyA geometry represented in WKT using a supported geometry type. See an example form.
colour ringsAllows a colour-ring combination to be specified. The section in square brackets defines the maximum number of rings that can be specified for the different leg sections. It is followed by the individual codes and labels of the available colours, for example
[XX],Blue:B,red:R,green:G.The documented colour codes are:
R— red;P— pink;G— green;g— light green;O— orange;Y— yellow;B— blue;b— light blue;W— white;K— black;N— brown;U— purple;V— violet; andM— silver.
Input control¶
Input controls check values entered into the field. The available options are:
no check;
minimum and maximum;
regular expression;
spatial; and
custom check.
List definition¶
To use a list during data submission, set the column type to list,
autocomplete, or autocompletelist.
List definitions can describe simple or multiple-choice lists, autocomplete sources, values obtained from other database tables, and rules for filtering those values.
A short list can be defined directly. In the following example, uploaders
can select female or male from a drop-down list. The selected value
is stored in the database.
{
"list": {
"female": [],
"male": []
}
}
Several input labels can be mapped to the same stored value. For example,
F, f, and female can all be interpreted as the stored value
female. This is particularly useful during file upload when data from
different contributors or years use different labels for the same concept.
{
"list": {
"female": [
"F",
"f",
"female"
],
"male": [
"M",
"m",
"male"
]
}
}
A list can also be entered in plain-text format, with one value on each line. When the form is saved, the application converts the plain-text list to JSON. The resulting JSON can then be edited directly.
List values can also come from an SQL table. Specify the schema
(optionsSchema), table (optionsTable), stored-value column
(valueColumn), and, where required, visible-label column
(labelColumn).
Values can be filtered using preFilterColumn and preFilterValue.
The following example applies prefilters:
{
"optionsTable": "milvus_taxon",
"valueColumn": "word",
"preFilterColumn": [
"lang",
"status"
],
"preFilterValue": [
"obm_taxon",
[
"accepted",
"undefined"
]
],
"orderBy": "taxon_db",
"order": "desc"
}
The complete list definition uses JSON. It can be assembled with the list editor in the web interface and is checked for valid syntax by the application. If the syntax is invalid, the application returns an error message.
The following example lists the documented properties:
{
"list": {
"val1": [
"label1",
"label2"
]
},
"optionsSchema": "e.g. public",
"optionsTable": "a table name",
"valueColumn": "a column from the table",
"labelColumn": "a column from the table - optional",
"filterColumn": "",
"pictures": {
"an element from the list, e.g. val1": "url-string"
},
"triggerTargetColumn": [
""
],
"Function": "",
"disabled": [
"an element from the list, e.g. val1"
],
"preFilterColumn": [
""
],
"preFilterValue": [
""
],
"preFilterRelation": [
""
],
"multiselect": "true or false, default is false",
"selected": [
"an element from the list, e.g. val1"
],
"size": "a numeric value",
"orderBy": [
"column or SQL expression"
],
"order": [
"ASC or DESC"
],
"limit": "numeric value"
}
Joint lists¶
A joint list uses the value selected in one column, called the starter column, to determine the available values in another column. This creates a dependent or cascading list.
First, create a lookup table containing the relationships between the list
levels. For example, an animal_taxons table could describe which animal
groups belong to each supergroup. Vertebrates could contain amphibians,
reptiles, birds, and mammals, while invertebrates could contain cnidarians
and insects.
In the list definition of the starter column, specify the target column:
{
"triggerTargetColumn": [
"affected_list_name"
],
"Function": "select_list",
"optionsSchema": "shared",
"optionsTable": "animal_taxons",
"valueColumn": "animal_group_name",
"labelColumn": "animal_group_name",
"labelAsValue": true
}
The properties used in this example are:
FunctionUses the documented value
select_list.optionsSchemaIdentifies the schema containing the lookup table. This example uses
shared.optionsTableIdentifies the lookup table.
valueColumnIdentifies the column providing the values for the starter list.
labelColumnIdentifies the column providing the visible labels.
triggerTargetColumnIdentifies the form column whose list must be updated.
In the affected column, define which lookup-table column provides its values and which column is used to filter them:
{
"optionsTable": "animal_taxons",
"valueColumn": "animal_group_name",
"labelColumn": "animal_group_name",
"filterColumn": "animal_supergroup",
"Function": "select_list",
"optionsSchema": "shared"
}
Here, filterColumn identifies the lookup-table column that is matched
against the value selected in the preceding form column.
Joint lists can connect more than two form columns:
{
"optionsSchema": "shared",
"optionsTable": "animal_taxons",
"filterColumn": "animal_supergroup",
"Function": "select_list",
"valueColumn": "animal_group_name",
"triggerTargetColumn": [
"species"
],
"labelColumn": "animal_group_name"
}
In a chain of joint lists, triggerTargetColumn identifies the next form
column, filterColumn identifies the lookup-table column used to match
the preceding selection, and valueColumn and labelColumn define the
current list.
Joint-list example: buildings within a settlement¶
Suppose a project collects data about species breeding in artificial nest
boxes. A lookup table named tytoalba_buildings records which buildings
occur in each settlement. The settlement field should provide an
autocomplete list, and the building field should show only buildings in the
selected settlement.
First, configure the settlement column as an autocomplete field and identify the building column as its target:
{
"triggerTargetColumn": [
"building"
],
"Function": "select_list",
"optionsSchema": "public",
"optionsTable": "tytoalba_buildings",
"valueColumn": "settlement"
}
Next, configure the building column as a list and filter its values using the selected settlement:
{
"optionsTable": "tytoalba_buildings",
"filterColumn": "settlement",
"Function": "select_list",
"valueColumn": "building"
}
Default values¶
A predefined value can be assigned to a field. The documented dynamic default values are:
_autocomplete;_input;_list;_geometry;_login_name;_email;_boolean;_attacment;_datum; and_auto_geometry.
For example, _input produces an empty input field, _list fills a
selection list using the list definition, _geometry provides geometry
selection, and _datum provides date selection.
See an example form.
Field display options¶
The following display options are documented:
stickyPrimarily used by the mobile application. When selected, the field retains its value when a new row is started.
hiddenThe field is not displayed.
read onlyThe field value cannot be modified.
onceIn the mobile application, the field is displayed only once for an observation list, at the end of the observation.
This option is intended to allow a field to be moved outside the repeating table in the web form. Currently, a similar result can be achieved in the web form by using a default value.
list elements as buttonsDisplays list elements as buttons. Images can be used on the buttons. Images should be defined for all list elements in the list definition.
unfolding listProvides a species-list workflow for the mobile application. This option can be used only with an autocomplete field, typically a scientific-name field, when the form also contains a number-of-individuals field assigned the corresponding semantic role in the database-table settings.
The mobile application displays the selected species names and their individual counts in a list. Counts can be modified without saving a separate record after every change. The option is therefore most useful in an observation-event form, where Save observation acts as an intermediate save and does not clear the accumulated species list.
The following list definition associates images with example button values:
{
"pictures": {
"animals": "http://....png",
"plants": "http://....png",
"mushrooms": "http://....png",
"bats": "http://....png"
}
}
Column relations¶
Column relations check or modify the value of one field according to the
value of another field. For example, a weight field can be restricted to a
numeric range of 20 to 30 when the sex field contains female:
(sex=female) {minmax(20:30)}
See an example form.
Pseudo-columns¶
Columns from other upload forms can be added using the following format:
form-name:column1,column2,columnN
The listed columns appear after the column containing this definition. Values entered in the pseudo-columns are uploaded using the other form’s definition. This allows data to be submitted to two tables in one workflow.
The relations language definition¶
The documented general syntax of the relations language is:
(rel_field=rel_statement) {rel_type(rel_value)}, (rel_field=rel_statement) {rel_type(rel_value)}, ...
The intended interpretation is:
IF another field (rel_field) matches rel_statement,
THEN apply rel_type with rel_value to the current field.
rel_type is a function associated with the current field type. The
documented functions are:
yearFor date fields, extracts the year component from a date string.
minmaxFor text or numeric fields, performs a minimum and maximum range check.
obligatoryFor any field type, changes whether the current field is obligatory.
inequalityFor any field type, compares the related field and the current field using a supported comparison operator. A failed comparison produces a validation error.
A regular-expression statement begins with !! followed by a regular
expression, for example:
!!^(\d{2})$
When rel_statement is a regular expression, rel_value can use a
replacement function based on the matched value:
.Replaces the current field value with the string matched in
rel_field..+Appends the current field value to the string matched in
rel_field.+.Appends the string matched in
rel_fieldto the current field value.
For an inequality relation, the documented expressions use + for the
matched value of rel_field and . for the current field value:
+<.
+<=.
+>=.
+=.
+<>.
For other relation types, rel_value can contain another value or may be
ignored, depending on the function.
Relation examples¶
Making a field obligatory¶
On the tarsus_length column:
(clutch_size=!!^([123])$) {obligatory(1)}
This makes tarsus_length obligatory when clutch_size is 1,
2, or 3.
Comparing two dates¶
On the end_date column:
(found_date=!!^(.+)$) {inequality(+>=.)}
If found_date is not empty, the relation checks whether end_date is
greater than or equal to found_date. A false result produces an upload
error.
Adding a year to a date¶
On a date field that does not contain a year:
(year=!!^(d{4})$) {set(.)}
If the year column is not empty and contains four digits, the date field
is updated with that year.
Requiring a ring number¶
On the ring_number field:
(recapture=1) {obligatory(1)}
If recapture has the value 1, ring_number becomes obligatory.
Requiring an alternative name¶
On the english_name column:
(scientific_name=!!(^$)) {obligatory(1)}
If scientific_name is empty, english_name becomes obligatory.
Setting a value according to a count¶
On the amount_type field:
(number_of_individuals>50) {set(estimated value)},(egyedszam<=50) {set(exact value)}
If the number of individuals is greater than 50, amount_type is set to
estimated value. If it is 50 or less, amount_type is set to
exact value.