Using Custom Script for Questions

Using Custom Script for Questions

by Yaniv Cogan -
Number of replies: 19

Hi,
I've noticed that using the HTML tag editor (that can be accessed by the rich-text editor), I'm able to embed JS scripts, and was thus able to create a draw able canvas (I am attaching a .txt file with the code to this post) inside of a 'description' type question (though I guess it might as well have been any other question type).

I was wandering if there is any way I could make this client-side script interface with the Moodle grade system, to create a costume question type.

I have absolutely no knowledge of how the Moodle works, but I guess this would require some PHP?

My fantasy would be to be able to simply be able to refer to built-in functions with names like setAnswer(); from inside the script. This way, I could put my questions in the context of a little JS game, and set the answer to a question according to whether the student win or fail the game.

For example, I could place a screenshot of a Word document (inside the canvas), and have the students mark where they would click to change the font (by simply drawing on the canvas).
There may be a way to do this using some plugin, but given that I have a lot of free time, and would like to make the quizzes as diverse and interactive as possible, I would much rather to have a general solution that will allow me to program a question behavior without having to learn actual Moodle-plugin development (unless that is really straight forward to server-side beginners!)

The context for this is that we already plan to use games as a framing for some of the quizzes (which we use more to fill the role of an exercise than that of an exam) we give, and we would love to be able to integrate the scores the students get in these games into the same system which stores the scores for our "regular" quizzes*.


This is almost certainly not practical, but if there is any plugin or method to achieve something close to this, I'd love to hear about it.

Sorry for rambling, and thanks for taking your time to read!
     -Yaniv

*Again, these quizzes are used as a more interactive form of an exercise - we wouldn't mix together the scores of straight-up exams and those achieved in a game, since the game also tests skills unrelated to the subject at hand.

Average of ratings: -
In reply to Yaniv Cogan

Re: Using Custom Script for Questions

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

For the word document example you give, you could just use a screen-grab of the document, and make a drag-drop markers question types.

For other examples, rather than making an Ajax call to the server, a better approach is to use hidden form fields to transmit the data when the page is submitted.

If fact, you could use a standard Moodle short-answer or Cloze question. Just get the JavaScript to convert the usual input type=text into an input type=hidden, and display an alternate user interface for creating the response.

Average of ratings: Useful (1)
In reply to Tim Hunt

Re: Using Custom Script for Questions

by Yaniv Cogan -

Thanks, Tim!
Seems like this is a very elegant solution.

I've been trying to do as you suggested (using a short-answer rather than a Cloze), and came short (probably due to my own shortcomings in navigation the DOM, rather than because of any flaw in the method you suggested).

For now - I've only tried to set the input type to hidden, and alter the "Answer: " label. I did that by writing into the Question Content field (while in the HTML editor) the following code:

<script>
document.getElementById("q1501:1_answer").type="hidden";
document.getElementById("yui_3_17_2_2_1465305183720_296").innerHTML="answer here";</script>


which had no effect, as far as I can tell.
I got the IDs by navigating the HTML elements with the Chrome DOM inspector.

Am I supposed to access the input field in some other way?

Thanks again,
      -Yaniv

In reply to Yaniv Cogan

Re: Using Custom Script for Questions

by Yaniv Cogan -

