diff --git a/docs/en_us/developers/source/extending_platform/extending.rst b/docs/en_us/developers/source/extending_platform/extending.rst index ac9f969779..e9bba048a7 100644 --- a/docs/en_us/developers/source/extending_platform/extending.rst +++ b/docs/en_us/developers/source/extending_platform/extending.rst @@ -15,7 +15,7 @@ This section of the developers' documentation lists and explains the different w :header-rows: 1 * - - - :ref:`Custom JavaScript Display and Grading` + - :ref:`Custom JavaScript Applications` - LTI - External Graders - XBlocks @@ -63,7 +63,7 @@ This section of the developers' documentation lists and explains the different w - Yes - Yes * - Server Side Grading - - No (See JavaScript) + - Possibly (See JavaScript) - Yes - Yes - Yes diff --git a/docs/en_us/developers/source/extending_platform/index.rst b/docs/en_us/developers/source/extending_platform/index.rst index 19459b9bea..5df61fbcc9 100644 --- a/docs/en_us/developers/source/extending_platform/index.rst +++ b/docs/en_us/developers/source/extending_platform/index.rst @@ -6,4 +6,5 @@ Extending the edX Platform :maxdepth: 2 extending.rst - javascript \ No newline at end of file + javascript + js_template_example \ No newline at end of file diff --git a/docs/en_us/developers/source/extending_platform/javascript.rst b/docs/en_us/developers/source/extending_platform/javascript.rst index 88de3df08a..808c11c38e 100644 --- a/docs/en_us/developers/source/extending_platform/javascript.rst +++ b/docs/en_us/developers/source/extending_platform/javascript.rst @@ -1,239 +1,312 @@ - -.. _Custom JavaScript Display and Grading: +.. _Custom JavaScript Applications: ########################################## -Custom JavaScript Display and Grading +Custom JavaScript Applications ########################################## -Custom JavaScript display and grading problems (also called custom JavaScript -problems or JS Input problems) allow you to create a custom problem or tool that -uses JavaScript and then add the problem or tool directly into Studio. When you -create a JS Input problem, Studio embeds the problem in an inline frame (IFrame) -so that your students can interact with it in the LMS. You can grade your -students’ work using JavaScript and some basic Python, and the grading is -integrated into the edX grading system. - -Course staff should see `documentation on using custom JavaScript `_ and `Establishing a Grading Policy `_ in *Building and Running an edX Course*. - -The rest of this section provides more information for developers who are creating JavaScript applications for courses on the edX platform. - -.. note:: This section assumes proficiency with JavaScript and Python, and with how problems are constructed in edX Studio. ******************************* -The Template Example +Overview ******************************* -As referred to in `course staff documentation `_, there is a built-in template in Studio that uses a sample -JavaScript application. -This sample application has students select two different shapes, a cone -and a cube. The correct state is when the cone is selected and the cube is not selected: +You can include custom JavaScript applications (also called custom JavaScript +problems or JS Input problems) in a course. You add the application directly +into edX Studio. -.. image:: ../images/JavaScriptInputExample.png - :alt: Image of the sample JavaScript application, with the cone selected +When you create a JavaScript application, Studio embeds the problem in an inline +frame (HTML ``iframe`` tag) so that students can interact with it in the LMS. -You can `download files for that application `_. You must upload these files in edX Studio to use them in a problem. +See the following sections for more information: -The following information uses this example to explain what developers need to know to embed their JavaScript applications in an edX course. +* `Grading Options for Custom JavaScript Applications`_ +* `Use a JavaScript Application Without Grading`_ +* `Use a JavaScript Application for a Summative Assessment`_ +* `Grade the Student Response with Python`_ +* `XML for Custom JavaScript Applications`_ -******************************* -Required JavaScript Functions -******************************* +See :ref:`The Custom JavaScript Display and Grading Example Template` for +information about the template application built in to edX Studio. -To enable grading of students' interactions, your JavaScript application must contain three global methods: +Course staff should see the following sections of the document `Building and Running an edX Course `_: -* ``getState`` -* ``setState`` -* ``getGrade`` +* `Custom JavaScript Display and Grading `_ + +* `Establishing a Grading Policy `_ + +The rest of this section provides more information for developers who are +creating JavaScript applications for courses on the edX platform. + +.. note:: This section assumes proficiency with JavaScript and with how problems + are constructed in edX Studio. If you intend to grade students' interactions + with your JavaScript application, you must also be proficient with Python. + + + +******************************************************* +Grading Options for Custom JavaScript Applications +******************************************************* + +When using a JavaScript application in your course content, you have three +options: + +#. A JavaScript application that visually demonstrates a concept or process. The + application would not require student interaction, and students would not be + graded. + +#. A JavaScript application that requires student interaction but does not grade + performance. Referred to as a formative assessment, such an application + provides feedback to students based on their interactions. + +#. A JavaScript application that requires and grades student interaction. + Referred to as a summative assessment, such an application can be used to + evaluate student learning against a standard. To use the JavaScript + application as a summative assessment and have student performance integrated + into the edX grading system, you must also use basic Python code in the + component. + +These options are explained through examples below. + +******************************************************* +Use a JavaScript Application Without Grading +******************************************************* + +The simplest option is to use JavaScript to show content to students, and +optionally to provide feedback as a formative assessment. + +#. In edX Studio, upload an HTML file that contains the JavaScript you want to + show students. +#. Copy the **Embed URL** of the file. +#. `Create a Custom JavaScript Display and Grading Problem `_. The template + for the problem contains the definition for a sample JavaScript application + that requires and grades student interaction. +#. Edit the XML of the component to remove grading information and refer to the + HTML file you uploaded: + +.. code-block:: xml + + + + + +For example: + +.. code-block:: xml + + + + + + +************************************************************** +Use a JavaScript Application for a Summative Assessment +************************************************************** + +To use a JavaScript Application for a summative assessment and have student +results calculated by the edX grading system, you must: + +* Include required functions in the JavaScript application. + + * `getState() Function`_ + * `setState() Function`_ + * `getGrade() Function`_ + +* Reference functions in the problem XML. + +* `Grade the Student Response with Python`_. -You reference these methods in the XML problem specification, as described below. ==================== getState() Function ==================== -Your application must be able to return the state of objects on which grades will be based. +Your application must contain a ``getState()`` function that returns the state +of all objects as a JSON string. -In the template example, grading is based on the the state of the cylinder and cone objects. The state is initialized for the cylinder and cube in the ``WebGLDemo.js`` file: +The ``getState()`` function retrieves the state of objects in the application, +so each student experiences that application in its initial or last saved state. -.. code-block:: javascript +The name of the ``getState()`` function must be the value of the ``get_statefn`` +attribute of the ``jsinput`` element for the problem. - var state = { - 'selectedObjects': { - 'cylinder': false, - 'cube': false - } - } +For example: -User interactions toggle the ``state`` values of the cylinder and cube between ``true`` and ``false``. +.. code-block:: xml -Your application must contain a ``getState()`` function that is referenced in the XML problem specification and that returns the current state as a JSON string. + + + + - import json - def vglcfn(e, ans): - ''' - par is a dictionary containing two keys, "answer" and "state" - The value of answer is the JSON string returned by getGrade - The value of state is the JSON string returned by getState - ''' - par = json.loads(ans) - # We can use either the value of the answer key to grade - answer = json.loads(par["answer"]) - return answer["cylinder"] and not answer["cube"] - ''' - # Or we could use the value of the state key - state = json.loads(par["state"]) - selectedObjects = state["selectedObjects"] - return selectedObjects["cylinder"] and not selectedObjects["cube"] - ''' - +In the Python code, you must: -In this example, the ``ans`` parameter contains the JSON string returned by ``getGrade()``. The value is converted to a Python Unicode (?) structure in the variable ``par``. +* Enclose all code in a ``script`` element of type ``loncapa/python``. -In the function's first option, object(s) the student selected are stored in the ``answer`` variable. If the student selected the cylinder and not the cube, the ``answer`` variable contains only ``cylinder``, and the function returns ``True``, which signifies a correct answer. Otherwise, it returns ``False`` and the answer is incorrect. +* Import ``json`` -In the function's second option, the objects' states are retrieved. If the cylinder is selected and not the cube, the function returns ``True``, which signifies a correct answer. Otherwise, it returns ``False`` and the answer is incorrect. +* Define a function that is executed when the student clicks Check. This + function: + * Is placed before the ``customresponse`` element that defines the problem. + * By default is named ``vglcfn`` + * Has two parameters: ``e`` for the submission event, and ``ans``, which is + the JSON string returned by the JavaScript function ``getGrade()``. + * Must return ``True`` if the student's submission is correct, or ``False`` if + it is incorrect. -******************************* -XML Problem Structure -******************************* - -Following the Python code and any HTML content you want to precede the IFrame containing your JavaScript application, you define the XML for the problem. - -The XML problem for the sample template is: +The structure of the Python code in the problem is: .. code-block:: xml - - - + + + + . . . . + -As in this example, the JS Input problem is defined in a ```` element. -The value of the ``cfn`` attribute is the name of the Python function in the problem that evaluates the submission's grade. +******************************************************* +XML for Custom JavaScript Applications +******************************************************* -The ```` element contains a ```` element, which defines how your JavaScript application is used in the course. +The problem component XML that you define in Studio to provide students with a +JavaScript application has the following structure: + +.. code-block:: + + + + + + + + -Following are details about the attributes of the ```` element. =================== jsinput attributes =================== +The following table describes the attributes of the ``jsinput`` element. + .. list-table:: - :widths: 10 80 10 + :widths: 10 50 10 :header-rows: 1 * - Attribute - Description - Example * - gradefn - - The function in your JavaScript application that returns the state of the objects to be evaluated as a JSON string. - - ``WebGLDemo.getGrade`` + - The function in your JavaScript application that returns the state of the + objects to be evaluated as a JSON string. + - ``JSObject.getGrade`` * - get_statefun - - The function in your JavaScript application that returns the state of the objects. [NOT CLEAR TO ME WHY YOU NEED BOTH getGrade and setState] - - ``WebGLDemo.getState`` + - The function in your JavaScript application that returns the state of the + objects. + - ``JSObject.getState`` * - set_statefun - - The function in your JavaScript application that saves the state of the objects. - - ``WebGLDemo.setState`` + - The function in your JavaScript application that saves the state of the + objects. + - ``JSObject.setState`` * - width - - The width of the IFrame in which your JavaScript application will be displayed, in pixels. + - The width of the IFrame in which your JavaScript application will be + displayed, in pixels. - 400 * - height - - The height of the IFrame in which your JavaScript application will be displayed, in pixels. + - The height of the IFrame in which your JavaScript application will be + displayed, in pixels. - 400 * - html_file - - The name of the HTML file containing your JavaScript application that will be loaded in the IFrame. + - The name of the HTML file containing your JavaScript application that + will be loaded in the IFrame. - /static/webGLDemo.html * - sop - - The same-origin policy (SOP), meaning that all elements have the same protocol, host, and port. To bypass the SOP, set to ``true``. - - false + - The same-origin policy (SOP), meaning that all elements have the same + protocol, host, and port. To bypass the SOP, set to ``true``. + - false \ No newline at end of file diff --git a/docs/en_us/developers/source/extending_platform/js_template_example.rst b/docs/en_us/developers/source/extending_platform/js_template_example.rst new file mode 100644 index 0000000000..1287eae492 --- /dev/null +++ b/docs/en_us/developers/source/extending_platform/js_template_example.rst @@ -0,0 +1,195 @@ +.. _The Custom JavaScript Display and Grading Example Template: + +########################################################### +The Custom JavaScript Display and Grading Example Template +########################################################### + +As referred to in `course staff documentation `_, there is a built-in template in edX Studio that uses a sample JavaScript application. + +This sample application has students select two different shapes, a cone and a +cube. The correct state is when the cone is selected and the cube is not +selected: + +.. image:: ../images/JavaScriptInputExample.png + :alt: Image of the sample JavaScript application, with the cone selected + +You can `download files for that application `_. +You must upload these files in Studio to use them in a problem. + +The following information steps through this example to demonstrate how to apply +the guidelines in `Custom JavaScript Display and Grading`. + + +**************************** +Example getState() Function +**************************** + +In the example, the ``state`` variable is initialized for the cylinder and cube +in the ``WebGLDemo.js`` file: + +.. code-block:: javascript + + var state = { + 'selectedObjects': { + 'cylinder': false, + 'cube': false + } + } + +User interactions toggle the ``state`` values of the cylinder and cube between +``true`` and ``false``. + +The ``getState()`` function in the sample application returns the state as a +JSON string: + +.. code-block:: javascript + + function getState() { + return JSON.stringify(state); + } + + +****************************** +Example setState() Function +****************************** + +In the example, when a student clicks **Check**, the ``state`` variable is saved +so that the student can later return to the application and find it in the same +state: + +.. code-block:: javascript + + function setState() { + stateStr = arguments.length === 1 ? arguments[0] : arguments[1]; + state = JSON.parse(stateStr); + updateMaterials(); + } + +The ``updateMaterials()`` function called by ``setState()`` updates the state of +the cylinder and cone with the user's current selections: + +.. code-block:: javascript + + function updateMaterials() { + if (state.selectedObjects.cylinder) { + cylinder.material = selectedMaterial; + } + else { + cylinder.material = unselectedMaterial; + } + + if (state.selectedObjects.cube) { + cube.material = selectedMaterial; + } + else { + cube.material = unselectedMaterial; + } + } + +****************************** +Example getGrade() function +****************************** + +In the example, when a student clicks **Check**, the ``getGrade()`` function in +returns the selected objects: + +.. code-block:: javascript + + function getGrade() { + return JSON.stringify(state['selectedObjects']); + } + +The returned JSON string is then used by the Python code defined in the problem +to determine if correct objects were selected or not, and to return a result. + +******************************* +Grade the Student Response +******************************* + + +The following is the Python function ``vglcfn`` in the sample application: + +.. code-block:: python + + + +The ``ans`` parameter contains the JSON string returned by ``getGrade()``. The +value is converted to a Python Unicode structure in the variable ``par``. + +In the function's first option, object(s) the student selected are stored in the +``answer`` variable. If the student selected the cylinder and not the cube, the +``answer`` variable contains only ``cylinder``, and the function returns +``True``, which signifies a correct answer. Otherwise, it returns ``False`` and +the answer is incorrect. + +In the function's second option, the objects' states are retrieved. If the +cylinder is selected and not the cube, the function returns ``True``, which +signifies a correct answer. Otherwise, it returns ``False`` and the answer is +incorrect. + + +******************************* +XML Problem Structure +******************************* + +The XML problem for the sample template is: + +.. code-block:: xml + + + +

+ The shapes below can be selected (yellow) or unselected (cyan). + Clicking on them repeatedly will cycle through these two states. +

+

+ If the cone is selected (and not the cube), a correct answer will be + generated after pressing "Check". Clicking on either "Check" or "Save" + will register the current state. +

+ + + +
\ No newline at end of file diff --git a/docs/en_us/developers/source/index.rst b/docs/en_us/developers/source/index.rst index 0f816d7ad0..64d3722f85 100644 --- a/docs/en_us/developers/source/index.rst +++ b/docs/en_us/developers/source/index.rst @@ -37,6 +37,7 @@ Internationalization i18n.rst i18n_translators_guide.rst pavelib.rst + xblocks.rst Indices and tables ==================