Hi everyone,

Is it possible to include something like the equation preview box that's available on STACK qtypes (like below) in a normal numerical qtype?

And if yes, how would we do it?

Thanks

Andrew

This discussion has been locked because a year has elapsed since the last post. Please start a new discussion topic.

Hi everyone,

Is it possible to include something like the equation preview box that's available on STACK qtypes (like below) in a normal numerical qtype?

And if yes, how would we do it?

Thanks

Andrew

Of course you can do it. The STACK question type is just PHP code + JavaScript, the same as the rest of Moodle. You just need to add similar code to the numerical question type.

However, what purpose would the preview serve?

Thanks Tim,

I should have said shortanswer (not numerical) questions where we're asking for 2^2 or 1/2 (not sure if this is best practice but it's how we started). We are primarily looking to have a clearer visual way for learners to see what they entering when entering fractions and exponents.

Was thinking of this option for 2 reasons:

- We haven't managed to get STACK to work yet due to something going wonky on our local server - hoping it'll get fixed on next upgrade.
- Even if we did, we have built loads and loads of SA questions over the last few years.

Thanks

Andrew

Andrew,

If you have lots of SA questions which are really mathematics, perhaps one solution would be to write a short script to auto-convert them into a basic STACK question? I'm sure that would be possible, would solve the problem and would give the possibility of much better feedback available through STACK.

How many questions are you talking about?

Chris

Hi Chris,

Thanks for the suggestion. It's quite few, I think we've got around 14 000 questions. Mostly a mix of Short answer and numerical (and some MC).

Happy to hear suggestions.

Andrew

Gosh Andrew,

That is a lot! Well, in this case it probably is worth while in investing time to create an auto-conversion tool. If you'd like to discuss this further, perhaps we could email off the list and then post an update if we decide to do something? It sounds like you have a special case which I'd be happy to talk about further. (C.J.Sangwin@ed.ac.uk)

Chris

Hi Andrew,

You could do this in javascript alone if you are using MathJax to render the expressions. You would need to use a selector to find changes in the value of the textbox and then use the MathJax API to insert or update a tex or asciimath expression next to that box. You will also need to have a mechanism to control when it is used assuming that there are short answers that are not mathematical on the site. (Generico filter should work)

I did something like this to add the mathslate editor to questions using a filter some time ago. You may also find looking at it helpful.

Daniel

Thanks Daniel, much appreciated.

Hello Andrew,

I have an update of the configuration that we discussed offline. This should be placed in the header.

<script>The results should look like this

window.MathJax = {

AuthorInit: function() {

MathJax.Hub.Register.StartupHook('End', function() {

MathJax.Hub.processSectionDelay = 0;

var questions = document.getElementsByClassName('shortanswer');

for (var i = 0; i < questions.length; i++) {

var preview = document.createElement('span');

preview.setAttribute('class', 'filter_mathjaxloader_equation');

var source = questions[i]

.getElementsByClassName('answer')[0]

.getElementsByTagName('input')[0];

preview.innerHTML = ' `' + source.value + '`';

source.parentNode.appendChild(preview);

MathJax.Hub.Queue(['Typeset', MathJax.Hub, preview]);

source.addEventListener('input', function() {

var math = MathJax.Hub.getAllJax(preview)[0];

MathJax.Hub.Queue(['Text', math, source.value]);

});

}

});

}

}

</script>

if you have Asciimath configured through MathJax correctly.

Daniel

Andrew,

Here is an updated version that also handles embedded short answer and embedded numberical questions. Other question types can be used by modifying the selector.

<script>

window.MathJax = {

AuthorInit: function() {

MathJax.Hub.Register.StartupHook('End', function() {

var preview = document.createElement('span');

preview.setAttribute('class', 'filter_mathjaxloader_equation')

preview.innerHTML = ' ``';

MathJax.Hub.processSectionDelay = 0;

MathJax.Hub.Queue(['Typeset', MathJax.Hub, preview]);

var questions = document.querySelectorAll('.subquestion, .shortanswer .answer');

for (var i = 0; i < questions.length; i++) {

var source = questions[i]

.getElementsByTagName('input')[0];

if (source.getAttribute('type') === 'text') {

source.parentNode.appendChild(preview.cloneNode(true));

MathJax.Hub.Queue(['Typeset', MathJax.Hub, source.nextSibling]);

source.addEventListener('input', function() {

var math = MathJax.Hub.getAllJax(this.nextSibling)[0];

MathJax.Hub.Queue(['Text', math, this.value]);

});

}

}

});

}

}