Oh, it seems that the ID of the answer input field changes each time I try to preview the question (goes up by one, so what was once "q1501:1_answer" becomes "q1505:1_answer after 4 previews).

So how would one (and specifically, I) go about changing the input type to "hidden"?

Thanks,
     -Yaniv

In reply to Yaniv Cogan

Re: Using Custom Script for Questions

by Marcus Green -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers

That number refers to the question attempt rather than the field. So to break down the id you can think of it as q for question 1501 as the question attempt, the  1 after : as the id of the field and _answer as identifying the type of field. Once you know that you should be able to parse to identify what is an input field and poke in the html to make a field hidden. This diagram may help understand what is going on.

https://docs.moodle.org/dev/Question_Engine_2:Design

When you preview a question the current data is for the question attempt rather than the question type.


In reply to Marcus Green

Re: Using Custom Script for Questions

by Yaniv Cogan -

Hi,
I'm not sure I understand exactly. Is it possible for me to know the question attempt number?
I tried using the ID that would match my next try (so, if when using the DOM explorer I found the id of the input to be q1519:1_answer, I would make the getElementById use the id q1520:1_answer) - but that still turned out as null.

If there is another way to access the input element (without using getElementById), or if you could explain a little further on what that diagram (thanks for that!) means practically for what I'm trying to do I'll be grateful.

I thought maybe I should use getElementByID on the entire form (which has a static id - responseform), and then get the form elements and access the input that way.

Thanks for sticking with me and helping out!

In reply to Yaniv Cogan

Re: Using Custom Script for Questions

by Marcus Green -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers

We may be talking at cross purposes slightly because my knowledge is based on writing PHP for question types which means I can get the details of the question attempt. You by contrast are using Javascript where you don't have direct access to this. 

I was assuming you would somehow traverse the text searching for entry fields(may be with a regular expression), that contained q[0-9]:[0-9]_answer. Put the results in an array loop through using your standard getElementById. (that is not a proper reg ex by the way).


Marcus


In reply to Yaniv Cogan

Re: Using Custom Script for Questions

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Don't make any assumptions about the id. Just find the <input type="text"> inside the <div class="formulation"> that wraps around the question text.

Average of ratings: Useful (1)
In reply to Tim Hunt

Re: Using Custom Script for Questions

by Yaniv Cogan -

The input inside the formulation div is already in type="hidden".

(the black text is Hebrew, you can ignore it)

Changing the type back to "text" just adds another input field with the value "1" inside.
Are you sure I'm not supposed to turn the the input inside the span "answer" to type "hidden"?

In reply to Yaniv Cogan

Re: Using Custom Script for Questions

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

As you highlight, there are two input's inside the div. the sequencecheck one is internal to the question system. You should leave it alone. The other one is the one that receives the student's reponse. That is the one you want to work with.

Average of ratings: Useful (1)
In reply to Tim Hunt

Re: Using Custom Script for Questions

by Yaniv Cogan -

Thanks.
There seems to be some a-synchronous thing going on, so I had to use setTimeout before accessing that input field. Full code if anyone is interested:

<script>


var input;

setTimeout(function(){
input=document.getElementsByClassName("ablock").item(0).querySelectorAll("input").item(0);
//hide the entire div so that the "answer:" label won't show up.
document.getElementsByClassName("ablock").item(0).visibility="hidden";
//hide input field
input.type="hidden";
}, 50);

function setAns (does)
{
if (does)
input.value="correct";
else
input.value="wrong";
}

</script>

In reply to Yaniv Cogan

Re: Using Custom Script for Questions

by Marcus Green -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers

I like your ambition Yaniv, as Tim suggests, have a look at the ddmarker question type and let us know what you think.

In reply to Marcus Green

Re: Using Custom Script for Questions

by Yaniv Cogan -

I'll be sure to do that! It has been on our shortlist of plugins to install for quite a while.

In reply to Yaniv Cogan

Re: Using Custom Script for Questions

by Marcus Green -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers

It started shipping as a core module from Moodle 3.0 but it has the pedigree of being an OU plugin and has been around for a long time.  The tricky bit for Joe Q ordinary teacher is working out the x:y coordinates for the drop areas.

In reply to Marcus Green

Re: Using Custom Script for Questions

by Yaniv Cogan -

We currently work on Moodle 2.9, but we are considering updating to the up-to-date version, and are currently looking into what that means in terms of content potentially being no longer compatible.

Thankfully, we work in a system in which we have a few "content creators", who are in charge of creating, among other things, the quizzes themselves.
This way we can spend a lot of time and effort on a small amount of content, and polish it as much as we want. Then these bits of content are made available for all the teachers as tools to use and embed in the lesson plan (that is largely up to them).
All of this is to say - your system seems perfect for this type of questions, and we won't have any problem with the X Y system.

I would still like to have a more general solution for cases where none of the included question types fit what we want, and Tim's suggestion seems to be great in that case, if I can just get it to work... smile

 


In reply to Yaniv Cogan

Re: Using Custom Script for Questions

by Yaniv Cogan -

In continuation to this question - is there any possible way to integrate images into the script?
With the Moodle using CAS is it possible to address any image by path? If so - do I need to have direct access to the file directories in order to upload the images in a retrievable manner?

Thanks!

In reply to Yaniv Cogan

Re: Using Custom Script for Questions

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

It depends what you are trying to do with the images. Do you know how Moodle handles images in the question text (for example)?

In reply to Tim Hunt

Re: Using Custom Script for Questions

by Yaniv Cogan -

Hmm, I don't want to display them as image elements directly in the document body, but rather load them and draw them on a 2d canvas element.

I've recently made an alternative visual representation for the Questionnaire plugin (using the method you've suggested - hiding the actual UI and replacing it with a custom one, and then feeding the chosen answer back to the invisible

ezgif-2286308978.gif


The entire is painted on a canvas (easier for me than managing css layers and absolute position). In this example, if I could load images through the script, I could make the arrows behind the smiley-marker clearer and more stylized.


I have no idea how Moodle handles images that are embedded in a question, I'll be sure to take a look.

In reply to Yaniv Cogan

Re: Using Custom Script for Questions

by Yaniv Cogan -

Sorry, the path to that GIF has been broken. Here it is:
http://imgur.com/90YUCTz

In reply to Yaniv Cogan

Re: Using Custom Script for Questions

by Yaniv Cogan -
OK, made it! I just used the same method as before - added the images to the document, gave them an ID and hid them, and then accessed them through javascript:



I would guess that generally speaking, this method of changing the UI is frowned upon? I personally find it easier (because I have no familiarity with the core Moodle code, or PHP), but it is admittedly very roundabout.

If anyone is interested in achieving the same result regardless of the way there not being very elegant, I will gladly post the code once I'm done developing it.