WeBWorK Problems

Creating drag-and-drop, fill-in-the-blank questions

by Paul Pearson -
Number of replies: 0
Hi all,

Inspired by Davide Cervone's "draggableProof.pl" macro, I would like to make a macro for drag-and-drop, fill-in-the-blank questions in webwork.  But, I need some help.  I have made some partial forward progress in two directions: (1) using jQuery and (2) using html5.

1. One avenue that seems promising is to use jQuery.  Here's a minimal working example on jsfiddle: http://jsfiddle.net/e97nug2a/1/  When I try to implement this example in webwork (see inline file FillInTheBlank_jQuery_01.pg below my signature), I am not getting the desired result.  In particular, the chemical formula for water (written as "H_2 O" using MathJax) is not draggable.  So, the main problem I have yet to solve with this approach is how to actually implement working jQuery code for drag-and-drop in a webwork problem.  If we could get drag-and-drop to work, then we would also need to figure out answer checking and persistence of state between answer submissions (i.e., using html hidden input fields to make sure that the problem appears the same before and after "submit answers" is clicked).

2. Another avenue I have explored is to use html5.  When I try to implement it in webwork (see inline file FillInTheBlank_html5_01.pg below my signature), I am able to get drag-and-drop to work.  However, I have not yet figured out how to get the answer string from answer blank and then pass the answer string to the answer checker.  If we could figure out answer checking, then we would also need to address persistence of state between answer submissions.
Is there anyone out there in mathmagic land who would be interested in helping me?  Are there better ways to do this?

Paul Pearson

#########################################################
#  FillInTheBlank_jQuery_01.pg

DOCUMENT();

"PGstandard.pl",
"PGML.pl",
"PGchoicemacros.pl",
"HopeStats.pl",
"PGcourse.pl"
);
TEXT(beginproblem());

Context('Numeric');

qq!
<script>
~~$("input").droppable({ drop: function(event, ui) { alert(ui.draggable.text()); } }); ~~$("span").draggable();
</script>
!);

$water = MODES(TeX=>'',HTML=>'<span">$$H_2 O$$</span>'); BEGIN_TEXT$water
$PAR Jack and Jill went up the hill to fetch a pail of \{ ans_rule(20) \} END_TEXT ENDDOCUMENT(); ########################################################## # FillInTheBlank_html5_01.pg DOCUMENT(); loadMacros( "PGstandard.pl", "PGML.pl", "PGchoicemacros.pl", "HopeStats.pl", "PGcourse.pl" ); TEXT(beginproblem()); Context('Numeric'); HEADER_TEXT( qq! <style> .draggableText {background-color:#ffffff;margin:5px;padding:3px;} #FillInTheBlank0 {float:left; min-width:100px; min-height:35px; margin:10px;padding:10px;border:1px solid #aaaaaa;background-color:#efefef;} #FillInTheBlank1, #FillInTheBlank2 {display:inline-block;min-width:50px; min-height:25px; margin:0px;padding:0px;border:1px solid #aaaaaa;} </style> <script> function allowDrop(ev) { ev.preventDefault(); } function drag(ev) { ev.dataTransfer.setData("text", ev.target.id); } function drop(ev) { ev.preventDefault(); var data = ev.dataTransfer.getData("text"); ev.target.appendChild(document.getElementById(data)); } </script> ! );$ans1 = "hill (and over the vale)";
$ans2 = "$$H_2 O$$";$distractor1 = "milk";

$choices = MODES(TeX=>'',HTML=>qq( <div id="FillInTheBlank0" ondrop="drop(event)" ondragover="allowDrop(event)"> <span class="draggableText" draggable="true" ondragstart="drag(event)" id="drag1">$ans1</span>
<span class="draggableText" draggable="true" ondragstart="drag(event)" id="drag2">$ans2</span> <span class="draggableText" draggable="true" ondragstart="drag(event)" id="drag3">$distractor1</span>
</div>
<br clear="all" />
));

$ansblank1 = MODES(TeX=>'',HTML=>qq(<div id="FillInTheBlank1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>));$ansblank2 = MODES(TeX=>'',HTML=>qq(<div id="FillInTheBlank2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>));

BEGIN_TEXT
$choices Jack and Jill went up the$ansblank1 to fetch a pail of \$ansblank2.
END_TEXT

ENDDOCUMENT();

#####################################################