Form Language
- Modified
- Language
- English
- License
- CC BY-SA 4.0
- Document Status
- Draft
Note: There was an issue with Dokieli where URLs within pre tags are interpreted not simply rendered, hence the missing <...> around URLs in the code samples. It has been fixed in Dokieli, so just waiting for inclusion in Data Browser before we can fix the document.
Introduction
As described in Linked
Data Shapes, Forms and Footprints, “Form
Languages are used to define user interfaces for
reading and writing Linked Data with a specific
shape.” Based on the User
Interface ontology, Form Language defines how
data should be presented as a form, and provides a
direct relationship between the form fields and the
shape elements.
This document provides guidance on how to write a
Form Model, in Form Language, to define the layout
and user interface (UI) elements rendered in a form.
References
- The UI ontology (source file)
- The implementation code. Implementation of a Form Model renderer in JavaScript.
Form Models
Form Models are defined as a turtle (.ttl) files. It is assumed the reader of this document is familiar with Turtle. A primer discussing Turtle can be found here.
A Form Model uses a simple structure with:
- List of Prefixes used within the Form Model.
- Form node, defining the form name and (an ordered) list of form parts.
- An ordered list of single fields, repeated fields, or grouped fields to be displayed on the form.
By way of illustration, an example Form Model is shown below which allows viewing and editing of a contact’s name and photo:
@prefix shape: <contact-shapes.ttl#>. @prefix ui: <http://www.w3.org/ns/ui#>. :personForm a ui:Form; ui:parts (:nameField :photoField). :nameField a ui:SingleLineTextField; ui:label "Name"; ui:arc shape:Individual_fn; ui:size 20. :photoField a ui:ImageField; # @@ correct name? ui:arc shape:Individual_hasPhoto.The example references 2 prefixes (
shape:
and ui:
), and would render a form (:personForm
)
that has 2 parts (:nameField
and :photoField
).Prefixes
The Prefixes are namespace declarations, providing the association of a prefix used in the document with a URI; one line per prefix.
For example, the following code snippet references the UI Ontology and the RDF syntax in the Form Model.
@prefix ui: http:www.w3.org/ns/ui# . @prefix rdf: http:www.w3.org/22-rdf-syntax-ns# .
Form
The ui:Form
node defines the name,
groups and fields of the form:
Property | Type | Description | Example |
---|---|---|---|
parts | rdf:Collection (ordered array) of Groups & Fields | The parts of the form in the order in which they are displayed. | |
part | Field (Obsolete) | A field which is a part of the form or group. This property is obsolete. Use parts. |
ui:part
method
for listing the parts of a form, then each field needs
an additional property:
Property | Type | Description | Example |
---|---|---|---|
sequence | Integer (Obsolete) |
The parts of the form in the order in which they are laid out. | |
sequence | Integer (Obsolete) |
The parts of the form in the order in which they are laid out. |
ui:part
, declare its type, and
the extra data that type requires.In the example below, the
:personForm
namedNode is defined as a ui:Form
type,
which contains two parts: the :nameField
and the :photoField
. :personForm a ui:Form; ui:parts (:nameField :photoField) .Due to the
:
prefix, these are expected
to be namedNodes inside the same file. They can be
named anything, as long as they are linked here.Fields
Parts
The form ui:parts
defines the layout
of the controls (e.g., text boxes, checkboxes,
dropdowns, etc.) that are displayed on the form.The
ui:parts
can be:
- Fields. Single instance of a control. Fields will be discussed in detail below.
- Group. A collection of parts treated as a single block of controls.
- Multiple. Repeated instances of the same field.
They may be named nodes in your file, or blank nodes - the form system does not mind. However, it is often useful to name them to keep track of them.
Group
Aui:Group
is a field which is just a
collection of other fields. It is in fact
interchangeable with ui:Form
.
:Address a ui:Group ; ui:parts (:street :locality :region :postalcode ) ;This
:Address
node is a group of parts,
the same way a Form is a set of parts. In this case,
the :Address
node could be used in
another Form type, and it would pull in all of these
parts into a subform inside of the main form. You can
include groups inside of other groups.
Multiple
When the subject can have several of the same
thing (e.g., friends, phone numbers, etc.), then
the ui:Multiple
field can be used.
For each new thing, the system should generate an
arbitrary (timestamp) URI within the file where
the data is being stored. The subform is then
about that thing: the subject of the subform is
not the subject of the original form. It is the
friend, or the address, and so on.
:Addresses a ui:Multiple ; elem:title "Address Details" ; ui:part :Address .
This example shows an :Addresses
part defined as a ui:Multiple
, which
indicates to the UI that it is repeatable. This
particular node has a title and the single part:
an Address. In the parent form, :Addresses
would be included in the ui:parts
predicate.
Fields
Common Field Properties
Some field properties can be used with any field (except the Documentations fields).
Unless explicitly specified, all field classes and properties are in the UI namespace except the data types like Integer which are in the XSD namespace.
Property | Type | Description | Example |
---|---|---|---|
arc | IRI | Link to an external shape definition. | ui:arc shape:Individual_fn; |
autofocus | Boolean | Indicate that the form element should receive input focus as soon as the form is loaded, so that you can start typing immediately without having to specifically click on or tab to that control. Default is false. | ui:autofocus "1"; |
backgroundColor | RGB Hex String | Background color of the part. | ui:backgroundColor "#00000"; |
backgroundImage | IRI or base64 | Background image. | |
?:className | String | Name of a CSS class to apply to the element | ?:className "inrupt-form" ; |
color | RGB Hex String | Foreground color of the part. | ui:color "#EE00EE" ; |
default | [according to field type] Optional | The input control is by default set to this value. It is easiest for the user to enter this value. (This value is not stored by the forms system automatically if the user does not select or enter it in some way. | |
dependingOn | rdf:Property | Link to a part that the current part depends upon. | |
label | String | A label for the form field. | ui:label “Address: ”@en; |
multiple | Type | Assigned to a part to indicate it can be repeated. | |
prompt | String | Additional text to display to the user (e.g., mouseover or tooltip text, or placeholder). | ui:prompt “Enter your mailing address”@en; |
property | rdf:Property | When the user enters the data, it is stored in the web as a triple with this property as its predicate. | |
required | Boolean | Is the field required? Default is false. | ui:required "1"; |
requiredError |
- |
Define the error to be displayed if a user
does not enter data into a required field. |
ui:requiredError [ rdfs:label :"Name
is required"@en]; |
readonly | Boolean | Is the field editable? Default is false. | ?:readonly "1"; |
sequence |
Number |
(Deprecated) Used to define the order of the fields. This can now be done more simply using ui:parts Lists | |
sortBy | Class | ||
sortPriority | Integer | Sort order for a set of values. | |
style | String |
Valid CSS style string such as one could put in an HTML style attribute. Depending on the user interface system, this can by given to individuals, classes or properties. It is up to a user interface which wants to draw on them to pick how it uses styles from which parts of the data it has. |
|
validationError | - |
Define the error to be displayed if a user enters invalid data. |
ui:validationError [ rdfs:label :"Age has
to 18+"@en]; |
Logical Fields
These prompt the user to select either a 2-state (true/false) or 3-state (true/false/unknown) value:- 2-state (BooleanField).
- 3-state (TriStateField).
BooleanField
A 2-state checkbox on the form, stores an RDF boolean true or false value.:poweruserField a ui:BooleanField; ui:label “Are you a Power User?”@en ; ui:default "0" ; ui:property solid:poweruser.
TriStateField
A 3-state checkbox on the form, stores a tri-state value - true, false, or no value (i.e., unknown) if the box is left in its third, blank state.:accepttermsField a ui:TriStateField; ui:label “Do you accept the Terms and Conditions?”@en ; ui:property <...>.
Numeric Fields
These fields prompt the user for a single numeric value:- Monetary (DecimalField).
- Floating-point number (FloatField).
- Integer (IntegerField).
These numeric fields share a common set of properties.
Property | Type | Description | Example |
---|---|---|---|
maxValue | Same as field type | Maximum value for the field.
If no maximum value is provided,
the maximum is set to the maximum
value for the field type. |
ui:maxValue "3.142" ; |
minValue | Same as field type | Minimum value for the field. If no minimum value is provided, the minimum is set to the minimum value for the field type. | ui:minValue "-3.142" ; |
DecimalField
An RDF decimal value. This is useful for monetary amounts.
:itemCost a ui:DecimalField ui:label "Cost?" ; ui:minValue "10.99" ; ui:maxValue "9999" ; ui:property <...> .
FloatField
Enter a floating point number.
:distanceField a ui:FloatField
ui:label "Distance (km): " ;
ui:minValue "-173.45" ;
ui:property https:open.vocab.org/terms#kilometers .
IntegerField
Enter an RDF integer value. Depending upon the valid integer range and rendering device, integer could be selected using an integer selector.
:ageInYears a ui:IntegerField ui:label "Age in years" ; ui:minValue "0" ; ui:maxValue "125" ; ui:property <...> .
Date and Time Fields
For many forms, a user will need to temporal values:
- Date (DateField).
- Time (TimeField).
- Combined Date and Time (DateTimeField).
DateField
Select/enter a date, preferably via a Date picker.
This field uses specific properties.
Property | Type | Description | Example |
---|---|---|---|
maxValue | date | Maximum valid date. | ui:maxValue "2019-01-01"; |
maxdateOffset |
Integer |
Offset (in days) from today
of the maximum valid date. |
ui:maxdateOffset "365"; |
minValue | date | Minimum valid date. | ui:minValue "2019-12-31" ; |
mindateOffset | Integer | Offset (in days) from today of the minimum valid date. | ui:mindateOffset "-7"; |
Note: If both a hardcoded and an offset
date are provided (e.g., ui:maxValue
and ui:maxdateOffset
), the
hardcoded date takes precedence.
Generates an RDF date literal as is value.
:bodFrom a ui:DateField ; ui:label "Date of Birth: "@en ; ui:minValue "1900-01-01" ; ui:maxdateOffset "0" ; ui:property person:birthDate .
DateTimeField
Select/enter a date and time combination, preferably via a DateTime picker.
This field uses specific properties.
Property | Type | Description | Example |
---|---|---|---|
maxValue | dateTime | Maximum valid datetime. | ui:maxValue "2011-12-31 17:00:00"; |
maxdatetimeOffset | Integer | Offset (in seconds) from now of the maximum valid datetime. | ui:maxdatetimeOffset "129600"; |
minValue | dateTime | Minimum valid datetime. |
ui:minValue "2011-01-01
08:30:00"; |
mindatetimeOffset | Integer | Offset (in seconds) from now of the minimum valid datetime. | ui:maxdatetime "-43200"; |
Note: If both a hardcoded and an offset
datetime are provided (e.g., ui:maxValue
and ui:maxdatetimeOffset
),
the hardcoded datetime takes precedence.
Leaves an RDF datetime literal as is value.
:departureDateTime a ui:DateTimeField ; ui:label "Departure: "@en ; ui:mindatetimeOffset "0" ; ui:maxdatetimeOffset "31536000" ; ui:property https:open.vocab.org/terms#departuredate .
TimeField
Allows the user to select/enter a time, preferably via a Time picker.
This field uses specific properties.Property | Type | Description | Example |
---|---|---|---|
maxValue | time | Maximum valid time. If not
set, maxValue assumed to be
"23:59:59". |
ui:maxValue "17:00:00" ; |
minValue | time | Minimum valid time. If not set, minValue assumed to be "00:00:00". | ui:minValue "08:30:00" ; |
Leaves an RDF time literal as is value.
:trainArrivalTime a ui:TimeField ; ui:label "Arrival Time: "@en ; ui:minValue "06:00:00" ; ui:maxValue "21:59:59" ; ui:property TrainTrip:arrivalTime .
Text Fields
A major function of a form is to allow
entry of pieces of text. This is done
through use of subclasses of the ui:TextField
class that allow entry of strings:
- Email (EmailField)
- Phone (PhoneField)
- Text Area (MultiLineTextField)
- Text Box (SingleLineTextField)
These text field parts share a common set of predicates.
Property | Type | Description | Example |
---|---|---|---|
maxlength | Integer | Maximum character width of the Text Box. | ui:maxlength "256"; |
pattern | String | Regex pattern to apply to the field. | ui:pattern "^\+?[0-9]+[0-9-]*[0-9]$"; |
size | Integer | Visible character width of the Text Box. | ui:size "40"; |
EmailField
Allows entry of a valid email address.
Generates a named node with a uri which starts 'mailto:'.
:emailAddress a ui:EmailField ;
ui:label "Email"@en ;
ui:pattern "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$" ;
ui:maxLength "128" ;
ui:size "40" ;
ui:property vcard:email .
PhoneField
Allows entry of a valid telephone number.
Generates a named node with a uri which starts 'tel:'.
:phoneNumber a ui:PhoneField ;
ui:label "Phone Number"@en ;
ui:pattern "^\+?[0-9]+[0-9-]*[0-9]$" ;
ui:property vcard:phone .
SingleLineTextField
Allows entry of a single line of text.
:fullNameField a ui:SingleLineTextField ;ui:label "Full Name: "@en ;ui:maxLength "255" ;ui:size "100" ;
ui:required "1" ;
ui:requiredError "Please enter your full name"@en ;
ui:prompt "Enter Full Name"@en ;
ui:property vcard:fn .
MultiLineTextField
Allow entry of a large, potentially multiple line, block of text.
:comments a ui:MultiLineTextField ;ui:label "Comments/Questions?"@en ;ui:required "0" ;ui:maxLength "10000" ;ui:property vcard:note .
Other Simple Fields
ColorField
Select/enter a color, preferably via a Color picker. Generates a string which is a CSS-compatible color like #ffeebb.
:backgroundColor a ui:ColorField ; ui:label "Background Color:"@en ; ui:property solid:backgroundcolor .
Complex Fields
Choice
The user choses an item from a class.
Choice has some unique optional properties:
Property | Type | Description | Example |
---|---|---|---|
from | rdfs:Class | The selected thing must be a member of this class (e.g., Person). | ui:from vcard:Type; |
property | rdf:Property | When the item is found, the new data links it from the subject with this property (e.g., friend). | |
canMintNew | xsd:Boolean | If the user doesn't find the thing they want, can they introduce a item of that class by filling in a form about it? (e.g. add a new option to a dropdown, like adding a new tab via a Combobox) | ui:canMintNew "0"; |
Classifier
In many situations, a user will need to select one (or more) values from a pre-defined list of choices. These Classifier fields can be rendered in a several different types of control:
- List (single- or multi-select).
- Dropdown/combobox.
- Radio buttons.
Classifier has some unique optional properties:
Property | Type | Description | Example |
---|---|---|---|
category | rdfs:Class | The superclass to define the values from. The user will select subclasses of this class. | |
property | rdf:Property | When the item is found, the new data links it from the subject with this property (e.g., friend). | |
canMintNew | xsd:Boolean | If the user doesn't find the thing they want, can they introduce a item of that class by filling in a form about it? (e.g. add a new option to a dropdown, like adding a new tab via a Combobox) | ui:canMintNew "0"; |
type | String | Guidance on how the Classifier should be rendered in the form. For example, "List", "Dropdown", "Radio buttons". | |
?:values | Collection | A collection of strings to represent non-class based values |
There are three ways to define the values for a Choice field:
- Based on a Class subtype.
- Hardcoded.
- Value-Label pairs.
Class Subtype
The first way is using a class to define the Choice values.<#telephoneType> a ui:Classifier ;ui:canMintNew "0" ;ui:category <http://www.w3.org/2006/vcard/ns#Type> ;ui:from <http://www.w3.org/2006/vcard/ns#Type> ;ui:property <http://purl.org/dc/terms/type> .
In this example, a new Classifier type defines the "type" of a Phone Number. The displayed values are automatically compiled from the vcard:Type
subclass.
This version of the Classifier leverages the ontology heavily. It pulls the subclasses of the given class, and if and only if the ontology says that the class is a disjoint union (owl:disjointUnionOf
) of the subclasses, then the user interface should only allow the user to pick one. If the user picks a subclass, and the ontology shows that that subclass has its own subclasses, then the user should be prompted to pick one of those, to (if they like) further refine the selection. And so on.
Hardcoded Ordered List
Another way to define the Choice values is to define them yourself::greekletterField a ui:Classifier ; ui:canMintNew "0" ; ?:values ("Alpha" "Beta" "Delta") ; ui:property <...> .
Value-Label Pairs
{Need to explain how this could be done}Options
The ui:Options
field is the 'case statement' of the form system. It will
chose at runtime a subfield depending on a property, often the type, of
the subject. It is often used after a ui:Classifier
.
Options property | range | significance | Example |
---|---|---|---|
dependingOn | rdf:Property | The predicate in the data used to select the case. | |
case | Case | A case object, with for x use y. (2 or more cases) |
ui:case
:
Case property | range | significance | Example |
---|---|---|---|
for | [The range of the dependingOn property] | The value this case applies to. | |
use | Field | Sub form to be used in case the value matches the "for". |
Documentation Fields
The Documentation fields allow additional text to be displayed in the rendered form to both delineate the form and provide the user with guidance on use of the form.
Heading
Help the user find parts of a long form, or just for a title of a short form.
Property | Type | Description | Example |
---|---|---|---|
contents | String | The text content of the heading. |
:educationHeading a ui:Heading ;
ui:contents "Education"@en .
Comment
Use comments in the form to help users understand what is going on, what their options are, and what the fields mean.
Property | Type | Description | Example |
---|---|---|---|
contents | String | The text content of the comment. (This should be displayed by form systems as pre-wrap mode). |
:educationDescription a ui:Comment ;
ui:contents "Define your educational history"@en .
Conclusion
Not all possibilities can be defined using the Form Language, and rendered via one of the implementations, but it can handle a pretty wide selection of tasks in common daily life at home and at work. It can be very efficient as developers can reuse material between forms. Users can even generate their own forms.