[LON-CAPA-cvs] cvs: rat /client parameter.html loncom/homework lonhomework.pm loncom/interface lonmenu.pm lonparmset.pm

raeburn raeburn at source.lon-capa.org
Tue Mar 15 10:25:41 EDT 2016


raeburn		Tue Mar 15 14:25:41 2016 EDT

  Modified files:              
    /loncom/interface	lonparmset.pm lonmenu.pm 
    /loncom/homework	lonhomework.pm 
    /rat/client	parameter.html 
  Log:
  - Bug 6763
    - "Done" button used to end a timed event can include a textbox where a
      required key is entered.
  
  
-------------- next part --------------
Index: loncom/interface/lonparmset.pm
diff -u loncom/interface/lonparmset.pm:1.557 loncom/interface/lonparmset.pm:1.558
--- loncom/interface/lonparmset.pm:1.557	Fri Mar  4 21:43:15 2016
+++ loncom/interface/lonparmset.pm	Tue Mar 15 14:25:26 2016
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set parameters for assessments
 #
-# $Id: lonparmset.pm,v 1.557 2016/03/04 21:43:15 raeburn Exp $
+# $Id: lonparmset.pm,v 1.558 2016/03/15 14:25:26 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -824,7 +824,7 @@
         }
     } else {
         if ($type eq 'date_interval') {
-            my ($totalsecs,$donebutton) = split(/_/,$value);
+            my ($totalsecs,$donebutton,$proctor,$secretkey) = split(/_/,$value);
             my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($totalsecs);
             my @timer;
             $year=$year-70;
@@ -859,7 +859,11 @@
             }
             $result.=join(", ", at timer);
             if ($donebutton eq 'done') {
-                $result .= ' '.&mt('+ "done"');
+                if ($secretkey) {
+                    $result .= ' '.&mt('+ "done" with proctor key: [_1]',$secretkey);  
+                } else {
+                    $result .= ' '.&mt('+ "done"');
+                }  
             }
         } elsif (&isdateparm($type)) {
             $result = &Apache::lonlocal::locallocaltime($value).
@@ -1125,6 +1129,31 @@
 END
 }
 
+sub done_proctor_js {
+    return <<"END";
+function toggleSecret(form,radio,key) {
+    var radios = form[radio+key];
+    if (radios.length) {
+        for (var i=0; i<radios.length; i++) {
+            if (radios[i].checked) {
+                if (radios[i].value == '_done_proctor') {
+                    if (document.getElementById('done_'+key+'_proctorkey')) {
+                        document.getElementById('done_'+key+'_proctorkey').type='text';
+                    }
+                } else {
+                    if (document.getElementById('done_'+key+'_proctorkey')) {
+                        document.getElementById('done_'+key+'_proctorkey').type='hidden';
+                        document.getElementById('done_'+key+'_proctorkey').value='';
+                    }
+                }
+            }
+        }
+    }
+}
+END
+
+}
+
 sub startpage {
     my ($r,$psymb,$crstype) = @_;
 
@@ -3601,8 +3630,11 @@
         $seconds += $env{'form.'.$name.'_'.$key} * $factor;
     }
     }
-    if (($key =~ /\.interval$/) && ($env{'form.done_'.$key} eq '_done')) {
+    if (($key =~ /\.interval$/) && (($env{'form.done_'.$key} eq '_done') || ($env{'form.done_'.$key} eq '_done_proctor'))) {
         $seconds .= $env{'form.done_'.$key};
+        if ($env{'form.done_'.$key.'_proctorkey'}) {
+            $seconds .= '_'.$env{'form.done_'.$key.'_proctorkey'};
+        }
     }
     return $seconds;
 }
