Autor des Abschnitts: Jonathon Love
3. Advanced Customisation
3.1. Customizing UI controls
Sometimes the
.u.yaml-file alone doesn’t provide enough flexibility for an analysis options UI. More complex UIs can be achieved through writing additional javascript that provides more complex behaviour. This allows much greater freedom and flexibility, and allows you to design an options UI completely from scratch if necessary.The options UI is customised through attaching javascript ‘event handler’ functions to the user interface. These then respond to events such as a UI ‘loaded’ event, or an option ‘changed’ event in response to a user interaction.
Additional UI functions are defined in a javascript-file with a
.js-suffix, and are placed in thejamovi/jsfolder of the module. The name of the.js-file should match the names of the other.yaml-files for that analysis. For example:The events
.js-files follow theCommonJSjavascript module spec, assigning each of the event handlers and functions to an object which is assigned tomodule.exports.IMPORTANT: For customisations to function, the
jusproperty in the.u.yaml-file needs to be set to3.0.For example:
name: ttest title: T-Test jus: '3.0' compilerMode: tame children: - type: ComboBox name: ttestTypemodule.exports = { // event handlers and functions are defined here // this is an example of an event handler view_loaded: function(ui, event) { // do something }, // this is another example of an event handler ttestType_changed: function(ui, event) { let value = this.calculateValue(); // do something }, // this is an example of an auxiliary function calculateValue: function() { // do something } };In the above example, the
view_loaded(...)event handler is invoked with aloadedevent when the analysis options UI is created for the first time. Similarly, achangedevent is fired, and the event handler functionttestType_changed(...)is invoked when the user changes the value of thettestTypeoption.Note that jamovi ships with the Chrome developer tools, so it’s possible to invoke these, and have access to the debugger, DOM viewer, etc. The dev tools are invoked by pressing
F10. (Note that sometimes jamovi’s internal iframes prevent this key stroke from registering. You sometimes need to click the blue bar along the top to move the focus back to the main window, before theF10keystroke will register.)
3.1.1. Events
Event handlers are added by naming the function with the following pattern. Option name, followed by an underscore, followed by the event name
{optionName}_{eventName}.For example:
ttestType_changedjamovi will automatically attach the event handler
ttestType_changed(...)to thechangedevent of thettestTypeoption when the analysis is run.
3.1.1.1. View
Event
Description
creating
Invoked at the very beginning of the options panel creation, before anything is added to the DOM.
loaded
Invoked after the options panel has been created and the DOM has been populated. The same analysis options panel persists as long as jamovi is still running, and is shared by all analyses of the same type, so this is only invoked once. This is the most common event to use for customising the UI.
updated
Invoked when the user selects a different analysis (of the same type) and the options need to change to reflect the new analysis’ option values (This is also called when the user inserts a new analysis, when an option panel for that analysis type already exists).
3.1.1.2. All controls
Event
Description
changing changed
Invoked before the value of the control is changed. Invoked after the value of the control is changed.
3.1.1.3. ListBox
Event
Description
listItemAdded listItemRemoved
Invoked when a control is added to a list box. Invoked when a control is removed from a list box.
3.1.1.4. Suppliers
Event
Description
updated
Invoked when a variable name or level name is changes.
IMPORTANT NOTE: The use of the
updatedevent is required for allSupplierandVariableSuppliercontrols (under certain conditions). If it is not implemented then jamovi will display the following error:Error: The use of a ‘VariableSupplier’ control, with the property > populate: ‘manual’, requires an ‘updated’ event handler to be assigned.or:
Error: The use of a ‘Supplier’ control requires an ‘updated’ event handler to be assigned.These suppliers require manual population and therefore need to be appropriately updated in response to variable or level name changes.
3.1.1.5. Custom Control
Event
Description
creating
Invoked during the creation phase of the options panel. Allows for access to the custom control for customisation before it is made visible.
updated
Invoked when a variable name or level name is changes.
3.1.2. Event handlers
All event handlers are invoked with two arguments; the
ui, and theevent. The ui is a convenience object containing all the other controls in the options panel and the DOM. All the option controls are available in the ui argument as properties. For example:ttestType_changed(ui, event) { let ttype = ui.ttestType.value() if (ttype === 'welchs') ui.priorWidth.setValue(0.707) }In this example, when the user changes the
ttestTypeoption towelchs, thepriorWidthoption is changed to0.707. All options have the.value()and.setValue()methods.Note that each change to the values of the options triggers the re-running of the analysis. If multiple option values need to change in response to an event, it is better to batch these changes together, to prevent the analysis being restarted again and again. Option changes can be batched together with the
ui.view.model.optionsbeginEdit()andendEdit()functions as follows:ui.view.model.options.beginEdit(); ui.figWidth.setValue(400); ui.figHeight.setValue(300); ui.view.model.options.endEdit();In this example, changing the
figWidthandfigHeightoptions only triggers the re-running of the analysis once.
3.1.3. Accessing the DOM
The DOM for the root of options UI can be accessed from the ui through the
viewproperty:ui.view.el | the root DOM node ui.view.$el | the root DOM node as a jQuery objectIt is also possible to inspect the DOM using the chrome dev tools shipped with jamovi (to access these, click the blue bar at the top of jamovi, and press
F10).Additionally, the DOM elements for most of the option controls are accessible through the
eland$elproperty. i.e.let figWidth = ui.figWidth.el let $figWidth = ui.figWidth.$el
3.2. Adding a custom control
Sometimes the controls built into jamovi do not provide the behaviour your analysis requires. In this scenario, it’s possible to create a ‘custom control’ which is placed within the DOM.
A control of type
CustomControlallows for this possibility, when added to the.u.yaml-file, and thecreatingevent is handled in the javascript.For example, the description of the control in the
.u.yaml- type: CustomControl name: ttestTypeand the event handler for the the
.jsttestType_creating: function(ui, event) { let $element = ui.ttestType.$el; // in this instance, the $element object represents the root DOM node // of the custom control. sub-nodes can be added to this node, and the // control will be laid out by the layout manager in the final options // UI }
3.3. Options UI from scratch
Sometimes an analysis requires a very radical UI design that can’t be accommodated by the standard UI controls or a custom control. If this is the case, an entirely custom UI may need to be developed.
To achieve this, the options and their types are defined as usual in the
.a.yaml-file, however, each option is marked ashidden: true. This preventsjmvtoolsfrom (re)adding the standard UI controls into the.u.yaml-file, allowing you to implement them yourself.To construct the UI, all the DOM setup for the custom panel should occur in a
creatingevent handler for theviewcontrol.'use strict'; module.exports = { view_creating: function(ui, event) { let $panel = ui.view.$el; // in this instance, the $panel object represents the root DOM node // of the options panel. sub-nodes can be added to this node. } }