Question Authors' Forum

Graph in HTML-Field

by Markus Gafner -
Number of replies: 16

Dear developers,

first, I would like to say thanks you for this plugin. In times of COVID-19, it allows us the test students online.

We are using coderunner for digital logic in the language VHDL. In the basic year, students don't get in touch with VHDL, in this time they learn how to generate boolean-expressions, true tables, state-machines, ... and a lot more.

We like to generate a test where we explain the task and then the students answer multiple questions in this topic. For example, given a Boolean expression, fill the true table and draw the state machine. If the true table contains errors, we’d like to take them in the following question (so that the following questions are correct on their previous answers. Because we didn't find a possibility to share parameters over questions, we made a question using the HTML-UI with custom grading. There we can draw all fields which are required and in the supplied python-script the answers get corrected.

Now to my question: We also like to integrate a Field like the Graph-UI where the students draw their state-machine. Is there a simple solution, or how much effort would be required to implement such a functionality?

In reply to Markus Gafner

Re: Graph in HTML-Field

by Richard Lobb -

I'm interested to see people using the html_ui recently. I originally implemented it just for fun and until this year hadn't ever used it myself in production questions. Suddenly I find several people using it in quite demanding and impressive ways.

You may be interested in the recent forum discussion here, focused on turning an html_ui question into a question type so the html code is shared.

To answer your specific question ... I don't think it's too much work to achieve what you want. As a proof of concept I went back to the open-source project we originally used a basis for graph_ui, here. I copied all of Evan Wallace's JavaScript and some of his html into the GlobalExtra field of an HTML UI question. I gave the canvas element a name ('crui_canvas') and gave it the class "coderunner-ui-element". So that jquery could get the serialised graph (which requires the existence of a val method for the element), I added the snippet

$.valHooks.canvas = { get: function(elem) { saveBackup(); return localStorage['fsm']; } }; And that's about all it took to get a rudimentary graph-drawing window into the answer box. If you click Check a JSON serialisation of the graph is returned as the student answer, in html_ui format. I attach the exported question which just prints the serialisation whenever you click Check. It's only a very crude proof of concept and doesn't handle the necessary loading of the graph from the serialisation when the question is reloaded or reopened, but it should at least give you an idea of what's possible. You can decide if you want to pursue it further. In reply to Richard Lobb Re: Graph in HTML-Field by Markus Gafner - Dear Richard, thanks you very much for your answer. I will try it, but for the moment, I am busy, and the amount of work is no visible for me. As preview, it works well, but in a test, I observed some problems with (de-)serialising the content. Also the missing help-text and the interfacing (directed/indirect, fsm, …) would be needed to be implemented. I was also thinking about the fact, that all scripts are already in moodle. The only problem is that the graph_ui takes the html-tag <textarea> and will insert the graph directly after it. Also, it takes the data from this node. It might make sense to implement a second version of it where a canvas-class and the json-tag gets defined, so that the experience and everything else keeps the same for the users. I will inform you when I get any news In reply to Markus Gafner Re: Graph in HTML-Field by Richard Lobb - Hi Markus When I said "I don't think it's too much work to achieve what you want" I should have clarified that I was wearing my developer's hat, not my question author's hat! It's certainly not trivial to include graph drawing within the HTML-UI context and I didn't intend to imply that my proof of concept was anywhere near workable. Indeed, as you say, the serialisation isn't correct - the original fsm script serialises to/from browser local storage and provides functions to export that in SVG, Latex etc. In a CodeRunner question the code needs to serialise to/from a text area according to events like page load/unload, CTRL-ALT-M and check-button clicks. You say the scripts are already in Moodle, but that's not quite true. The original FSM script(s) have been heavily modified to implement the API defined by interfacewrapper.js : ui_graph.js is an AMD module with all the event handlers required by the protocol. It's not suitable for use within the ui_html context, which supports only html elements of class coderunner-ui-element that implement the jquery val method. And even if it were suitable, there's no easy way to access it. Hence my quick proof-of-context hack was just to take the original unmodified FSM scripts and implement a hook to enable a jquery get (half of the val method) so the serialisation could be read out when required. I didn't implement set (which I think should allow the serialisation to be loaded back in) and didn't strip out all the code associated with the use of local storage and export in various formats. You asked "Is there a simple solution, or how much effort would be required to implement such a functionality?" Perhaps I should have just answered with: "No, there's no simple solution and it would take some effort - plus a detailed understanding of the CodeRunner user-interface elements and protocols - to do it." :-/ Richard In reply to Richard Lobb Re: Graph in HTML-Field by Markus Gafner - Hi Richard, sorry for the long delay. All your writing is correct, I also found the AMD-Scripts and checked them already. Regarding the question-html: A textarea-field gets defined with a certain id containing a rolling number which defined the current attempt-number in moodle. The given AMD-Script will search this field and appends the Graph in / after this field. Also, the results get serialized in this field. (All is given) My approach is now to define such an element in my code. Its more or less copy and paste, I just gave it the class "coderunner-ui-element", changed the id to "graph_target" and gave it the same name so that it gets returned as result: <textarea class="coderunner-ui-element" id="graph_target" name="graph_target" spellcheck="false" rows="18" data-params="" data-globalextra=""></textarea> Next we have to call this AMD-Script, with the defined id: <script> M.util.js_pending('qtype_coderunner/userinterfacewrapper'); require(['qtype_coderunner/userinterfacewrapper'], function(amd) {amd.newUiWrapper("graph", "graph_target"); M.util.js_complete('qtype_coderunner/userinterfacewrapper');});; </script> And this is all which has to be done. Now the HTML-Form shows the Graph-UI as normal, but with other content. There is only one part which is a little bit ugly: Due to the fact, that the id is not unique for each attempt, when multiple attempts are shown, the first one shown n identical graph, where n is the number of attempts which gets shown. Do you think it be possible to define a tag, which gets replaced by the attempt-id in the ui_html.js ? When your already on it, also a content-filter on multilingual content would be nice, because our students speak normally German and French, but we also have students from other countries which prefer English. Unfortunately, the multilang-class doesn’t get filtered. I attached an example with the implemented content. I would like to say thanks you very much, and I will send you an example question if its finished. In reply to Markus Gafner Re: Graph in HTML-Field by Richard Lobb - That's very impressive. I never considered the possibility of including the graph-ui code inside a user interface wrapper inside the html ui inside a user interface wrapper! I also didn't realise you could use M.util to call the AMD script in that way. Nice! I'm certainly open to the idea of tweaking ui_html.js. Would you like to suggest changes? In reply to Richard Lobb Re: Graph in HTML-Field by Markus Gafner - Your right, I'll didn't think that is will work, but the content of the question’s html will be just copied in the html of the Moodle-content. When you see multiple results of the graph-ui, also multiple AMD scripts will get called... For displaying the graph-ui, a tag like the student_anser-tag would be very nice, so that the question-id could get used in the HTML-context to define a certain question. The new HTML-textarea would be for example: <textarea class="coderunner-ui-element" id="graph_target__question_id__" name="graph_target" spellcheck="false" rows="18" data-params="" data-globalextra=""></textarea> For the content filter: I don't know how to realize that caused to the fact that I'll don't know how this is realized in Moodle But thanks for your interest to implement my asked features. I will upload an example question by the end of next week as final result of this discussion. In reply to Markus Gafner Re: Graph in HTML-Field by Markus Gafner - Hi Richard, happy New Year Attached you will find an example of our question. I have replaced the testing code so that the students will not find the code to have the ability to cheat. But we are able to build the next answer dependent of the previous answers of the students, so that consequential failure gets checked. For us, it was difficult to find the correct syntax using the custom-grader. It might make sense to add an example-JSON string which shows the necessary elements. Did you also think about this tag which gets replaced as I suggested before? Cheers Markus In reply to Markus Gafner Re: Graph in HTML-Field by Markus Gafner - Hi Richard, I have made the changes and sent them as a push request. You will find it here: https://github.com/trampgeek/moodle-qtype_coderunner/pull/111 To perform some testing, I have attached the changed question and a screenshot where I did the test as student and show the check of the teacher role. I hope you will include the changes in the plugin. If yes it should also get documented somewhere. In reply to Markus Gafner Re: Graph in HTML-Field by Markus Gafner - Reply No 3: I have also observed that in the student-answer the radio-button is missing when the teacher-answer is shown as well. You can see that in the screenshot of the last post. Subquestion e shows nothing, but in the response history at the bottom, Qd_type holds the parameter Medvedev, which would be the answer. The problem is that the radio-buttons have the same name, so that only one element could get selected. This happens because the student solution and teacher solution contain the same name label, so only one of these twos could get selected. And due to the fact, that first will the student answers build and later the teachers solution. By adding the suffix "___textareaId___" to the name, also this problem could get solved. The only question would be should this tag get removed again? In reply to Markus Gafner Re: Graph in HTML-Field by Richard Lobb - Thanks for a great and instructive example of how to use the html_ui in ways way beyond my original imaginings! Thanks too for the suggested implemented change (i.e. the pull request). It's very ingenious. However I think there's another way to achieve the same effect without adding the extra complication (which would, as you say, need documenting and ideally extra code in the test suite). Can you not just use Twig to insert the question-id (or some number derived from it) into the global extra html specification? You just need to replace your ____textareaid____ tokens with {{ QUESTION.id }} in your global extra code and check the Twig All checkbox. Does that solve your problem? I attach a version of your question modified in that way. Thanks for the heads-up on the difficulty with understanding the custom grader. I'll see if I can improve the documentation in the next release. The problem with the display of the sample answer when using radio buttons is somewhat concerning. I accept that your ____textareaid____ mechanism would provide a way for authors to avoid the issue, unlike my Twig approach, but it would require all them to be aware of both the problem and the ____textareaid____ "macro" mechanism. I would prefer to find a solution that doesn't require question authors to explicitly use special names just for radio buttons. I'm going to mull over that one for a bit to see if I can automate a solution. In reply to Richard Lobb Re: Graph in HTML-Field by Markus Gafner - Dear Richard, for the radio-buttons, I did some research and found out, that is works as desired when I add the question in a <form> ... </form> tag. Then it is possible having multiple radio button groups with the same name. This would be very easy to implement when you checkout the lines around 136 in the amd/src/ui_html.js: outerDiv = "<div style='height:fit-content' class='qtype-coderunner-html-outer-div'>";this.htmlDiv =$(outerDiv + this.html + "</div>");

we could just add the <form> tag to the end of outerDiv and </form> before </div>.

The Twig element {{ QUESTION.id }} does not work as desired. It adds for the student answer and teachers answer the same tag. My tag ____textareaid____ will add a tag like “id_q{{Question.id}}_answer” for the students answer and “id_q{{Question.id}}_sampleanswer” for the teachers answer. And when reviewing the test, it is required to split all answers of the students and the answer of the teacher. Do you think it would be possible to add a twig-tag which specifies if the shown data is an answer or sampleanswer, so if student or teachers answer?

Thanks for the reply
Markus

In reply to Markus Gafner

Re: Graph in HTML-Field

by Richard Lobb -

Hi Markus

Ah yes, of course. I misunderstood - or perhaps forgot - the purpose of your ___textareaid___ macro.

I've pulled your change into Master and also into the development branch I'm working on. I've added the following documentation - please check if it's correct.

=======================

The textareaid macro

A problem arises if the HTML supplied by the question author contains elements with explicit id attributes, as might be required if there is also JavaScript present that needs to refer to the new elements. If the review options allow display of the question author's answer then when the student reviews their quiz, the student answer and the author's answer will both include the new elements, resulting in a conflict of id. Apart from being invalid HTML, this is likely to result in wrong results when any JavaScript code referencing the elements runs.

A workaround for this problem is to include the special macro string

___textareaid___


as part of any new ids. Note that there are THREE (3) underscores at both the start and end of the macro string.

When the HTML UI inserts the global extra html into the question, that macro is replaced everywhere by the actual ID of the answer box's text-area, which is different for the student and author answers. This technique can also be used to ensure that the names given to elements like radio buttons are different in the two answers.

Thanks Markus Gafner for this workaround.

========================

I did think of wrapping the inserted HTML in a form to prevent cross-contamination of radio button names between the student and author answers, but the HTML5 standard doesn't allow forms to be nested and entire quiz review page is wrapped in a form. I don't wish to create illegal HTML or depend on unspecified and possibly browser-dependent behaviour.

Thanks for the contribution

Richard

In reply to Richard Lobb

Re: Graph in HTML-Field

by Markus Gafner -
Dear Richard,
thanks for taking my changes in your code. The macro I defined is ___textareaId___ (with an upper case I). Also, it would be ok for me if you remove my name. It is just a single line, which has been changed. But I would include a paragraph, where gets described that it is possible to include the graph-ui in the HTML question type. The rest sounds okey for me.

Furthermore, I would like to inform you, that the amd-script are not up to date. So, when you generate a new version, the scripts must be updated.

Last week, we presented the results to the students. The students reported that their answers are not completed. I did a simple test and recognized the problem. We had an exam where the students had 60 minutes time to solve the questions. After this time, we set Moodle to collect the answers and evaluate them. To see the problem, I did a simple test with a small HTML-form, 2 fields, 1 minute answer-time. I entered something in the HTML-forms but did not send it to Moodle, because I wanted that Moodle collects the data. I got 0 points because my answer was empty. Repeating this rest with a python-question which uses the Ace-editor has shown, that collecting the data would work, but not for the HTML-formular. My first question could you reconstruct this error, and do you have any clue why this happens? Also do you think the answers are still stored somewhere?
In reply to Markus Gafner

Re: Graph in HTML-Field

by Richard Lobb -

Thanks for picking up the error of the lower-case 'i'. Fixed now.

I've changed the "Thanks for Markus Gafner" paragraph to

As an example application of this capability, see this CodeRunner author's forum thread where Markus Gafner (who contributed this workaround) shows a TextUI question with an embedded GraphUI question, plus other embedded questions.

Are you happy to have your name mentioned there or would you like me to remove it altogether?

I do always use grunt to rebuild the 'build' versions of amd modules before committing. But when I merged your pull request into master I made the mistake of assuming you had included any changed code in the pull request. However, I don't think it breaks anything - your textareaId feature isn't documented in the master branch yet and the fact that it doesn't work in the 'build' version shouldn't be a problem.

I'm sorry to hear about the failures in the test last week. Indeed if you depend entirely on "Open attempts are submitted automatically" it seems there's a problem, which I wasn't aware of.

The contents of the various CodeRunner UI elements are sync'd back to the underlying textarea answerbox only when a question is saved or submitted, which includes:
• when the student clicks Check or Precheck,
• when the user navigates to a different quiz page
• when the user explicitly submits their quiz.
The only exceptions are the AceUI and the GraphUI, both of which sync after every change.

I would have expected the "Open attempts are submitted automatically" feature, which is implemented in JavaScript, would initiate a submit operation on the form which should have in turn called my own sync code. But that seems not to be happening. I'll look into it. But I fear that the data is lost - all that is getting sent to the server on a quiz timeout is the unsync'd raw text area contents.
In reply to Richard Lobb

Re: Graph in HTML-Field

by Markus Gafner -

Dear Richard,

sorry for the long delay, i was in holiday the last days.
As I've seen you implemented some functionality to avoid that some results get lost when the test ends by the timeout. Will you release this functionality in the version 4.0 in the next weeks?

Also, I've read your documentation and added some words. I would already mention that it’s possible to include the GraphUI in the HtmlUI. I'll also included the necessary code in the tags <<code>><</code>>. What do you think about it?

When the new functionality will be released, I will test the final implementation, add the example question as one of my last answers in this thread.

Thanks four your help

Markus

The textareaId macro

A problem arises if the HTML supplied by the question author contains elements with explicit id attributes, as might be required if there is also JavaScript present that needs to refer to the new elements. If the review options allow display of the question author's answer then when the student reviews their quiz, the student answer and the author's answer will both include the new elements, resulting in a conflict of id. Apart from being invalid HTML, this is likely to result in wrong results when any JavaScript code referencing the elements runs.

A workaround for this problem is to include the special macro string

___textareaId___

as part of any new ids. Note that there are THREE (3) underscores at both the start and end of the macro string.

When the HTML UI inserts the global extra html into the question, that macro is replaced everywhere by the actual ID of the answer box's text-area, which is different for the student and author answers. This technique can also be used to ensure that the names given to elements like radio buttons are different in the two answers.

Using this macro, it is also possible to include the GraphUI in the HtmlUI. By including a custom grader, it is possible to create a Question with several sub questions. To do this, in the html-code a textarea element needs to be defined:


<textarea class="coderunner-ui-element"
     id="graph_target_name____textareaId___" name="graph_target"
spellcheck="false" rows="18" data-params=""
data-globalextra=""></textarea>

This element is hidden, but at this position, the graph will be drawn. Secondly, the amd-script needs to get called using:

<script>
M.util.js_pending('qtype_coderunner/userinterfacewrapper');
require(['qtype_coderunner/userinterfacewrapper'], function(amd) {
amd.newUiWrapper("graph", "graph_target_name____textareaId___");
M.util.js_complete('qtype_coderunner/userinterfacewrapper');
});
</script>

By using multiple graph elements, keep in mind that the id and name should be unique. For more information, see this CodeRunner author's forum thread where Markus Gafner (who contributed this workaround) shows a HtmlUI question with an embedded GraphUI question, plus other embedded questions.

(Edited by Richard Lobb - original submission Friday, 29 January 2021, 8:54 AM)

(Edited by Richard Lobb - original submission Wednesday, 10 March 2021, 8:35 PM)

(Edited by Richard Lobb - original submission Wednesday, 10 March 2021, 8:40 PM)

In reply to Markus Gafner

Re: Graph in HTML-Field

by Richard Lobb -

Hi Markus

Many thanks for the updated textareaId documentation - that's very helpful. I've incorporated it into the Readme.md for the upcoming release.

Yes, the new version includes code to deal with the bug you encountered with the HTML UI not sync'ing back to the textarea when a quiz times out. Although I have an onsubmit handler for the form, it turns out that a submit event is not fired if a form's submit method is called directly by JavaScript, as it is when a quiz times out. My workaround is to add a sync timer which regularly calls the UI plugin's sync() method to serialise the UI state back into the textarea. I've set the default sync interval to an arbitrary 5 secs, but have provided a UI parameter so that the question author can change this on a per-question basis if required. The number is totally arbitrary and I really have no feeling for what might by appropriate. As your use of the HTML UI shows, it is possible for authors to construct almost arbitrarily complex UIs so the sync overheads could perhaps become significant if called every second? Your thoughts?

For now I've also added the sync_interval_secs UI parameter to the other two UIs that don't automatically keep the textarea in sync: gapfiller UI and table UI. However since the overheads with those are likely to be always small, I might just use fixed time intervals for them. It's easy to add back in again if needed in the future.

Since syncing the UI contents back to the textarea doesn't in turn sync back to the server, there's still an element of risk with relying on quiz time outs for submissions. If, say, a student's laptop battery fails, or the network goes down, all a student's work could be lost. So I prefer to always provide students with at least a precheck button that provides some level of sanity check to the student while also submitting their work to the server.

If you're interested in checking out the intended new version, you could pull the Development branch from github. It's still in pre-release state, but I think it's close to release and I'm about to install it on our production server for this coming academic year. However, the Readme documentation and some of the inline documentation hasn't yet been updated and of course there are still likely to be a few bugs. But I'd certainly be grateful for any feedback.

Regards

Richard