@@ -3903,12 +3935,14 @@
     (
      'date_interval'
              => [[ 'done', 'Yes' ],
+                 [ 'done_proctor', 'Yes, with proctor key'],                  
                  [ '', 'No' ]],
     );
 
 my %intervalmatches = (
          'date_interval'
-              => [['done','\d+_done$'],],
+              => [['done','\d+_done$'],
+                  ['done_proctor','\d+_done_proctor_']],
     );
 
 my %intervaltypes = (
@@ -3996,16 +4030,29 @@
     if ($name eq 'interval') {
         unless ($skipval{'done'}) {
             my $checkedon = '';
+            my $checkedproc = '';
+            my $currproctorkey = '';
+            my $currprocdisplay = 'hidden';
             my $checkedoff = ' checked="checked"';
             if ($currval =~ /^(\d+)_done$/) {
                 $checkedon = ' checked="checked"';
                 $checkedoff = '';
+            } elsif ($currval =~ /^(?:\d+)_done_proctor_(.+)$/) {
+                $currproctorkey = $1;
+                $checkedproc = ' checked="checked"';
+                $checkedoff = '';
+                $currprocdisplay = 'text';
             }
-            $result .= '<span class="LC_nobreak">'.(' ' x 3).'('.&mt('Include "done" button').
-                       '<label><input type="radio" value="_done" name="done_'.$thiskey.'"'.$checkedon.' />'.
-                       &mt('Yes').'</label>'.
-                       '<label><input type="radio" value="" name="done_'.$thiskey.'"'.$checkedoff.' />'.
-                       &mt('No').'</label>)</span>';
+            my $onclick = ' onclick="toggleSecret(this.form,'."'done_','$thiskey'".');"';
+            $result .= '<br /><span class="LC_nobreak">'.&mt('Include "done" button').
+                       '<label><input type="radio" value="" name="done_'.$thiskey.'"'.$checkedoff.$onclick.' />'.
+                       &mt('No').'</label>'.(' 'x2).
+                       '<label><input type="radio" value="_done" name="done_'.$thiskey.'"'.$checkedon.$onclick.' />'.
+                       &mt('Yes').'</label>'.(' 'x2).
+                       '<label><input type="radio" value="_done_proctor" name="done_'.$thiskey.'"'.$checkedproc.$onclick.' />'.
+                       &mt('Yes, with proctor key').'</label>'.
+                       '<input type="'.$currprocdisplay.'" id="done_'.$thiskey.'_proctorkey" '.
+                       'name="done_'.$thiskey.'_proctorkey" value="'.$currproctorkey.'" /></span>';
         }
     }
     unless ($readonly) {
@@ -4144,6 +4191,7 @@
             &toggleparmtextbox_js()."\n".
             &validateparms_js()."\n".
             &ipacc_boxes_js()."\n".
+            &done_proctor_js()."\n".
 '// ]]>
 </script>
 ';
@@ -4343,6 +4391,7 @@
              &toggleparmtextbox_js()."\n".
              &validateparms_js()."\n".
              &ipacc_boxes_js()."\n".
+             &done_proctor_js()."\n".
              '// ]]>'."\n".
              '</script>'."\n";
     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
Index: loncom/interface/lonmenu.pm
diff -u loncom/interface/lonmenu.pm:1.439 loncom/interface/lonmenu.pm:1.440
--- loncom/interface/lonmenu.pm:1.439	Fri Feb 26 21:44:39 2016
+++ loncom/interface/lonmenu.pm	Tue Mar 15 14:25:26 2016
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Routines to control the menu
 #
-# $Id: lonmenu.pm,v 1.439 2016/02/26 21:44:39 raeburn Exp $
+# $Id: lonmenu.pm,v 1.440 2016/03/15 14:25:26 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1568,28 +1568,113 @@
 }
 
 # This creates a "done button" for timed events.  The confirmation box is a jQuery
-# dialog widget.  Clicking OK will set (LC_interval_done = 'true') which is checked in 
-# lonhomework.pm.
+# dialog widget. If the interval parameter requires a proctor key for the timed 
+# event to be marked done, there will also be a textbox where that can be entered. 
+# Clicking OK will set the value of LC_interval_done to 'true', and, if needed will 
+# set the value of LC_interval_done_proctorpass to the text entered in that box, 
+# and submit the corresponding form.
+# 
+# The &zero_time() routine in lonhomework.pm is called when a page is rendered if
+# LC_interval_done is true.
+#
 sub done_button_js {
-    my ($type,$height) = @_;
-    if ($height !~ /^\d+$/) {
-        $height = 320;
-    }
+    my ($type,$width,$height,$proctor) = @_;
     my %lt = &Apache::lonlocal::texthash(
                  title    => 'WARNING!',
                  button   => 'Done',
                  preamble => 'You are trying to end this timed event early.',
                  map      => 'Confirming that you are done will cause the time to expire and prevent you from changing any answers in the current folder.',
                  resource => 'Confirming that you are done will cause the time to expire for this question, and prevent you from changing your answer(s).', 
-                 ok       => 'Click "OK" if you are completely finished.',
+                 okdone   => 'Click "OK" if you are completely finished.',
                  cancel   => 'Click "Cancel" to continue working.',
+                 proctor  => 'Ask a proctor to enter the key, then click "OK" if you are completely finished.',
+                 ok       => 'OK',
+                 exit     => 'Cancel',
+                 key      => 'Key:',
+                 nokey    => 'A proctor key is required', 
     );
     my $confirm;
     if (($type eq 'map') || ($type eq 'resource')) {
-        $confirm = $lt{'preamble'}.' '.$lt{$type}.' '.$lt{'ok'}.' '.$lt{'cancel'};
-    }
-    if ($confirm) {
-        return <<END;
+        if ($proctor) {
+            $confirm = $lt{'preamble'}.' '.$lt{$type};
+            if ($height !~ /^\d+$/) {
+                $height = 400;
+            }
+            if ($width !~ /^\d+$/) {
+                $width = 400;
+            }
+            return <<END;
+<form method="post" name="LCdoneButton" action="">
+    <input type="hidden" name="LC_interval_done" value="" />
+    <input type="hidden" name="LC_interval_done_proctorpass" value="" />
+    <button id="LC_done-confirm-opener" type="button">$lt{'button'}</button>
+</form>
+
+<div id="LC_done-confirm" title="$lt{'title'}">
+  <p>$lt{'preamble'} $lt{$type}</p>
+  <p>$lt{'proctor'}</p>
+  <form>
+    <label>$lt{'key'}<input type="password" name="LC_interval_done_proctorkey" value="" /></label>
+    <input type="submit" tabindex="-1" style="position:absolute; top:-1000px" />
+  </form>
+  <p>$lt{'cancel'}</p>
+</div>
+
+<script type="text/javascript">
+// <![CDATA[
+    \$( "#LC_done-confirm" ).dialog({ autoOpen: false });
+    \$( "#LC_done-confirm-opener" ).on("click", function() {
+        \$( "#LC_done-confirm" ).dialog("open");
+        \$( "#LC_done-confirm" ).dialog({
+            height: $height,
+            width: $width,
+            modal: true,
+            resizable: false,
+            buttons: [
+                {
+                    text: "$lt{'ok'}",
+                    click: function() {
+                        var proctorkey = \$( '[name="LC_interval_done_proctorkey"]' )[0].value;
+                        if ((proctorkey == '') || (proctorkey == null)) {
+                            alert("$lt{'nokey'}"); 
+                        } else { 
+                            \$( '[name="LC_interval_done"]' )[0].value = 'true';
+                            \$( '[name="LC_interval_done_proctorpass"]' )[0].value = proctorkey;
+                            \$( '[name="LCdoneButton"]' )[0].submit();
+                        }
+                    },
+                },
+                {
+                    text: "$lt{'exit'}",
+                    click: function() {
+                        \$("#LC_done-confirm").dialog( "close" );
+                    }
+                }
+            ],
+            close: function() {
+                \$( '[name="LC_interval_done_proctorkey"]' )[0].value = '';
+            }
+        });
+        \$( "#LC_done-confirm" ).find( "form" ).on( "submit", function( event ) {
+            event.preventDefault();
+            \$( '[name="LC_interval_done"]' )[0].value = 'true';
+            \$( '[name="LC_interval_done_proctorpass"]' )[0].value = \$( '[name="LC_interval_done_proctorkey"]' )[0].value;
+            \$( '[name="LCdoneButton"]' )[0].submit();
+        });
+});
+
+// ]]>
+</script>
+
+END
+        } else {
+            if ($height !~ /^\d+$/) {
+                $height = 320;
+            }
+            if ($width !~ /^\d+$/) {
+                $width = 320;
+            }
+            return <<END;
 
 <form method="post" name="LCdoneButton" action="">
     <input type="hidden" name="LC_interval_done" value="" />
@@ -1597,7 +1682,7 @@
 </form>
 
 <div id="LC_done-confirm" title="$lt{'title'}">
-    <p>$confirm</p>
+    <p>$lt{'preamble'} $lt{$type} $lt{'okdone'} $lt{'cancel'}</p>
 </div>
 
 <script type="text/javascript">
@@ -1608,23 +1693,31 @@
     \$( "#LC_done-confirm" ).dialog({
       resizable: false,
       height: $height,
+      width: $width,
       modal: true,
-      buttons: {
-        "OK": function() {
-            \$( this ).dialog( "close" );
-            \$( '[name="LC_interval_done"]' )[0].value = 'true';
-            \$( '[name="LCdoneButton"]' )[0].submit();
-        },
-        Cancel: function() {
-          \$( this ).dialog( "close" );
-        }
-      }    
-    })
+      buttons: [
+                 {
+                    text: "$lt{'ok'}",
+                    click: function() {
+                        \$( this ).dialog( "close" );
+                        \$( '[name="LC_interval_done"]' )[0].value = 'true';
+                        \$( '[name="LCdoneButton"]' )[0].submit();
+                    },
+                 },
+                 {
+                     text: "$lt{'exit'}",
+                     click: function() {
+                         \$( this ).dialog( "close" );
+                     },
+                  },
+               ],
+       });
 });
 // ]]>
 </script>
 
 END
