@@ -103,28 +103,28 @@ define(function () {
103103 $ . get ( superClient . webContentFolder + assets . controls , function ( controls ) {
104104 $ ( '#oli-embed' ) . append ( controls ) ;
105105 $ ( "#save_btn" ) . click ( function ( ) {
106- if ( ! superClient . isCurrentAttemptCompleted ( ) && questionsSaveData . numberOfQuestionsAnswered ( ) < 1 ) {
106+ if ( ! superClient . isCurrentAttemptCompleted ( ) && questionsSaveData . numberOfQuestionsAnswered ( ) < 1 && ! $ ( '#save_btn' ) . hasClass ( 'disabled' ) ) {
107107 activityEmbed . save ( ) ;
108108 }
109109 } ) ;
110110 $ ( "#submit_btn" ) . click ( function ( ) {
111- if ( ! superClient . isCurrentAttemptCompleted ( ) && questionsSaveData . numberOfQuestionsAnswered ( ) < 1 ) {
111+ if ( ! superClient . isCurrentAttemptCompleted ( ) && questionsSaveData . numberOfQuestionsAnswered ( ) < 1 && ! $ ( '#submit_btn' ) . hasClass ( 'disabled' ) ) {
112112 activityEmbed . submit ( ) ;
113113 }
114114 } ) ;
115115 $ ( "#hint_btn" ) . click ( function ( ) {
116- if ( ! superClient . isCurrentAttemptCompleted ( )
116+ if ( ! superClient . isCurrentAttemptCompleted ( ) && ! $ ( '#hint_btn' ) . hasClass ( 'disabled' )
117117 && typeof ( currentPart ) === "undefined" || currentPart === null || currentPart . getHints ( ) . length > 0 ) {
118118 activityEmbed . hint ( ) ;
119119 }
120120 } ) ;
121121 $ ( "#next_btn" ) . click ( function ( ) {
122- if ( superClient . isCurrentAttemptCompleted ( ) ) {
122+ if ( superClient . isCurrentAttemptCompleted ( ) && ! $ ( '#next_btn' ) . hasClass ( 'disabled' ) ) {
123123 activityEmbed . nextAttempt ( ) ;
124124 }
125125 } ) ;
126126 $ ( "#solution_btn" ) . click ( function ( ) {
127- if ( superClient . isCurrentAttemptCompleted ( ) || activityEmbed . isUngradedActivity ( ) ) {
127+ if ( ( superClient . isCurrentAttemptCompleted ( ) || activityEmbed . isUngradedActivity ( ) ) && ! $ ( '#solution_btn' ) . hasClass ( 'disabled' ) ) {
128128 $ . get ( superClient . webContentFolder + assets . solutions , function ( data ) {
129129 var solutionText = null ;
130130 $ ( data ) . find ( "solution" ) . each ( function ( q ) {
@@ -156,7 +156,13 @@ define(function () {
156156 } ) ;
157157
158158 $ ( "#run" ) . click ( function ( ) {
159- if ( ! superClient . isCurrentAttemptCompleted ( ) ) {
159+ if ( ! superClient . isCurrentAttemptCompleted ( ) && ! $ ( '#run' ) . hasClass ( 'disabled' ) ) {
160+ activityEmbed . run ( ) ;
161+ }
162+ } ) ;
163+
164+ $ ( "#submit" ) . click ( function ( ) {
165+ if ( ! superClient . isCurrentAttemptCompleted ( ) && ! $ ( '#submit' ) . hasClass ( 'disabled' ) ) {
160166 var edit_text = ActivityEmbed . editor . getValue ( ) ;
161167 activityEmbed . pushInput ( edit_text ) ;
162168
@@ -170,7 +176,7 @@ define(function () {
170176 } ) ;
171177
172178 $ ( "#clear" ) . click ( function ( ) {
173- if ( ! superClient . isCurrentAttemptCompleted ( ) ) {
179+ if ( ! superClient . isCurrentAttemptCompleted ( ) && ! $ ( '#clear' ) . hasClass ( 'disabled' ) ) {
174180 ActivityEmbed . repl . clearScreen ( ) ;
175181 ActivityEmbed . repl . writeStdin ( '\n' ) ;
176182 ActivityEmbed . repl . disableStdin ( false ) ;
@@ -247,6 +253,8 @@ define(function () {
247253 if ( superClient . isCurrentAttemptCompleted ( ) ) {
248254 ActivityEmbed . repl . disableStdin ( ) ;
249255 ActivityEmbed . repl . disableStdout ( ) ;
256+
257+ $ ( '#oli-embed .question' ) . append ( '<p>This activity has been submitted. Click Reset to try again.</p>' ) ;
250258 }
251259
252260 ActivityEmbed . repl . attach ( document . getElementById ( 'console' ) ) ;
@@ -380,6 +388,9 @@ define(function () {
380388
381389 // restore content to editor
382390 initEditorText = input . value ;
391+ if ( ActivityEmbed . editor ) {
392+ ActivityEmbed . editor . setValue ( initEditorText ) ;
393+ }
383394
384395 // write previous input/output content
385396 ActivityEmbed . repl . on ( 'afterconnect' , ( ) => {
@@ -405,8 +416,8 @@ define(function () {
405416 $ ( '#save_btn' ) . addClass ( 'disabled' ) ;
406417 $ ( '#submit_btn' ) . addClass ( 'disabled' ) ;
407418 $ ( '#run' ) . addClass ( 'disabled' ) ;
419+ $ ( '#submit' ) . addClass ( 'disabled' ) ;
408420 $ ( '#clear' ) . addClass ( 'disabled' ) ;
409- $ ( '#hint_btn' ) . addClass ( 'disabled' ) ;
410421
411422 $ ( '#next_btn' ) . removeClass ( 'disabled' ) ;
412423 $ ( "#solution_btn" ) . removeClass ( 'disabled' ) ;
@@ -418,16 +429,18 @@ define(function () {
418429 $ ( '#save_btn' ) . addClass ( 'disabled' ) ;
419430 $ ( '#submit_btn' ) . addClass ( 'disabled' ) ;
420431 }
421- if ( typeof ( currentPart ) === "undefined" || currentPart === null || currentPart . getHints ( ) . length === 0 ) {
422- $ ( '#hint_btn' ) . addClass ( 'disabled' ) ;
423- } else {
424- $ ( '#hint_btn' ) . removeClass ( 'disabled' ) ;
425- }
426432 $ ( '#next_btn' ) . addClass ( 'disabled' ) ;
427433 $ ( '#run' ) . removeClass ( 'disabled' ) ;
434+ $ ( '#submit' ) . removeClass ( 'disabled' ) ;
428435 $ ( '#clear' ) . removeClass ( 'disabled' ) ;
429436 }
430- if ( Number ( superClient . currentAttempt ) > 1 || activityEmbed . isUngradedActivity ( ) ) {
437+
438+ if ( typeof ( currentPart ) === "undefined" || currentPart === null || currentPart . getHints ( ) . length === 0 ) {
439+ $ ( '#hint_btn' ) . addClass ( 'disabled' ) ;
440+ } else {
441+ $ ( '#hint_btn' ) . removeClass ( 'disabled' ) ;
442+ }
443+ if ( superClient . isCurrentAttemptCompleted ( ) || activityEmbed . isUngradedActivity ( ) ) {
431444 $ ( "#solution_btn" ) . removeClass ( 'disabled' ) ;
432445 } else {
433446 $ ( "#solution_btn" ) . addClass ( 'disabled' ) ;
@@ -456,16 +469,92 @@ define(function () {
456469 superClient . logAction ( action ) ;
457470
458471 } ;
472+ // Run the code in the editor without submitting for a score
473+ this . run = function ( ) {
474+ console . log ( "run()" ) ;
475+
476+ // disable run button
477+ $ ( '#run' ) . addClass ( 'disabled' ) ;
478+ $ ( '#run' ) . text ( 'Running...' ) ;
479+
480+ // clear out previous feedback
481+ $ ( '#' + currentQuestion . getId ( ) + '_feedback' ) . empty ( ) ;
482+ $ ( '#' + currentQuestion . getId ( ) + '_feedback' ) . removeAttr ( "style" ) ;
483+
484+ // clear console and disable further input
485+ code = ActivityEmbed . editor . getValue ( ) ;
486+ ActivityEmbed . repl . clearScreen ( ) ;
487+ ActivityEmbed . repl . writeln ( 'EXECUTING CODE:' ) ;
488+ ActivityEmbed . repl . writeln ( code ) ;
489+ ActivityEmbed . repl . write ( '\n' ) ;
490+ ActivityEmbed . repl . disableStdin ( ) ;
491+
492+ return ReplClient . exec ( code , { host : 'repl.oli.cmu.edu' , language : 'python3' } )
493+ . then ( function ( response ) {
494+ console . log ( "Ouput from ReplClient.exec " + JSON . stringify ( response ) ) ;
495+ ActivityEmbed . repl . writeln ( '---------------------------------------' ) ;
496+ ActivityEmbed . repl . writeln ( 'RESULT:' ) ;
497+ ActivityEmbed . repl . write ( response . result ) ;
498+
499+ // check if there was a question and part to process. If not, then this is treated as
500+ // an ungraded activity, so simply return
501+ if ( activityEmbed . isUngradedActivity ( ) ) {
502+ console . log ( "currentQuestion or currentPart not set" ) ;
503+ return ;
504+ }
505+
506+ // Only score attempt if at least 1 question has been answered
507+ if ( questionsSaveData . numberOfQuestionsAnswered ( ) < 1 ) {
508+ console . log ( "scoreAttempt() no questions answered " ) ;
509+ return ;
510+ }
511+
512+ if ( ! ( response . error ) ) {
513+ console . log ( "No error from ReplClient.exec" ) ;
514+
515+ var feedback = "Execution succeeded: Code is well formated" ;
516+ $ ( '#' + currentQuestion . getId ( ) + '_feedback' ) . append ( '<div style="display: inline-block;">' + feedback + '</div>' ) ;
517+ var styles = {
518+ background : '#ddffdd' ,
519+ borderColor : '#33aa33' ,
520+ display : 'block'
521+ } ;
522+ $ ( '#' + currentQuestion . getId ( ) + '_feedback' ) . css ( styles ) ;
523+ } else {
524+ var feedback = "Execution failed. Check the console output and your code for errors" ;
525+ $ ( '#' + currentQuestion . getId ( ) + '_feedback' ) . append ( '<div style="display: inline-block;">' + feedback + '</div>' ) ;
526+ var styles = {
527+ background : '#f4cfc9' ,
528+ borderColor : '#e75d36' ,
529+ display : 'block'
530+ } ;
531+ $ ( '#' + currentQuestion . getId ( ) + '_feedback' ) . css ( styles ) ;
532+ }
533+
534+ return response ;
535+ } )
536+ . catch ( function ( err ) {
537+ console . error ( err ) ;
538+ ActivityEmbed . repl . writeln ( "An unexpected error occurred: " + err ) ;
539+ ActivityEmbed . repl . writeln ( 'Please try reloading the page or contact support if the issue persists' ) ;
540+ } )
541+ . finally ( function ( ) {
542+ $ ( '#run' ) . removeClass ( 'disabled' ) ;
543+ $ ( '#run' ) . text ( 'Run' ) ;
544+ } ) ;
545+ } ;
546+ // Run the code in the editor and submit for a scoring
459547 this . submit = function ( ) {
460548 console . log ( "submit()" ) ;
461- if ( superClient . isCurrentAttemptCompleted ( ) ) {
462- return ;
463- }
464549
465- ActivityEmbed . repl . disableStdin ( ) ;
466- return activityEmbed . process ( ) ;
467- } ;
468- this . process = function ( ) {
550+ // disable run button
551+ $ ( '#submit' ) . addClass ( 'disabled' ) ;
552+ $ ( '#submit' ) . text ( 'Submitting...' ) ;
553+
554+ // clear out previous feedback
555+ $ ( '#' + currentQuestion . getId ( ) + '_feedback' ) . empty ( ) ;
556+ $ ( '#' + currentQuestion . getId ( ) + '_feedback' ) . removeAttr ( "style" ) ;
557+
469558 var questionData ;
470559 var partData ;
471560 var code ;
@@ -477,10 +566,17 @@ define(function () {
477566 code = partData . getInput ( ) . value
478567 }
479568
569+ ActivityEmbed . repl . clearScreen ( ) ;
570+ ActivityEmbed . repl . writeln ( 'EXECUTING CODE:' ) ;
571+ ActivityEmbed . repl . writeln ( code ) ;
572+ ActivityEmbed . repl . write ( '\n' ) ;
573+ ActivityEmbed . repl . disableStdin ( ) ;
574+
480575 return ReplClient . exec ( code , { host : 'repl.oli.cmu.edu' , language : 'python3' } )
481576 . then ( function ( response ) {
482577 console . log ( "Ouput from ReplClient.exec " + JSON . stringify ( response ) ) ;
483578 ActivityEmbed . repl . writeln ( '---------------------------------------' ) ;
579+ ActivityEmbed . repl . writeln ( 'RESULT:' ) ;
484580 ActivityEmbed . repl . write ( response . result ) ;
485581
486582 // check if there was a question and part to process. If not, then this is treated as
@@ -510,7 +606,7 @@ define(function () {
510606 }
511607 }
512608 } else {
513- var feedback = { id : "replt_eval" , content : "Correct: code is well formated" } ;
609+ var feedback = { id : "replt_eval" , content : "Execution succeeded: Code is well formated" } ;
514610 partData . setFeedback ( feedback ) ;
515611 partData . setScore ( Number ( 10 ) ) ;
516612 partData . setCorrect ( true ) ;
@@ -539,13 +635,19 @@ define(function () {
539635
540636 activityEmbed . saveDataAndScore ( ) ;
541637 }
638+
639+ $ ( '#oli-embed .question' ) . append ( '<p>This activity has been submitted. Click Reset to try again.</p>' ) ;
542640
543641 return response ;
544- } ,
545- function ( err ) {
642+ } )
643+ . catch ( function ( err ) {
546644 console . error ( err ) ;
547- }
548- ) ;
645+ ActivityEmbed . repl . writeln ( "An unexpected error occurred: " + err ) ;
646+ ActivityEmbed . repl . writeln ( 'Please try reloading the page or contact support if the issue persists' ) ;
647+ } )
648+ . finally ( function ( ) {
649+ $ ( '#submit' ) . text ( 'Submit' ) ;
650+ } )
549651 } ;
550652 this . cloudCoderProcess = function ( info ) {
551653 var questionData = questionsSaveData . getQuestionData ( currentQuestion . getId ( ) ) ;
0 commit comments