</script>

Andrew,

Here is another fix that takes care of the MC bug. It is better to post responses here rather than PM so that others understand the thread later.

<script> window.MathJax = { AuthorInit: function() { MathJax.Hub.Register.StartupHook('End', function() { var preview = document.createElement('span'); preview.setAttribute('class', 'filter_mathjaxloader_equation') preview.innerHTML = ' ``'; MathJax.Hub.processSectionDelay = 0; MathJax.Hub.Queue(['Typeset', MathJax.Hub, preview]); var inputs = document.querySelectorAll('.subquestion input, .shortanswer .answer input'); for (var i = 0; i < inputs.length; i++) { var source = inputs[i]; if (source.getAttribute('type') === 'text') { source.parentNode.appendChild(preview.cloneNode(true)); MathJax.Hub.Queue(['Typeset', MathJax.Hub, source.nextSibling]); source.addEventListener('input', function() { var math = MathJax.Hub.getAllJax(this.nextSibling)[0]; MathJax.Hub.Queue(['Text', math, this.value]); }); } } }); } } </script>

This is so GREAT! Thank you Daniel for all your help with this. Deeply appreciated.

It works perfectly and our learners are already enjoying the benefits.

Hi Daniel,

Firstly, this is working so well for us. Thank you again.

Secondly, I wanted ask something. When we have the question behaviour set to "interactive with multiple tries" and the student gets their first attempt wrong, it no longer renders the equation on the second attempt.

Do you have any suggestions for how to overcome this?

Many thanks

Andrew

I have not been able to reproduce this. Can you turn on the browser console and see if an error is reported?

Oh, I am getting a few error notices. Would it be one of the below?

Thanks

Andrew

It looks like you have a security program called Rapport installed on your client that is blocking MathJax because it thinks it is a cross site scripting threat.

Its not Rapport, also happening with me Daniel.

Uncaught Error: Can't make callback from given data

at USING (cdn.mathjax.org/mathjax/latest/MathJax.js?delayStartupUntil=configured:19)

at Object.Push (cdn.mathjax.org/mathjax/latest/MathJax.js?delayStartupUntil=configured:19)

at Object.Queue (cdn.mathjax.org/mathjax/latest/MathJax.js?delayStartupUntil=configured:19)

at HTMLInputElement.<anonymous> (attempt.php:39)

Seems if the textbox has a value at 'second try' - the renderer is not able to point to the HTML input box?

Are you loading MathJax in the header or are you using the Moodle MathJax filter?

Andrew and I found that certain review options change the DOM structure so I had to update the script

<script> window.MathJax = { AuthorInit: function() { MathJax.Hub.Register.StartupHook('End', function() { var preview = document.createElement('span'); preview.setAttribute('class', 'filter_mathjaxloader_equation') preview.innerHTML = ' ``'; MathJax.Hub.processSectionDelay = 0; MathJax.Hub.Queue(['Typeset', MathJax.Hub, preview]); var inputs = document.querySelectorAll('.subquestion input, .shortanswer .answer input'); for (var i = 0; i < inputs.length; i++) { var source = inputs[i]; if (source.getAttribute('type') === 'text') { source.parentNode.appendChild(preview.cloneNode(true)); MathJax.Hub.Queue(['Typeset', MathJax.Hub, source.parentNode.lastChild]);

source.parentNode.lastChild.innerHTML = '`' + source.value + '`'; source.addEventListener('input', function() { var math = MathJax.Hub.getAllJax(this.parentNode)[0]; MathJax.Hub.Queue(['Text', math, this.value]); }); } } }); } } </script>