This article explains how to change the Question Editor edit panel layouts. Here's a demo of a customized edit layout so you can see what is possible.
Add the layout configuration
Add the ui.layout.edit_panel settings to your Question Editor API initialization options. The layout value identifies the custom layout and must match the data-lrn-qe-layout value of the layout template added to the page.
You can apply a custom layout to:
- All templates for a particular Widget type.
- A template with a particular name.
- A template with a particular reference.
Apply a layout to all templates for a Widget type
Specify only the layout property to apply the layout to all templates for the specified Widget type.
Example:
ui: {
layout: {
edit_panel: {
mcq: [
{
layout: "mcq_1"
}
]
}
}
}In this example, the mcq_1 layout applies to all mcq templates.
Apply a layout to a template name
Use the template property to apply a layout to templates with a particular name.
Example:
ui: {
layout: {
edit_panel: {
mcq: [
{
layout: "mcq_1",
template: "Multiple Choice – Multiple Response"
}
]
}
}
}In this example, the mcq_1 layout applies to the template named Multiple Choice – Multiple Response.
Apply a layout to a template reference
Use the template_reference property to apply a layout to a template with a particular reference. If both template and template_reference are supplied, template_reference is used.
Example:
ui: {
layout: {
edit_panel: {
mcq: [
{
layout: "mcq_1",
template_reference: "9e8149bd-e4d8-4dd6-a751-1a113a4b9163"
}
]
}
}
}In this example, the mcq_1 layout applies to the template with the specified reference.
Add the custom layout template to the page
Add a <script> element to the same HTML page that initializes Question Editor API. Set its type to text/template and use the data-lrn-qe-layout attribute to identify the layout. The identifier must match the layout value specified in the initialization options.
Add the complete custom editor layout inside the <script> element.
Example:
<script type="text/template" data-lrn-qe-layout="mcq_1">
<div class="lrn-qe-edit-form">
<h1>My Custom Edit Panel Layout</h1>
<span data-lrn-qe-label="stimulus"></span>
<span
data-lrn-qe-input="stimulus"
data-lrn-qe-i18n-placeholder-label="empty_stimulus">
</span>
</div>
</script>Download and modify the Question or Feature layout
Download the default layout for the Question or Feature type you want to customize from the layout download page. Paste the downloaded template inside the <script> element and modify it to suit your requirements. For example, you can change labels, rearrange attributes, or remove attributes that should not appear in the edit panel.
How editor_schema and editor_layout work together
For a Custom Question or Feature, the editor_schema defines the attributes that an author can configure and the editor controls used to edit those attributes. It is specified as part of the Custom Question or Feature definition.
The editor_layout is an HTML template that controls where those attributes appear in the Question Editor edit panel. The layout template is added to the page using a <script> element and connected to Question Editor API through the ui.layout.edit_panel initialization settings.
When an editor_layout is supplied, each attribute that should appear in the edit panel must be referenced using an appropriate data-lrn-qe-* hook, such as data-lrn-qe-input or data-lrn-qe-label. Attributes that are not referenced in the custom layout are not rendered.
Layout conventions
When creating an editor layout:
- Use
data-lrn-qe-inputto render an editor control for an attribute. - Use
data-lrn-qe-labelto render the corresponding label defined by the attribute'snameproperty. - Use
data-lrn-qe-loopfor array attributes. - Reference every attribute that should appear in the editor. Attributes that are not referenced are not rendered.
Editor Layout components
Custom editor layouts use HTML elements with data-lrn-qe-* attributes. These hooks identify where Question Editor API should render labels, input controls, array entries, actions, and sections within the HTML template.
The available layout components are grouped into the following categories:
- Simple Question or Feature attributes
- Array attributes
- Sections
Simple Question or Feature attributes
Use the following hooks to render non-array attributes in a custom layout:
data-lrn-qe-inputdata-lrn-qe-labeldata-lrn-qe-i18n-placeholder-label
The following example renders the label and input control for the stimulus attribute and specifies placeholder text to use when the input is empty:
<div class="lrn-qe-edit-form">
<span
data-lrn-qe-label="stimulus"
class="lrn-text-normal">
</span>
<span
data-lrn-qe-input="stimulus"
data-lrn-qe-i18n-placeholder-label="empty_stimulus"
class="lrn-qe-lg-ckeditor lrn-text-normal">
</span>
</div>data-lrn-qe-input
Defines where the editor control for a particular Widget attribute, such as the Question stimulus, is rendered.
Inputs only work for non-array attributes. To position an array attribute, see the section on array attributes.
For example:
<span data-lrn-qe-input="stimulus" data-lrn-qe-label="Compose question:"></span> will render the following:
| Attributes | Description |
|---|---|
data-lrn-qe-input |
Define which Widget attribute this input relates to |
class |
(Optional) Define extra CSS classes for the rendered input. The Question Editor API will not strip out any classes specified in the layout. |
data-lrn-qe-show-delete |
In a complex component where there is a delete button, this flag allows you to show or hide the delete button. It accepts either true or false and the default is true. It is currently supported with the following inputs: mcq options, math symbols, possible responses, essay formatting options, math symbol groups, highlight line colour options, math text blocks, graph tools and controls and possible points in number line Questions. |
data-lrn-qe-label |
Define which Widget attribute this label relates to. |
<h1>My Custom Edit Panel Layout</h1>
<span data-lrn-qe-input="stimulus" class="lrn-qe-lg-ckeditor lrn-text-normal"></span>
<!-- MCQ options with hidden delete button -->
<div data-lrn-qe-loop="options[*]">
<span data-lrn-qe-input="options[*]" data-lrn-qe-show-delete="false"></span>
</div>Nested attributes are referenced using dot notation.
For example:
<span data-lrn-qe-input="validation.valid_response.score"></span>
The Question Editor automatically resolves the attribute path and renders the corresponding editor control.
Note: The data-lrn-qe-input-path attribute is added automatically by the Question Editor at runtime. It is used internally for attribute lookups and internationalization, and should not be added manually to custom editor layouts.
data-lrn-qe-i18n-placeholder-label
This data field allows you to define a placeholder for the editor, string, textarea and number input fields of Question Editor. The placeholders appear if the element is empty.
If you specify <span data-lrn-qe-input="stimulus" data-lrn-qe-i18n-placeholder-label="empty_stimulus"></span> Question Editor searches for a label with key placeholder:empty_stimulus in the label bundle and will display what it finds there as a placeholder.
If you don't want to specify special keys for the placeholder values, you can use default keys in the label bundle. Default keys are built by adding a prefix placeholder: to an element's attribute path. For example, for data-lrn-qe-input="stimulus" you can specify a label with key placeholder:stimulus.
| Attributes | Description |
|---|---|
| data-lrn-qe-i18n-placeholder-label | Define which label should be used as a placeholder for this element. |
<h1>My Custom Edit Panel Layout</h1>
<span data-lrn-qe-input="stimulus" data-lrn-qe-i18n-placeholder-label="empty_stimulus"></span>data-lrn-qe-label
Define where the label for a particular Widget attribute (for example, Question stimulus) should be rendered. Labels only work for non-array attributes. If you want to position an array attribute, see the section on loops.
For example, <span data-lrn-qe-label="stimulus"></span> will render the following:
| Attributes | Description |
|---|---|
| data-lrn-qe-label | Define which Widget attribute this label relates to |
| class | (Optional) Define extra CSS classes for the rendered label. The Question Editor API will not strip out any classes specified in the layout. |
<h1>My Custom Edit Panel Layout</h1>
<span data-lrn-qe-label="stimulus" class="lrn-qe-lg-ckeditor lrn-text-normal"></span> Array attributes
Array attributes can contain multiple entries, such as MCQ options or validation alternate responses. Use data-lrn-qe-loop to define the HTML template for each array entry. Add and remove controls can be included using data-lrn-qe-action-add and data-lrn-qe-action-remove.
The following example renders a list of options with controls for adding and removing entries:
<div class="lrn-qe-options">
<div data-lrn-qe-loop="options[*]">
<span data-lrn-qe-label="options[*]"></span>
<span
data-lrn-qe-input="options[*]"
data-lrn-qe-show-delete="false">
</span>
<span data-lrn-qe-action-remove="options[*]"></span>
</div>
<span data-lrn-qe-action-add="options"></span>
</div>data-lrn-qe-loop
Define the DOM template of a complex array Item.
Loops are needed for array attributes, for example, alternate responses. (There can be multiple alternate responses so the Question JSON will contain an array.) The example in the code example on the right will render the DOM below, every time a new alternate response is added by the author. Behind the scenes, the Question Editor API layout engine injects the template inside the corresponding data-lrn-qe-loop any time a view that matches the loop regex (validation.alt_responses[*]).
| Attributes | Description |
|---|---|
| data-lrn-qe-loop | Define the template of the array Item (can be nested in another array Item's loop template). When the Learnosity Question Editor API layout engine hits a div with a data-lrn-qe-loop attribute, it will use the inner HTML of that div as the template for the specified array attribute. |
<div class="lrn-qe-tab-item" data-lrn-qe-loop="validation.alt_responses[*]" data-lrn-qe-tab-item
data-lrn-qe-layout-listeners="remove">
<div class="lrn-qe-tab-header" data-lrn-qe-tab-header>
<div class="lrn-qe-tab-trigger" data-lrn-qe-trigger>
<span data-lrn-qe-label="validation.alt_responses[*]"></span>
</div>
</div>
<div class="lrn-qe-tab-content" data-lrn-qe-tab-content>
<div class="lrn-qe-tab-sub-content">
<span data-lrn-qe-action="validation.alt_responses[*]" class="lrn-qe-tab-remove"></span>
<span data-lrn-qe-input="validation.alt_responses[*].score"
data-lrn-qe-label="Point(s)"
class="lrn-qe-form-control-sm lrn-text-normal lrn-qe-custom-points lrn-mls"></span>
</div>
<span data-lrn-qe-input="validation.alt_responses[*].value" data-lrn-qe-label></span>
</div>
</div>data-lrn-qe-action-add
Define where add buttons for a particular attribute (for example, options for an mcq Question) should be rendered.
For example, <span data-lrn-qe-action-add="options"></span> will render the following:
| Attributes | |
|---|---|
| data-lrn-qe-action-add | Define which Widget attribute (for example, options for an mcq Question) these action buttons should control. |
| class | (Optional) Define extra CSS classes for the buttons. The Question Editor API will not remove any classes specified in the layout. |
data-lrn-qe-action-remove
Define where remove buttons for attributes which consist of multiple elements (for example, validation alternate responses) should be rendered.
| Attributes | Description |
|---|---|
| data-lrn-qe-action-remove | Define which Widget attribute (for example, validation alternate responses) the remove button should control |
| class | (Optional) Define extra CSS classes for the buttons. The Question Editor API will not remove any classes specified in the layout. |
Section
data-lrn-qe-section
Defines a named layout section that can be shown or hidden using hidden_sections/shown_sections in the init options
For example:
<div data-lrn-qe-section="more_options.heading">
<h2>More options</h2>
</div>
<div data-lrn-qe-section="more_options.content">
<span data-lrn-qe-label="instant_feedback"></span>
<span data-lrn-qe-input="instant_feedback"></span>
</div>
<hr data-lrn-qe-section="more_options.divider">| Attributes | Description |
|---|---|
| data-lrn-qe-section | Define the name of the section, for example, "more_options.heading" "more_options.content" "more_options.divider" |
Note: When you define a custom editor layout, you already control which attributes and sections are included. Therefore, you generally do not need to define sections and then hide them using separate initialization settings. Use data-lrn-qe-section only when the same custom layout must support different section visibility configurations.
Common layout behaviors
The following behaviors apply when using custom editor layouts:
| Behavior | Description |
|---|---|
| Explicit rendering | Only attributes referenced using data-lrn-qe-* hooks are rendered. |
| Automatic labels |
data-lrn-qe-label displays the value of the attribute's name property. |
| Nested attributes | Reference nested attributes using dot notation. |
| Arrays | Render arrays using data-lrn-qe-loop and the [*] wildcard. |
| Automatically generated layouts | If no editor_layout is supplied, the Question Editor automatically generates the layout from the editor_schema. |
| Custom layouts | The HTML layout controls attribute placement; the group property is ignored. |