This is a lower-level API. Lower-level APIs are not recommended for most projects, and may not be available on all plans. See our page on recommended deployment patterns for more information.

Public Methods

This article details the public methods you can use to interact with the Question Editor API. It also covers how to deal with page unload events.

The following methods are accessed via the window.LearnosityQuestionEditor object.

When the <script src="https://questioneditor.learnosity.com"></script> tag is included on the page, the window.LearnosityQuestionEditor object is instantiated, and ready for use.

A method called on window.LearnosityQuestionEditor to instantiate an instance of the Question Editor. Once called, and finished initializing (see callbacks for more info on when the API is considered in 'ready' state), you can use the returned application instance (called questionEditorApp in this documentation) to access its public methods.

This function must be called before any other functionality can be used.

Parameters
initOptions
object

Object containing Question Editor config parameters.

See initOptions for more information.

selector
string

DOM element where Question Editor should be rendered into.

For example, if you pass .my-question-editor as the second argument, you should change the div class value from learnosity-question-editor to my-question-editor.

Default: '.learnosity-question-editor'

callbacks
object

Visit the Question Editor API callback object for detailed documentation on callbacks and its parameters.

The following methods are accessed via the questionEditorApp instance returned by window.LearnosityQuestionEditor.init().

Allows you to get, modify, or remove a specified input value based on an attribute path.

For example, if you wanted to set the stimulus but didn't want to change anything else, it would be better to use the attribute method rather than setWidget.

Parameters
attribute_path
string
Returns:
Return value types:
attributeObject

A returned instance of attributee.g. stimulus

undefined
If the attribute does not exist. This could happen with custom questions for example.

For this reason, make sure to check the returned value is a defined object before calling its methods.

One way of doing this is by leveraging optional chaining for example with

const value = attribute('stimulus')?.getValue();
questionEditorApp.attribute("stimulus");

/* example output - returns object with available functions
{
    {getValue: f, setValue: f, remove: f}
}
*/

Checks whether the question currently being edited has a correct answer set.

Parameters
options
object
Properties:
showErrors
boolean
When true and a correct answer is not set, this will highlight the "Set correct answer(s)" section in the UI.

Default: false

Returns:
Return value types:
validationStatusObject

A return object of checkValidation that contains has_validation property which indicates the presence of validation

false

If the operation can not be performed.
i.e., the widget currently being edited is not a question, or the editor is not in the widget edit view.

Note An error message will also be logged to the console.

var result = questionEditorApp.checkValidation({ showErrors: true }); // { has_validation: true }

Destroy current instance of the Question Editor API app.

This method will also restore the HTML hook which was used to first initialize the app. Remember to delete references to the instance as well. You need to make sure that you don't destroy while Question Editor is still initializing, as this may lead to unexpected results. You should only use destroy() after readyListener is called.

function destroy () {
    questionEditorApp.destroy();
}

Returns the JSON currently available in the Editor.

Returns: QuestionJson

Returns the metadata JSON of the current widget.

Currently metadata has key template_reference which specifies the template with which the current question is displayed. If a question is displayed within a custom template, the metadata should be saved as part of the question. On editing the question, setWidget should be called with the metadata as second argument, so that the question is displayed as it was at creation time.

Returns: metadataJson

Removes a previously-bound callback function for an event.

When called with no parameters, callbacks for all events are removed.

Parameters
event_name
string

Name of the event that you want to stop listening to.

See events list for more information.

event_callback
function()

If no callback is provided, all callbacks for the event_name will be removed.

context
object

If no context is provided, all callbacks for the event_name, event_callback combination will be removed.

questionEditorApp.off("preview:changed"); //Removes callbacks for the 'preview:changed' event.
questionEditorApp.off(); //Removes callbacks for all events.

Set up an event listener.

Parameters
event_name
string

Name of the event that you want to listen to.

See events list for more information.

event_callback
function()

Callback function that will be invoked whenever the event is triggered.

context
object

Execution context that will be used for this when the callback function is invoked.

questionEditorApp.on("preview:changed", function() {
    console.log("The preview data was changed.");
}); // Sets up a recurring event listener for the 'preview:changed' event.

Set up an one time event listener. Will fire once and then stop listening.

Parameters
event_name
string

Name of the event that you want to listen to.

See events list for more information.

event_callback
function()

Callback function that will be invoked whenever the event is triggered.

context
object

Execution context that will be used for this when the callback function is invoked.

questionEditorApp.once("editor:ready", function() {
    console.log("The editor has fully loaded.");
}); // Sets up a one-time event listener for the 'editor:ready' event.

Returns the Questions API instance being used by Question Editor API when editing a widget (used by the set validation area and the preview area).

This instance exposes the public methods (see return value link for exposed public methods.) for use to customise behavior, or getting data directly from it not otherwise exposed by Question Editor API.

Version added: v2021.3.LTS

Returns: Questions API
// Example 1: Validate answer in the preview area
questionEditorApp.questionsApp().validateQuestions();

// Example 2: Get feature and stop video playing (e.g. with custom button)
const features = authorApp.editorApp().questionsApp().features();

Object.values(features).forEach(function(feature) {
    feature.video.stop();
});

Revert Question Editor state to a newer captured state.

Conditions that may prevent operation to be performed:

  • A previous Undo/Redo operation is still running.
  • There are no previous snapshots to revert to.
  • A snapshot is currently being saved.
  • The page has not yet completely loaded.

