From 6810c785fb888598a0f888954ba4c91f19bae52d Mon Sep 17 00:00:00 2001 From: Jacek Bzdak Date: Tue, 29 Mar 2016 23:46:12 +0200 Subject: [PATCH 1/7] Initial implementation --- .../public/js/mentoring_with_steps.js | 116 ++++++++++++------ .../tests/integration/test_step_builder.py | 5 +- 2 files changed, 80 insertions(+), 41 deletions(-) diff --git a/problem_builder/public/js/mentoring_with_steps.js b/problem_builder/public/js/mentoring_with_steps.js index 532c4f9e..752231e6 100644 --- a/problem_builder/public/js/mentoring_with_steps.js +++ b/problem_builder/public/js/mentoring_with_steps.js @@ -7,17 +7,18 @@ function MentoringWithStepsBlock(runtime, element) { } var children = runtime.children(element); + var steps = []; for (var i = 0; i < children.length; i++) { var child = children[i]; var blockType = $(child.element).data('block-type'); if (blockType === 'sb-step') { - steps.push(child); + registerStep(child) } } - var activeStep = $('.mentoring', element).data('active-step'); + var activeStepIndex = $('.mentoring', element).data('active-step'); var attemptsTemplate = _.template($('#xblock-attempts-template').html()); var message = $('.sb-step-message', element); var checkmark, submitDOM, nextDOM, reviewButtonDOM, tryAgainDOM, @@ -25,12 +26,66 @@ function MentoringWithStepsBlock(runtime, element) { var reviewStepDOM = $("div.xblock[data-block-type=sb-review-step], div.xblock-v1[data-block-type=sb-review-step]", element); var hasAReviewStep = reviewStepDOM.length == 1; + function registerStep(step) { + var $element = $(step.element); + var $anchor = $(''); + $anchor.insertBefore($element); + var step = { + idx: step.length, + $element: $element, + xblock: step, + $anchor: $anchor + }; + steps.push(step); + } + + function getActiveStep() { + return getStepByIndex(activeStepIndex); + } + + function getActiveStepBlock() { + return getActiveStep()['xblock']; + } + + function getStepByIndex(idx){ + return steps[idx]; + } + + function forEachStep(func){ + for (var idx=0; idx Date: Wed, 30 Mar 2016 15:39:34 +0200 Subject: [PATCH 2/7] Rever test changes --- problem_builder/tests/integration/test_step_builder.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/problem_builder/tests/integration/test_step_builder.py b/problem_builder/tests/integration/test_step_builder.py index ad7800c6..7846ed77 100644 --- a/problem_builder/tests/integration/test_step_builder.py +++ b/problem_builder/tests/integration/test_step_builder.py @@ -624,6 +624,9 @@ def test_review_tips(self): @data(True, False) def test_conditional_messages(self, include_messages): + """ + Test that conditional messages in the review step are visible or not, as appropriate. + """ max_attempts = 3 extended_feedback = False params = { @@ -1368,7 +1371,7 @@ def test_no_review_step(self): def provide_freeform_answer(self, step_number, question_number, step_builder, text_input): steps = step_builder.find_elements_by_css_selector('div[data-block-type="sb-step"]') - current_step = steps[0] + current_step = steps[step_number-1] freeform_questions = current_step.find_elements_by_css_selector('div[data-block-type="pb-answer"]') current_question = freeform_questions[question_number-1] From c9651b6074018bab47523e360812c0183b8e0a2d Mon Sep 17 00:00:00 2001 From: Jacek Bzdak Date: Wed, 30 Mar 2016 16:12:21 +0200 Subject: [PATCH 3/7] Some renames --- .../public/js/mentoring_with_steps.js | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/problem_builder/public/js/mentoring_with_steps.js b/problem_builder/public/js/mentoring_with_steps.js index 752231e6..f58be3a8 100644 --- a/problem_builder/public/js/mentoring_with_steps.js +++ b/problem_builder/public/js/mentoring_with_steps.js @@ -43,8 +43,8 @@ function MentoringWithStepsBlock(runtime, element) { return getStepByIndex(activeStepIndex); } - function getActiveStepBlock() { - return getActiveStep()['xblock']; + function getActiveBlock() { + return getActiveStep().xblock; } function getStepByIndex(idx){ @@ -64,7 +64,6 @@ function MentoringWithStepsBlock(runtime, element) { } function showStep(step) { - // step.$element.insertAfter(step.$anchor); step.$element.show(); } @@ -104,7 +103,7 @@ function MentoringWithStepsBlock(runtime, element) { } else { checkmark.addClass('checkmark-incorrect icon-exclamation fa-exclamation'); } - var step = getActiveStepBlock(); + var step = getActiveBlock(); if (typeof step.showFeedback == 'function') { step.showFeedback(response); } @@ -133,7 +132,7 @@ function MentoringWithStepsBlock(runtime, element) { function submit() { submitDOM.attr('disabled', 'disabled'); // Disable the button until the results load. var submitUrl = runtime.handlerUrl(element, 'submit'); - var activeStep = getActiveStepBlock(); + var activeStep = getActiveBlock(); var hasQuestion = activeStep.hasQuestion(); var data = activeStep.getSubmitData(); data["active_step"] = activeStepIndex; @@ -157,14 +156,14 @@ function MentoringWithStepsBlock(runtime, element) { } function getResults() { - getActiveStepBlock().getResults(handleReviewResults); + getActiveBlock().getResults(handleReviewResults); } function handleReviewResults(response) { // Show step-level feedback showFeedback(response); // Forward to active step to show answer level feedback - var step = getActiveStepBlock(); + var step = getActiveBlock(); var results = response.results; var options = { checkmark: checkmark @@ -188,7 +187,7 @@ function MentoringWithStepsBlock(runtime, element) { } function updateNextLabel() { - var step = getActiveStepBlock(); + var step = getActiveBlock(); nextDOM.attr('value', step.getStepLabel()); } @@ -213,7 +212,7 @@ function MentoringWithStepsBlock(runtime, element) { nextDOM.on('click', updateDisplay); reviewButtonDOM.on('click', showGrade); - var step = getActiveStepBlock(); + var step = getActiveBlock(); if (step.hasQuestion()) { // Step includes one or more questions nextDOM.attr('disabled', 'disabled'); submitDOM.show(); @@ -294,7 +293,7 @@ function MentoringWithStepsBlock(runtime, element) { nextDOM.show(); nextDOM.removeAttr('disabled'); } - var step = getActiveStepBlock(); + var step = getActiveBlock(); tryAgainDOM.hide(); if (step.hasQuestion()) { @@ -330,7 +329,7 @@ function MentoringWithStepsBlock(runtime, element) { function validateXBlock() { var isValid = true; - var step = getActiveStepBlock(); + var step = getActiveBlock(); if (step) { isValid = step.validate(); } From d356500a8d582cc1bcbb7f57440e511a998d81e5 Mon Sep 17 00:00:00 2001 From: Jacek Bzdak Date: Wed, 30 Mar 2016 16:23:54 +0200 Subject: [PATCH 4/7] Code cleanups and documentation --- .../public/js/mentoring_with_steps.js | 98 +++++++++++++------ 1 file changed, 66 insertions(+), 32 deletions(-) diff --git a/problem_builder/public/js/mentoring_with_steps.js b/problem_builder/public/js/mentoring_with_steps.js index f58be3a8..8dc977dd 100644 --- a/problem_builder/public/js/mentoring_with_steps.js +++ b/problem_builder/public/js/mentoring_with_steps.js @@ -14,7 +14,7 @@ function MentoringWithStepsBlock(runtime, element) { var child = children[i]; var blockType = $(child.element).data('block-type'); if (blockType === 'sb-step') { - registerStep(child) + registerStep(child); } } @@ -25,54 +25,88 @@ function MentoringWithStepsBlock(runtime, element) { gradeDOM, attemptsDOM, reviewLinkDOM, submitXHR; var reviewStepDOM = $("div.xblock[data-block-type=sb-review-step], div.xblock-v1[data-block-type=sb-review-step]", element); var hasAReviewStep = reviewStepDOM.length == 1; - + + /** + * Registers step to in this builder, it stores the xblock element, and some additional metadata used to safely + * remove and re-attach xblock to the DOM. See showStep and hideStep to see why we need to do it. + * @param step xblock instance to register + */ function registerStep(step) { var $element = $(step.element); var $anchor = $(''); $anchor.insertBefore($element); - var step = { + var step_wrapper = { idx: step.length, $element: $element, xblock: step, $anchor: $anchor }; - steps.push(step); - } - - function getActiveStep() { - return getStepByIndex(activeStepIndex); + steps.push(step_wrapper); } - function getActiveBlock() { - return getActiveStep().xblock; + /** + * Returns wrapper for active step + * @returns {*}, an object containing xblock, and additional metadata (see registerStep where this object is created + * for properties) + */ + function getWrapperForActiveStep() { + return steps[activeStepIndex](activeStepIndex); } - function getStepByIndex(idx){ - return steps[idx]; + /** + * Returns active step) + * @returns {*} + */ + function getActiveStep() { + return getWrapperForActiveStep().xblock; } + /** + * Calls a function for each registered step. Object passed to this function is an step wrapper object + * (see registerStep where this object is created a list of properties) + * + * @param func single arg function. + */ function forEachStep(func){ for (var idx=0; idx Date: Wed, 30 Mar 2016 16:37:06 +0200 Subject: [PATCH 5/7] Fix stupid typo --- problem_builder/public/js/mentoring_with_steps.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problem_builder/public/js/mentoring_with_steps.js b/problem_builder/public/js/mentoring_with_steps.js index 8dc977dd..c6f499a5 100644 --- a/problem_builder/public/js/mentoring_with_steps.js +++ b/problem_builder/public/js/mentoring_with_steps.js @@ -50,7 +50,7 @@ function MentoringWithStepsBlock(runtime, element) { * for properties) */ function getWrapperForActiveStep() { - return steps[activeStepIndex](activeStepIndex); + return steps[activeStepIndex]; } /** From 2849e6d2e955cdcf05b288e4054ea254d40cd0dc Mon Sep 17 00:00:00 2001 From: Jacek Bzdak Date: Wed, 30 Mar 2016 16:47:17 +0200 Subject: [PATCH 6/7] Fixed a pronoun --- problem_builder/public/js/mentoring_with_steps.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problem_builder/public/js/mentoring_with_steps.js b/problem_builder/public/js/mentoring_with_steps.js index c6f499a5..ab64d4a3 100644 --- a/problem_builder/public/js/mentoring_with_steps.js +++ b/problem_builder/public/js/mentoring_with_steps.js @@ -97,7 +97,7 @@ function MentoringWithStepsBlock(runtime, element) { } /** - * Displays active step + * Displays the active step */ function showActiveStep() { var step = getWrapperForActiveStep(); From 020ab935720915d5dff84eb65f98ce0aa5612ff9 Mon Sep 17 00:00:00 2001 From: Jacek Bzdak Date: Wed, 30 Mar 2016 22:30:35 +0200 Subject: [PATCH 7/7] PR Review fixes --- .../public/js/mentoring_with_steps.js | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/problem_builder/public/js/mentoring_with_steps.js b/problem_builder/public/js/mentoring_with_steps.js index ab64d4a3..ffd313a9 100644 --- a/problem_builder/public/js/mentoring_with_steps.js +++ b/problem_builder/public/js/mentoring_with_steps.js @@ -27,7 +27,8 @@ function MentoringWithStepsBlock(runtime, element) { var hasAReviewStep = reviewStepDOM.length == 1; /** - * Registers step to in this builder, it stores the xblock element, and some additional metadata used to safely + * Registers step with this StepBuilder instance: Creates and stores a wrapper that contains the XBlock instance + * and associated DOM element, as well as some additional metadata used to safely * remove and re-attach xblock to the DOM. See showStep and hideStep to see why we need to do it. * @param step xblock instance to register */ @@ -36,7 +37,6 @@ function MentoringWithStepsBlock(runtime, element) { var $anchor = $(''); $anchor.insertBefore($element); var step_wrapper = { - idx: step.length, $element: $element, xblock: step, $anchor: $anchor @@ -45,16 +45,16 @@ function MentoringWithStepsBlock(runtime, element) { } /** - * Returns wrapper for active step - * @returns {*}, an object containing xblock, and additional metadata (see registerStep where this object is created - * for properties) + * Returns wrapper for the active step + * @returns {*}, an object containing the XBlock instance and associated DOM element for the active step, as well + * as additional metadata (see registerStep where this object is created for properties) */ function getWrapperForActiveStep() { return steps[activeStepIndex]; } /** - * Returns active step) + * Returns the active step * @returns {*} */ function getActiveStep() { @@ -62,13 +62,13 @@ function MentoringWithStepsBlock(runtime, element) { } /** - * Calls a function for each registered step. Object passed to this function is an step wrapper object - * (see registerStep where this object is created a list of properties) + * Calls a function for each registered step. The object passed to this function is a step wrapper object + * (see registerStep where this object is created for a list of properties) * * @param func single arg function. */ function forEachStep(func){ - for (var idx=0; idx