HTML-based displays¶
The following elements use HTML
for showing content. That’s all there is to them! If you are new to lab.js
, these are the easiest way to get things in front of your participants.
Contents
Screen¶
The html.Screen()
is a component of the experiment that changes the content of an element on the page when it is run. Otherwise, it behaves exactly as a core.Component()
does.
-
class
html.
Screen
([options])¶ When an
html.Screen()
is constructed, it takes a single argument that specifies the component options. The most important of these is thecontent
, which is the string of text andHTML
inserted into the document. Additional options correspond to those of acore.Component()
.For example, a screen showing a simple text could be constructing as follows:
const screen = new lab.html.Screen({ content: '<p>Hello world!</p>', }) screen.run()
When this code is run, the screen content is shown, that is, the content string supplied is inserted into the page. Per default, the element with the attribute
data-labjs-section="main"
is used as an insertion point, however this may be changed usingel
option.Using placeholders
You can access the
parameters
available through thehtml.Screen()
to insert placeholders within itscontent
. These are filled when the screen isprepared
. Through this mechanism, the exact content of a screen need not be specified fully from the onset of the study, but can be assembled dynamically depending on the structure of the experiment, and participants’ behavior.Placeholders are delimited by
${
and}
. A parameter name can be placed within these limits in the formatparameters.parameter_name
, and the content stored in place of the parameter will replace the placeholder as soon as the screen is prepared. Similarly, the last value in every column of the data set can be accessed viastate.column_name
. For example, you might want to use the veracity of the last response to provide feedback viastate.correct
.The following screen would produce an output equivalent to the example above, using parameters:
const parameterScreen = new lab.html.Screen({ content: '<p>Hello ${ parameters.place }!</p>', parameters: { place: 'World' }, })
Placeholders can contain any JavaScript expression, so basic logic can be inserted directly into a placeholder. For example, you might use the boolean value contained in
state.correct
to provide feedback, using a conditional operator:const feedbackScreen = new lab.html.Screen({ content: '<p>${ state.correct ? "Well done!" : "Please have another go!" }</p>', })
Note
The placeholder syntax is deliberately chosen to be equivalent to JavaScript’s template literals. You might therefore be tempted to place the content options containing placeholders in backticks (
`
) instead of quotation marks ('
or"
). Doing so will introduce a subtle difference: The option you’re setting will no longer be a regular string, and your browser’s JavaScript engine will attempt to compute the content in placeholders and insert the result in their place as soon as it encounters them. Because the template literal mechanism prempts and bypasses the placeholders, they won’t perform their regular function.In sum: If your placeholders aren’t doing what they are supposed to, this might be worth checking.
Options
The options available for an
html.Screen()
are identical to those of thecore.Component
. For example, one might captureresponses
as in the following example:const screen = new lab.html.Screen({ content: '<p>Please press <kbd>s</kbd> or <kbd>l</kbd></p>', responses: { 'keypress(s)': 's', 'keypress(l)': 'l' }, }) screen.run()
Similarly, the screen might be shown only for a specified amount of time (in milliseconds):
const timedScreen = new lab.html.Screen({ content: '<p>Please press space, fast!</p>', timeout: 500, // 500ms timeout responses: { 'keypress(Space)': 'response' }, })
See also
If you are looking for very short or more precise timings, you will probably be better served using canvas-based displays such as the
canvas.Screen()
.Screens provide two new options that can be specified:
-
html.Screen.options.
content
¶ HTML
content to insert into the page, as text.
-
html.Screen.options.
contentUrl
¶ URL
from which to loadHTML
content as text. The content is loaded when the screen is prepared. Replaces the screen’scontent
.
-
Form¶
A html.Form()
is like the html.Screen()
described above, in that it uses HTML
to display information. However, it adds support for HTML
forms. This means that it will automatically react to form submission, and save form contents when it ends.
On a purely superficial level, a html.Form()
is handled, and behaves, almost exactly like an html.Screen()
: The content
option contains an HTML string which is rendered onscreen when the screen is shown. This is because a html.Form()
builds upon, and extends, the html.Screen()
. It merely handles HTML
form tags somewhat more intelligently.
HTML forms¶
HTML
forms make possible inputs of many kinds, ranging from free-form text entry, to checkboxes, to multiple-choice items and response buttons. This allows for a great variety of data collection methods, ranging far beyond the responses discussed so far.
As with the html.Screen()
discussed above, we assume some familiarity with HTML
forms in the following. If you would like to become familiar or reacquaint yourself with them, we have found the following resources helpful:
Form handling¶
Within HTML
forms, each field is represented by one or more HTML
tags. The name
attribute of these tags typically contains the variable in which the fields information is stored and transmitted.
For example, a very simple form containing only an input field for the participant id, and a button for submitting the form, might be represented as follows:
<form>
<input type="number" name="participant-id" id="participant-id">
<button type="submit">Save</button>
</form>
By inserting this snippet into an HTML
document, an input field is added which accepts numeric input, and also offers buttons to increment and decrease the contained value. In addition, the form can be submitted using a button. Please note that the input field is named, which means that any input present in the form field when the form is submitted will be represented by the key given in the name
attribute, in this case participant-id
(though it is common to reuse the value of the name
attribute as the element’s id
attribute, the two are unrelated and can be chosen independently).
By combining the above code with an html.Form()
, it can become part of an experiment:
const screen = new lab.html.Form({
content: '<form>' +
' <input type="number" name="participant-id" id="participant-id">' +
' <button type="submit">Save</button>' +
'</form>'
})
The above screen, inserted into an experiment, will display the form, and wait for the user to submit it using the supplied button. When this occurs, the form contents will automatically be transferred into the experiment’s data set, and whichever value was entered into the specified field will be saved into the variable participant-id
.
Caution
The html.Form()
differs from standard HTML
forms (those that are sent to a server, which responds with a new page) in one important point: It does not save information about the <button>
used to submit the <form>
data. This is because the information is not made available within the page itself.
If you are looking to capture a response to one of several buttons, we recommend using an html.Screen()
instead, and defining a distinct response
for clicks on every button.
-
class
html.
Form
([options])¶ An
html.Form()
accepts the same options and provides the same methods thehtml.Screen()
does, with a few additions:See also
A
html.Form()
is derived from thehtml.Screen()
, and therefore also accepts thecontent
andcontentUrl
options.-
html.Form.
serialize
()¶ Read the current form state from the page, and output it as a javascript object in which the keys correspond to the
name
attributes on the form fields, and the values correspond to their current states.
-
html.Form.
validate
()¶ serialize()
the current form content and check its validity using thevalidator
. Returnstrue
orfalse
.
-
html.Form.options.
validator
¶ Function that accepts the serialized form input provided by the
serialize()
method, and indicates whether it is valid or not by returningtrue
orfalse
depending on its decision. Only if it returnstrue
will thehtml.Form()
end following submission of the form content.The function is also responsible for generating an error message and showing it to the user, if this is desired.
The
validator
option defaults to a function that always returnstrue
, regardless of form content.
-
Frame¶
The html.Frame()
inserts pre-defined HTML
content into the page like a html.Screen()
does, but then runs
a nested component
within this new context, passing on control over a subsection of the screen. It thereby provides a ‘frame’ around the content of a subordinate component
.
-
class
html.
Frame
([options])¶ A
html.Frame()
provides aHTML
surrounding, acontext
, for nested components, itscontent
. This has two main use-cases:- Simplicity: Any content common to all nested components can be moved to the superordinate
frame
and need not be repeated. - Speed: Instead of exchanging the entire screen content, nested components swap out only a small part of the page, reducing the load on the browser and ensuring more consistent performance. A
frame
can also embed canvas-based components so that the most timing-critical parts of the screen, or visually complex and interactive stimuli, can be rendered through the more performant canvas.
A common application is when stimuli make up only a small part of the total screen content:
const stimuli = new lab.flow.Loop({ /* ... */ }) const frame = new lab.html.Frame({ context: ` <header> You have one job to do </header> <main> <!-- this is where stimuli will be inserted --> </main> <footer> You better / push the button / let me know. </footer> `, contextSelector: 'main', content: stimuli, })
-
html.Frame.options.
context
¶ HTML
code in which the nestedcontent
is embedded (required).
- Simplicity: Any content common to all nested components can be moved to the superordinate