To know when the undo operation has completed, listen to the revisionHistoryState:change (refer to event types) and watch for when either canUndo or canRedo is true.

Note User must have called undo method before being able to call redo method.

Note If undo method is called and then a change is made to the question, then the redo operation can not be called, as the newer states will have been removed to capture the latest change.

Returns:
Return value types:
boolean
If the operation can not be performed, then false is returned
null
If the operation can be performed, then null is returned
// event to listen - after undo
questionEditorApp.on("revisionHistoryState:change", function (data) {
    console.log(data); //{canUndo: false, canRedo: true}
});

questionEditorApp.redo(); //{canUndo: true, canRedo: false}

To reset data of rendered views and empty the json of given question/feature. For default global layout, the method will set the view back to the widget selection screen. It can optionally pass a widget_type to change between feature and response types in a single instance.

You need to make sure that you don't reset while Question Editor is still initializing, as this may lead to unexpected results. You should only use reset() after readyListener was called.

Parameters
widget_type
string

See widget_type for more information.

document.getElementById('reset').onclick = function () {
    questionEditorApp.reset('feature');
};

Called to determine if the user has made any changes and if it is safe to unload/navigate away from the Questions Editor. It will return true, if content has not been modified after question/feature has been rendered

External code can manually mark the Questions Editor as safe to unload by passing "true" as the first argument to this method.

Parameters
isSafe
boolean

Mark the editor as safe to unload

Returns: boolean

Sets JSON to edit in the Question Editor API. The Question Editor API will open the specified question/feature type and pre-populate attributes from the supplied JSON.

The responseJson argument is the JSON Object to set in the editor for editing.

setWidget accepts an object specifying a template_reference key for the template as a second argument. If this is set, the widget is displayed within the template specified by the argument. Use that approach if you have custom template (with hidden sections, fields, etc.) set up as reference of QuestionType inside question_types.

Important: This method should only be called once the Question Editor API is fully loaded. It is provided to allow setting JSON at later stages if needed. If you have not loaded the Question Editor API and want to initialise the API with a specific question/feature type and pre-filled data, you should use the widget_json init option rather than setWidget.

Note User must have called undo method before being able to call redo method.

Parameters
widget_json
object

The widget JSON to be set

widget_template
object

The widget template to be used to render JSON. Template of same question/feature type is supported that is determined by widget_json, otherwise default template is used

Properties:
template_reference
string

The reference of the widget template to be used. Refer to the template reference knowledge base article for more details

Default: First template available for question/feature type

// on clicking the setWidget button, provide the new Response object with a changed picture.
    var responseJson = {
        "type": "highlight",
        "description": "The student needs to mark one of the flower's anthers in the image.",
        "img_src": "http://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Mono_Lake_Old_Marina_August_2013_012.jpg/320px-Mono_Lake_Old_Marina_August_2013_012.jpg",
        "line_color": "rgb(255, 20, 0)",
        "line_width": "4"
    };

    document.getElementById('setWidget').onclick = function (){
        questionEditorApp.setWidget(
            responseJson,
            {
                "template_reference": "908de244-5c71-4c09-b094-7fb49554f2f9"
            }
        );
    };

Revert Question Editor state to a previously captured state.

Conditions that may prevent operation to be performed:

  • A previous Undo/Redo operation is still running.
  • There are no previous snapshots to revert to.
  • A snapshot is currently being saved.
  • The page has not yet completely loaded.

To know when the undo operation has completed, listen to the revisionHistoryState:change (refer to event types) and watch for when either canUndo or canRedo is true.

Returns:
Return value types:
boolean
If the operation can not be performed, then false is returned
null
If the operation can be performed, then null is returned
// event to listen - after modifying any input field
questionEditorApp.on("revisionHistoryState:change", function (data) {
    console.log(data); //{canUndo: true, canRedo: false}
});

questionEditorApp.undo(); //{canUndo: false, canRedo: true}

In the Methods sections above, there are some object definitions which are complex enough to document separately. These are listed below, and linked from the relevant documentation above.

object

A returned instance of attribute e.g. stimulus

Properties:
addArrayItem

To add a new item to array collection type attribute
e.g. options, stems, response_containers

getValue
function()

Get current value of given attribute

Returns: string
remove
function()

To remove given array item, available for node of array collection only
e.g. options[1], stems[0]

setValue

Set value of given attribute

var stimulusAttribute = questionEditorApp.attribute("stimulus");
stimulusAttribute.getValue(); // "[This is stem.]"
stimulusAttribute.setValue("This is new stem!");

var optionsAttribute = questionEditorApp.attribute("options"); // Options is array node like "options": ["choice A", "choice B"]
optionsAttribute.addArrayItem("choice C"); // Create new array item with value "choice C"

var firstOptionAttribute = questionEditorApp.attribute("options[0]");
firstOptionAttribute.remove(); // Remove first array item options[0] ("choice A") from "options" array collection

To add a new item to array collection type attribute
e.g. options, stems, response_containers

Parameters
array_item
string

New array item

Set value of given attribute

Parameters
value
string

Value of attribute object

object

A return object of getMetadata that contains template name and template_reference data

Properties:
name
string

Template name of given question/feature

template_reference
string

Template reference of given question/feature

object

A return object of checkValidation that contains has_validation property which indicates the presence of validation

Properties:
has_validation
boolean

If true, the question currently being edited has a correct answer set.