@@ -122,7 +122,32 @@ async function handleWW(ww_id, action) {
122122 formData . set ( "problemUUID" , ww_id ) ;
123123 }
124124
125- $ . post ( url , Object . fromEntries ( formData ) , ( data ) => {
125+ // If in Runestone, check if there are previous answer submissions and get them now to use in the form.
126+ let checkboxesString = '' ;
127+ if ( runestone_logged_in && ! action ) {
128+ const answersObject = ( wwList [ ww_id . replace ( / - w w - r s $ / , '' ) ] . answers ? wwList [ ww_id . replace ( / - w w - r s $ / , '' ) ] . answers : { 'answers' : [ ] , 'mqAnswers' : [ ] } ) ;
129+ const previousAnswers = answersObject . answers ;
130+ if ( previousAnswers !== null ) {
131+ formData . set ( 'WWsubmit' , 1 ) ;
132+ }
133+ for ( const answer in previousAnswers ) {
134+ if ( previousAnswers [ answer ] . constructor === Array ) {
135+ for ( const k in previousAnswers [ answer ] ) {
136+ checkboxesString += '&' ;
137+ checkboxesString += answer ;
138+ checkboxesString += '=' ;
139+ checkboxesString += previousAnswers [ answer ] [ k ] ;
140+ }
141+ } else {
142+ formData . set ( answer , previousAnswers [ answer ] ) ;
143+ }
144+ }
145+ }
146+ // Need to get form data as a string, including possible repeated checkbox names
147+ // Do not pass post data as an object, or checkbox names will overwrite one another
148+ const formString = new URLSearchParams ( formData ) . toString ( ) ;
149+
150+ $ . post ( url , formString + checkboxesString , ( data ) => {
126151 // Create the form that will contain the text and input fields of the interactive problem.
127152 const form = document . createElement ( "form" ) ;
128153 form . id = ww_id + "-form" ;
@@ -185,36 +210,36 @@ async function handleWW(ww_id, action) {
185210 if ( input && input . value == '' ) {
186211 input . setAttribute ( 'value' , answers [ answer ] ) ;
187212 }
188- if ( input && input . type . toUpperCase ( ) == 'RADIO' ) {
189- const buttons = body_div . querySelectorAll ( 'input[name=' + answer + ']' ) ;
190- for ( const button of buttons ) {
191- if ( button . value == answers [ answer ] ) {
192- button . setAttribute ( 'checked' , 'checked' ) ;
193- }
194- }
195- }
196- if ( input && input . type . toUpperCase ( ) == 'CHECKBOX' ) {
197- const checkboxes = body_div . querySelectorAll ( 'input[name=' + answer + ']' ) ;
198- for ( const checkbox of checkboxes ) {
199- // This is not a bulletproof approach if the problem used input values that are weird
200- // For example, with commas in them
201- // However, we are stuck with WW providing answers[answer] as a string like `[value0, value1]`
202- // and note that it is not `["value0", "value1"]`, so we cannot cleanly parse it into an array
203- let checkbox_regex = new RegExp ( '(\\[|, )' + checkbox . value + '(, |\\])' ) ;
204- if ( answers [ answer ] . match ( checkbox_regex ) ) {
205- checkbox . setAttribute ( 'checked' , 'checked' ) ;
206- }
207- }
208- }
209- var select = body_div . querySelector ( 'select[id=' + answer + ']' ) ;
210- if ( select && answers [ answer ] ) {
211- // answers[answer] may be wrapped in \text{...} that we want to remove, since value does not have this.
212- let this_answer = answers [ answer ] ;
213- if ( / ^ \\ t e x t \{ .* \} $ / . test ( this_answer ) ) { this_answer = this_answer . match ( / ^ \\ t e x t \{ ( .* ) \} $ / ) [ 1 ] } ;
214- let quote_escaped_answer = this_answer . replace ( / " / g, '\\"' ) ;
215- const option = body_div . querySelector ( `select[id="${ answer } "] option[value="${ quote_escaped_answer } "]` ) ;
216- if ( option ) { option . setAttribute ( 'selected' , 'selected' ) } ;
217- }
213+ // if (input && input.type.toUpperCase() == 'RADIO') {
214+ // const buttons = body_div.querySelectorAll('input[name=' + answer + ']');
215+ // for (const button of buttons) {
216+ // if (button.value == answers[answer]) {
217+ // button.setAttribute('checked', 'checked');
218+ // }
219+ // }
220+ // }
221+ // if (input && input.type.toUpperCase() == 'CHECKBOX') {
222+ // const checkboxes = body_div.querySelectorAll('input[name=' + answer + ']');
223+ // for (const checkbox of checkboxes) {
224+ // // This is not a bulletproof approach if the problem used input values that are weird
225+ // // For example, with commas in them
226+ // // However, we are stuck with WW providing answers[answer] as a string like `[value0, value1]`
227+ // // and note that it is not `["value0", "value1"]`, so we cannot cleanly parse it into an array
228+ // let checkbox_regex = new RegExp('(\\[|, )' + checkbox.value + '(, |\\])');
229+ // if (answers[answer].match(checkbox_regex)) {
230+ // checkbox.setAttribute('checked', 'checked');
231+ // }
232+ // }
233+ // }
234+ // var select = body_div.querySelector('select[id=' + answer + ']');
235+ // if (select && answers[answer]) {
236+ // // answers[answer] may be wrapped in \text{...} that we want to remove, since value does not have this.
237+ // let this_answer = answers[answer];
238+ // if (/^\\text\{.*\}$/.test(this_answer)) {this_answer = this_answer.match(/^\\text\{(.*)\}$/)[1]};
239+ // let quote_escaped_answer = this_answer.replace(/"/g, '\\"');
240+ // const option = body_div.querySelector(`select[id="${answer}"] option[value="${quote_escaped_answer}"]`);
241+ // if (option) {option.setAttribute('selected', 'selected')};
242+ // }
218243 }
219244 }
220245
@@ -256,10 +281,8 @@ async function handleWW(ww_id, action) {
256281 let buttonContainer = ww_container . querySelector ( '.problem-buttons.webwork' ) ;
257282 // Create the submission buttons if they have not yet been created.
258283 if ( ! buttonContainer ) {
259- // Hide the original div that contains the old make active button.
260- ww_container . querySelector ( '.problem-buttons' ) . classList . add ( 'hidden-content' ) ;
261- // And the newer activate button if it is there
262- if ( activate_button != null ) { activate_button . classList . add ( 'hidden-content' ) ; } ;
284+ // Hide the original div that contains the Activate.
285+ ww_container . querySelector ( '.problem-buttons' ) . classList . add ( 'hidden-content' , 'hidden' ) ;
263286
264287 // Create a new div for the webwork buttons.
265288 buttonContainer = document . createElement ( 'div' ) ;
@@ -278,11 +301,8 @@ async function handleWW(ww_id, action) {
278301 check . style . marginRight = "0.25rem" ;
279302 check . classList . add ( 'webwork-button' ) ;
280303
281- // Adjust if more than one answer to check
282- const answerCount = body_div . querySelectorAll ( "input:not([type=hidden])" ) . length +
283- body_div . querySelectorAll ( "select:not([type=hidden])" ) . length ;
284-
285304 check . textContent = runestone_logged_in ? localize_submit : localize_check_responses ;
305+
286306 check . addEventListener ( 'click' , ( ) => handleWW ( ww_id , "check" ) ) ;
287307
288308 buttonContainer . appendChild ( check ) ;
@@ -429,7 +449,7 @@ async function handleWW(ww_id, action) {
429449 iframe . classList . add ( 'problem-iframe' ) ;
430450
431451 // Hide the static problem
432- ww_container . querySelector ( '.problem-contents' ) . classList . add ( 'hidden-content' ) ;
452+ ww_container . querySelector ( '.problem-contents' ) . classList . add ( 'hidden-content' , 'hidden' ) ;
433453
434454 if ( activate_button != null ) {
435455 // Make sure the iframe follows the activate button in the DOM
@@ -582,12 +602,12 @@ function resetWW(ww_id) {
582602 iframe = ww_container . querySelector ( '.problem-iframe' ) ;
583603 iframe . remove ( ) ;
584604
585- ww_container . querySelector ( '.problem-contents' ) . classList . remove ( 'hidden-content' ) ;
605+ ww_container . querySelector ( '.problem-contents' ) . classList . remove ( 'hidden-content' , 'hidden' ) ;
586606
587607 ww_container . querySelector ( '.problem-buttons.webwork' ) . remove ( ) ;
588- ww_container . querySelector ( '.problem-buttons' ) . classList . remove ( 'hidden-content' ) ;
608+ ww_container . querySelector ( '.problem-buttons' ) . classList . remove ( 'hidden-content' , 'hidden' ) ;
589609 // if the newer activate button is there (but hidden) bring it back too
590- if ( activate_button != null ) { activate_button . classList . remove ( 'hidden-content' ) ; } ;
610+ if ( activate_button != null ) { activate_button . classList . remove ( 'hidden-content' , 'hidden' ) ; } ;
591611}
592612
593613function adjustSrcHrefs ( container , ww_domain ) {
0 commit comments