maths / moodle-qtype_stack

Stack question type for Moodle
GNU General Public License v3.0
138 stars 147 forks source link

Setting Input value from STACK-JS does not work with Equivalence Reasoning inputs #1123

Closed bgailer closed 4 months ago

bgailer commented 4 months ago

We have a question using equivalence reasoning. The question consists of two parts with the second part only getting displayed when the first part is answered correctly (we use stack_js.toggle_visibility(id, true) for that). In the second part we have a syntax hint in the equivalence reasoning input. Due to this hint, when students check their answer for the first part multiple times, the second input is marked as partially correct when getting displayed.

In order to avoid this, we decided to use STACK-JS to write the first line of input2 ([[input:ans2]]) from the feedback of input1 like this:

[[javascript]]
stack_js.request_access_to_input("ans2", true).then(id => {
const input = document.getElementById(id);
input.value = "(-5*%i)^2+25";
input.dispatchEvent(new Event('change'));
});
[[/javascript]]

This does not work however and the console shows the error message Uncaught (in promise) No response to input registration of "ans2" in 5s. When testing the same code with a numeric input, everything works fine. The issue seems to be the input of type equivalence reasoning. Maybe this is because this input is a html textbox instead of an input element like most other input types?

sangwinc commented 4 months ago

Yes, the equivalence reasoning is a html textbox not an input element.

Could you resolve this with the [[reveal]] block? https://docs.stack-assessment.org/en/Authoring/Question_blocks/Dynamic_blocks/#reveal-block We're really not keen on supporting ad-hoc javascript! Chris

aharjula commented 4 months ago

It is indeed a current limitation of STACK-JS that it does not allow targeting of textareas, but it really has no reason why not to do so. Maybe I'll manage to add that feature before the conference. The example you have would be the way it should work, as the STACK-JS input logic always creates an <input type="hidden"> on the IFRAME side even when the other end could be an MCQ-input of some sort; it would then also do that for a textarea.

Chris, ad-hoc JavaScript is a very different thing than using [[javascript]] and STACK-JS with it, the latter being something we really want to support to get rid of the former.

sangwinc commented 4 months ago

Thanks @aharjula, so adding this to textareas is the way to go!

aharjula commented 4 months ago

Accessing text-areas should now work in the next release...

As to the original bit of code, just to point out that these are equivalent:

[[javascript]]
stack_js.request_access_to_input("ans2", true).then(id => {
const input = document.getElementById(id);
input.value = "(-5*%i)^2+25";
input.dispatchEvent(new Event('change'));
});
[[/javascript]]

that could be written like this:

[[javascript input-ref-ans2="id"]]
const input = document.getElementById(id);
input.value = "(-5*%i)^2+25";
input.dispatchEvent(new Event('change'));
[[/javascript]]

Asking for access to inputs is so common that we have special syntax for that so that one does not need to know how to write callbacks for promises. There is one use case where the former is required, though, and that is if the relevant input is not always the same as you cannot inject the name of the input to that input-ref-attribute, but you sure can do so with the JavaScript.