Extending the JavaScript template

All aspects of the task's lifecycle are controlled by two JavaScript classes:

  • Task is responsible for rendering and validating an individual task. Typically, you should extend this class if a task needs to have non-standard behavior.

  • TaskSuite is a “wrapper class” for the task page interface. You can redefine this class, like if you need to display a shared element on the page.

You can use services for specific needs (such as subscribing to keyboard presses or getting the user's GPS coordinates).

Lifecycle of a task

When a user starts a task, the workspace is initialized in the iframe. First, the list of tasks is requested. Then the received list is passed to the TaskSuite class. It creates an instance of the Task class for each task.

Rendering

To render the task page, the render() method of the TaskSuite class is called. This method calls the render() method of the Task class for each task and collects the created DOM tree components in a single list.

Here you can change the rendering of tasks and task pages.

Response validation

When the performer clicks the Send button, the TaskSuite.validate (solutions) method is called to validate the performer's responses. It calls the Task.validate (solutions) method for each task and returns errors.

Here you can launch additional verification of the performer's responses.

Removal

When the performer has finished all tasks on the page or skipped it, the destroy() class's TaskSuite method is called. It calls the destroy() method of the Task class for each task. These methods free up resources and remove the services and event handlers associated with tasks.

Class inheritance

To keep the code from looking heavy, use the following function for class inheritance and redefinition:

function extend(ParentClass, constructorFunction, prototypeHash) {    
    constructorFunction = constructorFunction || function() {};    
    prototypeHash = prototypeHash || {};        
    if (ParentClass) {        
        constructorFunction.prototype = Object.create(ParentClass.prototype);    
    }    
    for (var i in prototypeHash) {        
        constructorFunction.prototype[i] = prototypeHash[i];    
    }    
    return constructorFunction;
}

Function call:

var ChildClass = extend(ParentClass, function() {    
    ParentClass.call(this);
}, {    
    method: function() {}
})

Data types

The Task object is the task to perform.

{
    "id": <string>,
    "input_values": {
        "<id of the field with input data>": <value>,
        …
     }}

Key

Value

id

Task ID.

input_values

Task input data in the format "<field ID>":"<field value>". Example:
"input_values": {
  "image": "http://images.com/1.png"
}

The Solution object is the performer's response in the task.

{
    "task_id": <string>,
    "output_values": { 
        "<input field ID>": <value>,
        …
    }}

Key

Value

task_id

Task ID.

output_values

Responses in the format "<input field ID>":"<value>". Example:
"outputValues": {
  "colour": "white",
  "comment": "So white"
}

The SolutionValidationError object is a validation error for the performer's response.

{
    "task_id": string,
    "errors": { 
        "<field id>": {
            "code": "<error code>",
            "message": "<string>"
        },
        …
    }}

Key

Value

task_id

Task ID.

errors

Errors in the format: "<field ID>": {code: "<error code>", message: "<error message>"}. Example:
"errors": { 
  "colour": {
    "code": "REQUIRED",
    "message": "Required field"
  }
}