+        }
     } else {
         return;
     }
@@ -2293,9 +2386,9 @@
         }
         my $duedate = &Apache::lonnet::EXT("resource.0.duedate");
         my @interval=&Apache::lonnet::EXT("resource.0.interval");
-        my ($timelimit,$usesdone);
+        my ($timelimit,$usesdone,$proctor,$secret);
         if (@interval > 1) {
-            ($timelimit,$usesdone) = split(/_/,$interval[0]); 
+            ($timelimit,$usesdone,$proctor,$secret) = split(/_/,$interval[0]); 
             my $first_access=&Apache::lonnet::get_first_access($interval[1]);
             if ($first_access > 0) {
                 if ($first_access+$timelimit > time) {
@@ -2313,7 +2406,7 @@
                 $collapse = '► ';
                 if ((@interval > 1) && ($hastimeleft)) {
                     if ($usesdone eq 'done') {
-                        $donebutton = &done_button_js($interval[1]);
+                        $donebutton = &done_button_js($interval[1],'','',$proctor);
                     }
                 }
             } else {
Index: loncom/homework/lonhomework.pm
diff -u loncom/homework/lonhomework.pm:1.359 loncom/homework/lonhomework.pm:1.360
--- loncom/homework/lonhomework.pm:1.359	Mon Oct 26 20:36:45 2015
+++ loncom/homework/lonhomework.pm	Tue Mar 15 14:25:33 2016
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Homework handler
 #
-# $Id: lonhomework.pm,v 1.359 2015/10/26 20:36:45 musolffc Exp $
+# $Id: lonhomework.pm,v 1.360 2016/03/15 14:25:33 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1172,7 +1172,7 @@
 #    Render the page in whatever target desired.
 #
 sub renderpage {
-    my ($request,$file,$targets,$return_string) = @_;
+    my ($request,$file,$targets,$return_string,$donebuttonmsg) = @_;
 
     my @targets = @{$targets || [&get_target()]};
     &Apache::lonhomework::showhashsubset(\%env,'form.');
@@ -1225,7 +1225,12 @@
 	    if ($target eq 'analyze') {
 		$result=&Apache::lonnet::hashref2str(\%Apache::lonhomework::analyze);
 		undef(%Apache::lonhomework::analyze);
-	    }
+	    } elsif ($target eq 'web') {
+                if ($donebuttonmsg) {
+                    $result =~ s{</body>}{};
+                    $result.= &Apache::loncommon::confirmwrapper(&Apache::lonhtmlcommon::confirm_success($donebuttonmsg,1))."\n</body>";
+                }
+            }
 	    #my $td=&tv_interval($t0);
 	    #if ( $Apache::lonxml::debug) {
 	    #$result =~ s:</body>::;
@@ -1430,34 +1435,57 @@
     my @interval=&Apache::lonnet::EXT("resource.0.interval",$symb);
     if (@interval > 1) {
         if ($interval[1] eq 'course') {
-            return;
+            return ('fail',&mt('Ending of timed events not supported for intervals set course-wide'));
         } else {
             my $now = time;
             my $first_access=&Apache::lonnet::get_first_access($interval[1],$symb);
             if ($first_access > 0) {
-                my ($timelimit) = split(/_/,$interval[0]);
-                if ($first_access+$timelimit > $now) {
-                    my $done_time = $now - $first_access;
-                    my $snum = 1;
-                    if ($interval[1] eq 'map') {
-                        $snum = 2;
+                my ($timelimit,$done,$proctor,$secret) = split(/_/,$interval[0]);
+                if ($done eq 'done') { 
+                    if (($proctor) && ($secret ne '')) {
+                        my $key = $env{'form.LC_interval_done_proctorpass'};
+                        $key =~ s/^\s+//;
+                        $key =~ s/\s+$//;
+                        if ($env{'form.LC_interval_done_proctorpass'} ne $secret) {
+                            return ('fail',
+                                   &mt('Incorrect key entered by proctor')); 
+                        }
                     }
-                    my $result = 
-                        &Apache::lonparmset::storeparm_by_symb_inner($symb,'0_interval',
-                                                                     $snum,$done_time,
-                                                                     'date_interval',
-                                                                     $env{'user.name'},
-                                                                     $env{'user.domain'});
-                        # Record action in "User Notes"
-                        &Apache::lonmsg::store_instructor_comment(
-                            'Pressed Done button for symb:<br />'.$symb,
-                            $env{'user.name'}, $env{'user.domain'});
-                    return $result;
+                    if ($first_access+$timelimit > $now) {
+                        my $done_time = $now - $first_access;
+                        my $snum = 1;
+                        if ($interval[1] eq 'map') {
+                            $snum = 2;
+                        }
+                        my $result =
+                            &Apache::lonparmset::storeparm_by_symb_inner($symb,'0_interval',
+                                                                         $snum,$done_time,
+                                                                         'date_interval',
+                                                                         $env{'user.name'},
+                                                                         $env{'user.domain'});
+                        if ($result eq '') {
+                            # Record action in "User Notes"
+                            &Apache::lonmsg::store_instructor_comment(
+                                'Pressed Done button for symb:<br />'.$symb,
+                                $env{'user.name'}, $env{'user.domain'});
+                            return ('ok');
+                        } else {
+                            return ('fail',&mt('Error ending timed event: [_1]',$result));
+                        } 
+                    } else {
+                        return ('fail',&mt('Timed event already ended'));
+                    }
+                } else {
+                    return ('fail',&mt('Timed event can not be ended before the time limit'));
                 }
+            } else {
+                return ('fail',&mt('Timer not yet started for this timed event'));
             }
         }
+    } else {
+        return ('fail',&mt('No timer in use'));
     }
-    return;
+    return();
 }
 
 sub handler {
@@ -1519,13 +1547,15 @@
     } else {
         # Set the event timer to zero if the "done button" was clicked.  The button is
         # part of the doneButton form created in lonmenu.pm
+        my ($donebuttonresult,$donemsg);
         if ($symb && $env{'form.LC_interval_done'} eq 'true') {  
-            &zero_timer($symb);
+            ($donebuttonresult,$donemsg) = &zero_timer($symb);
             undef($env{'form.LC_interval_done'});
+            undef($env{'form.LC_interval_done_proctorpass'});
         }
 	# just render the page normally outside of construction space
 	&Apache::lonxml::debug("not construct");
-	&renderpage($request,$file);
+	&renderpage($request,$file,undef,undef,$donemsg);
     }
     #my $td=&tv_interval($t0);
     #&Apache::lonxml::debug("Spent $td seconds processing");
Index: rat/client/parameter.html
diff -u rat/client/parameter.html:1.69 rat/client/parameter.html:1.70
--- rat/client/parameter.html:1.69	Sat Nov 21 00:16:09 2015
+++ rat/client/parameter.html	Tue Mar 15 14:25:41 2016
@@ -5,7 +5,7 @@
 The LearningOnline Network with CAPA
 Parameter Input Window
 //
-// $Id: parameter.html,v 1.69 2015/11/21 00:16:09 musolffc Exp $
+// $Id: parameter.html,v 1.70 2016/03/15 14:25:41 raeburn Exp $
 //
 // Copyright Michigan State University Board of Trustees
 //
@@ -40,6 +40,7 @@
 var ptype='';
 var pvalue='';
 var pmodval='';
+var pextraval='';
 var preturn='';
 var pcode='';
 var pscat='';
@@ -312,25 +313,74 @@
              sform.seconds.options[sform.seconds.selectedIndex].value*1;
     if ((ptype=='date') && (pscat=='interval')) {
         var newpmodval = '';
+        var newpextraval = '';
         if (sform.donebutton.length) {
             for (var i=0; i<sform.donebutton.length; i++) {
                 if (sform.donebutton[i].checked) {
                     if (sform.donebutton[i].value == '_done') {
                         newpmodval = sform.donebutton[i].value;
+                    } else {
+                        if (sform.donebutton[i].value == '_done_proctor') { 
+                            newpmodval = sform.donebutton[i].value;
+                            newpextraval = sform.donebutton_proctorkey.value;
+                        }
                     }
                 }
             }
         }
         pmodval = newpmodval;
+        pextraval = newpextraval;
         draw();
         if (pmodval) {
             svalue += pmodval;
         }
+        if (pextraval != '') {
+            svalue += '_'+pextraval;
+        }
     } else {
         draw();
     }
 }
 
+function toggleSecret() {
+    var sform=choices.document.forms.sch;
+    if (sform.donebutton.length) {
+        for (var i=0; i<sform.donebutton.length; i++) {
+            if (sform.donebutton[i].checked) {
+                if (sform.donebutton[i].value == '_done_proctor') {
+                    if (document.getElementById('done_proctorkey')) {
+                        document.getElementById('done_proctorkey').type='text';
+                    }
+                } else {
+                    if (document.getElementById('done_proctorkey')) {
+                        document.getElementById('done_proctorkey').type='hidden';
+                        document.getElementById('done_proctorkey').value='';
+                    }
+                }
+            }
+        }
+    }
+}
+
+function validateInterval() {
+    var sform=choices.document.forms.sch;
+    if (sform.donebutton.length) {
+        for (var i=0; i<sform.donebutton.length; i++) {
+            if (sform.donebutton[i].checked) {
+                if (sform.donebutton[i].value == '_done_proctor') {
+                    if ((sform.donebutton_proctorkey.value == '') || 
+                        (sform.donebutton_proctorkey.value == null)) {
+                        alert('Please provide a key for a proctor to enter when a student uses the "Done" button.');
+                        return;
+                    }
+                }
+            }
+        }
+    }
+    intcalc();
+    assemble();
+}
+
 function integereval() {
    svalue=choices.document.forms.sch.intval.value;
    svalue=Math.round(svalue);
@@ -373,7 +423,7 @@
 }
 
 function callintervalpmodval() {
-    return 'onclick="parent.intcalc()"';
+    return 'onclick="parent.intcalc();parent.toggleSecret()"';
 } 
 
 function intervaldis() {
@@ -500,6 +550,10 @@
          tablestart('Date and time');
       }
       if (pscat=='interval') {
+         var proctorkeytype = 'hidden'; 
+         if (pmodval == '_done_proctor') {
+             proctorkeytype = 'text';
+         }
          tablestart('Time interval');
          choicewrite( [
             '<tr><td colspan="3">'+intervaldis()+'</td></tr>',
@@ -514,14 +568,23 @@
             ].join("\n"));
          tablestart('Provide a "Done" button to students?');
          choicewrite('<tr><td>Value:</td><td colspan="2">');
+         choicewrite('<label><input name="donebutton" value=""'+
+                     ' type="radio" '+callintervalpmodval());
+         if (pmodval == '') { choicewrite(' checked="checked"'); }
+         choicewrite(' /> No</label><br />');
          choicewrite('<label><input name="donebutton" value="_done"'+
                      ' type="radio" '+callintervalpmodval());
-         if (pmodval =='_done') { choicewrite(' checked="checked"'); }
+         if (pmodval == '_done') { choicewrite(' checked="checked"'); }
          choicewrite(' /> Yes</label><br />');
-         choicewrite('<label><input name="donebutton" value=""'+
+         choicewrite('<span style="white-space:nowrap">'+
+                     '<label><input name="donebutton" value="_done_proctor"'+
                      ' type="radio" '+callintervalpmodval());
-         if (pmodval != '_done') { choicewrite(' checked="checked"'); }
-         choicewrite(' /> No</label><br />');
+         if (pmodval == '_done_proctor') { choicewrite(' checked="checked"'); }
+         choicewrite(' /> Yes, with proctor key</label>');
+         choicewrite(' <input name="donebutton_proctorkey" value='+
+                     '"'+escapeHTML(pextraval)+'" type="'+proctorkeytype+
+                     '" id="done_proctorkey"'+' size="10"'+
+                     ' onblur="parent.intcalc();" /></span>');
          choicewrite('</td></tr></table>');
       } else {
          choicewrite('<tr><td colspan="3">'
@@ -875,6 +938,8 @@
   var i;
   var subs=new Array();
   var doneRegExp = /_done/;
+  var doneproctorRegExp = /_done_proctor/;
+  var proctorkeyRegExp = /^(\d+)_(.+)$/;
   var namevalue=this.window.location.search.split('&');
   namevalue[0]=namevalue[0].substr(1,namevalue[0].length-1);
 
@@ -905,10 +970,24 @@
   }
 
   if (ptype=='date' && pscat == 'interval') {
-      if (doneRegExp.test(pvalue)) {
-          var pnumval = pvalue.replace(doneRegExp,'');
-          pmodval = pvalue.match(doneRegExp);
-          pvalue = pnumval;
+      if (doneproctorRegExp.test(pvalue)) {
+          pmodval = pvalue.match(doneproctorRegExp);
+          var intervalwithkey = pvalue.replace(doneproctorRegExp,'');
+          if (proctorkeyRegExp.test(intervalwithkey)) {
+              var currvals = intervalwithkey.match(proctorkeyRegExp);
+              if (currvals.length == 3) {
+                  pvalue = currvals[1];
+                  pextraval = currvals[2];
+              } else {
+                  pmodval = '';
+              }
+          }
+      } else {
+          if (doneRegExp.test(pvalue)) {
+              var pnumval = pvalue.replace(doneRegExp,'');
+              pmodval = pvalue.match(doneRegExp);
+              pvalue = pnumval;
+          }
       }
   }
   svalue=pvalue;
@@ -1032,8 +1111,12 @@
   var targ='parent.opener';
   if (pmodal==1) {
      targ='parent.parent';
-  }  
-  selwrite('<a href="javascript:parent.assemble();');
+  }
+  if ((ptype=='date') && (pscat=='interval')) {
+      selwrite('<a href="javascript:parent.validateInterval();');
+  } else {
+      selwrite('<a href="javascript:parent.assemble();');
+  }
   if (preturn!='') {
      selwrite(targ+'.document.'+preturn+'_value.value=parent.window.svalue;');
      selwrite(targ+'.document.'+preturn+'_type.value=parent.window.stype;');


More information about the LON-CAPA-cvs mailing list