Adding a Custom Editor Layout for a Question Type

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-input to render an editor control for an attribute.
  • Use data-lrn-qe-label to render the corresponding label defined by the attribute's name property.
  • Use data-lrn-qe-loop for array attributes.
  • Reference every attribute that should appear in the editor. Attributes that are not referenced are not rendered.

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-input
  • data-lrn-qe-label
  • data-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>

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:

data-input

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.

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>

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:

data-label.png

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>

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[*]).

data-loop

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>

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:

data-action

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.

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

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.
Was this article helpful?

Did you arrive here by accident? If so, learn more about Learnosity.