diff --git a/macros/core/scaffold.pl b/macros/core/scaffold.pl index 4070b432a2..4eb817a951 100644 --- a/macros/core/scaffold.pl +++ b/macros/core/scaffold.pl @@ -186,6 +186,21 @@ =head1 DESCRIPTION have the student open it by hand before anwering the questions. In this case, set this value to 0 (it is 1 by default). +=item C 0 or 1 >>> + +This determines whether Preview My Answers should be allowed to open +a new section. Set this to 0 to prevent the next section from opening +after Preview My Answers is clicked (it is 1 by default). + +=item C 0 or 1 >>> + +This determines whether Preview My Answers should be allowed to close +a section which was open before, if the prior answers were changed to be +incorrect. By default the setting is 0, so such section closures can +occur due to a Preview, while when set to 1 sections will not be closed by +Preview. + + =item C 0 or 1 >>> This determines whether each section is automatically numbered before @@ -316,6 +331,7 @@ sub Begin { unshift(@scaffolds, $self); $scaffold = $self; $scaffold_depth++; + $self->{key_last_open} = "ScAfFoLd_${PREFIX}_SC-" . $self->{number} . "_last_open"; $self->{previous_output} = [ splice(@{$PG_OUTPUT}, 0) ]; # get output and clear it without changing the array pointer $self->{output} = []; # the contents of the scaffold @@ -338,6 +354,12 @@ sub End { $self->hide_other_results(@{ $self->{open} }); # hide results of unnopened sections in the results table push(@$PG_OUTPUT, @{ $self->{previous_output} }, @{ $self->{output} }) ; # put back original output and scaffold output + + if (!$self->{isPreview}) { + # Record the last_open value for future renders + main::update_persistent_data($self->{key_last_open}, $self->{open}[-1] ? $self->{open}[-1] : 0); + } + delete $self->{previous_output}; delete $self->{output}; # don't need these any more shift(@scaffolds); @@ -372,6 +394,11 @@ sub new { hardcopy_is_open => "always", # open all possible sections in hardcopy open_first_section => 1, # 0 means don't open any sections initially numbered => 0, # 1 means sections will be printed with their number + + # control whether Preview should be allowed to open/close sections + allow_next_section_to_open_on_preview => 1, # can Preview open another section + prevent_close_by_preview => 0, # can Preview close previously open sections + @_, number => ++$scaffold_no, # the number for this scaffold depth => $scaffold_depth, # the nesting depth for this scaffold @@ -402,7 +429,7 @@ sub start_section { # # Add the content from the current section into the scaffold's output -# and remove the current_section (so we can tell that no sectionis open). +# and remove the current_section (so we can tell that no section is open). # sub end_section { my $self = shift; @@ -435,11 +462,40 @@ sub section_answers { $evaluator->{rh_ans}{ans_message} = ""; delete $evaluator->{rh_ans}{error_message}; } - foreach my $name (@_) { $self->{scores}{$name} = $answers{$name}{score} if $answers{$name} } + + my $section_no = $self->{section_no}; + my $prior_last_open = main::get_persistent_data($self->{key_last_open}); + + my $myLastSet; # we save the name of the last answer field whose score was set + for my $name (@_) { + if ($answers{$name}) { + $self->{scores}{$name} = $answers{$name}{score}; + $myLastSet = $name; + } + } + if ($myLastSet) { + $self->{isPreview} = $answers{$myLastSet}{isPreview} if (!defined($self->{isPreview})); + if ($self->{isPreview}) { # Only handle for Preview mode + if ( + ($section_no == $prior_last_open) # Only should consider modifying the last previously open section + && !$self->{allow_next_section_to_open_on_preview} + ) + { + # This should prevent the next section from opening on Preview + # if all answers to this section are correct, unless it would open anyway. + $self->{scores}{$myLastSet} = 0; + } elsif (($section_no < $prior_last_open) && $self->{prevent_close_by_preview}) { + # This section was open before - AVOID closing it due to a change in prior sections and a Preview + for my $name (@{ $self->{ans_names} }) { + $self->{scores}{$name} = 1.0 if ($answers{$name}); # to prevent it from being closed + } + } + } + } } # -# Add the given sections to the list of sections to be openned +# Add the given sections to the list of sections to be opened # for this scaffold # sub is_open { @@ -601,7 +657,7 @@ sub new { # Adds the necessary HTML around the content of the section. # # First, determine the is_correct and can_open status and save them. -# Then check if the section is to be openned, and if so, add it +# Then check if the section is to be opened, and if so, add it # to the open list of the scaffold. # # The $PG_OUTPUT variable holds just the contents of this section, @@ -745,11 +801,11 @@ sub new_answers { package Section::can_open; # -# Always can be openned +# Always can be opened # sub always { return 1 } # -# Can be openned when all the answers from previous sections are correct +# Can be opened when all the answers from previous sections are correct # sub when_previous_correct { my $section = shift; @@ -772,7 +828,7 @@ sub incorrect { return !$section->{is_correct}; } # -# Never can be openned +# Never can be opened # sub never { return 0 }