[LON-CAPA-cvs] cvs: modules /gci londocsgci.pm

gci gci@source.lon-capa.org
Mon, 21 Dec 2009 15:51:29 -0000


This is a MIME encoded message

--gci1261410689
Content-Type: text/plain

gci		Mon Dec 21 15:51:29 2009 EDT

  Modified files:              
    /modules/gci	londocsgci.pm 
  Log:
  - Support for two part problems.
    - Client side: javascript to enforce prerequisites are selected.
    - Server side:
      - if checked items include coupled questions when map is written
        prerequisite is replaced with equivalent two-part problem.
      - reverse occurs for editing: two-part question triggers checking of 
        two items for display purposes.
  
  
--gci1261410689
Content-Type: text/plain
Content-Disposition: attachment; filename="gci-20091221155129.txt"

Index: modules/gci/londocsgci.pm
diff -u modules/gci/londocsgci.pm:1.5 modules/gci/londocsgci.pm:1.6
--- modules/gci/londocsgci.pm:1.5	Sun Dec 20 04:32:03 2009
+++ modules/gci/londocsgci.pm	Mon Dec 21 15:51:29 2009
@@ -2,7 +2,7 @@
 # Custom Edit Course Routines for Assembly of Valid Concept Tests from
 # Geoscience Concept Inventory. 
 #
-# $Id: londocsgci.pm,v 1.5 2009/12/20 04:32:03 gci Exp $
+# $Id: londocsgci.pm,v 1.6 2009/12/21 15:51:29 gci Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -44,10 +44,13 @@
 my $path;
 my $version;
 my $reqnum;
+my @mandcats;
+my @bincats;
 my @categories;
 my @allprobs;
 my %probcat;
 my %prereqs;
+my %revreqs;
 my @defchosen;
 my @chosen;
 my @mandprobs;
@@ -90,10 +93,10 @@
               ['63','64','65'],
               ['66','67','68','69','70','71']);
     @optional = ('05','11','29','31');
-
-   @categories=('M1','M2','M3','M4',
-                'A','B','C','D','E','F','G','H','I','J','K');
-   %probcat =('01' => 'M1' ,'02' => 'M2' ,'37' => 'M3' ,'2004_73' => 'M4' ,
+    @mandcats = ('M1','M2','M3','M4');
+    @bincats = ('A','B','C','D','E','F','G','H','I','J','K');
+    @categories=(@mandcats,@bincats);
+    %probcat =('01' => 'M1' ,'02' => 'M2' ,'37' => 'M3' ,'2004_73' => 'M4' ,
               '03' => 'A' ,'04' => 'A','05' => ''  ,'06' => 'A' ,'07' => 'B' ,
               '08' => 'B' ,'09' => 'B' ,'10' => 'C' ,'11' => ''  ,'12' => 'C' ,
               '13' => 'C' ,'14' => 'C' ,'15' => 'C' ,'16' => 'C' ,'17' => 'C' ,'18' => 'D' ,'19' => 'D' ,'20' => 'D' ,
@@ -106,12 +109,15 @@
               '60' => 'I' ,
               '61' => 'I' ,'62' => 'I' ,'63' => 'J' ,'64' => 'J' ,'65' => 'J' ,'66' => 'K' ,'67' => 'K' ,'68' => 'K' ,'69' => 'K' ,'70' => 'K' ,
               '71' => 'K');
-   %mandatory=('01' => 1 ,'02' => 1,'37' => 1, '2004_73' => 1);
-   @mandprobs = ('01','02','37','2004_73');
-   %prereqs=('10' => '08', '57' => '52', '69' => '18');
-   @defchosen=('01','02','03','07','12','18','26','32','37','38','47','54','63','66','2004_73');
-   @development = ('100','101','102');
-   %developmentitems = ('100' => 1, '101' => '1', '102' => '1');
+    %mandatory=('01' => 1 ,'02' => 1,'37' => 1, '2004_73' => 1);
+    @mandprobs = ('01','02','37','2004_73');
+    %prereqs=('10' => '08', '57' => '52', '69' => '18');
+    foreach my $item (keys(%prereqs)) {
+        $revreqs{$prereqs{$item}} = $item;
+    }
+    @defchosen=('01','02','03','07','12','18','26','32','37','38','47','54','63','66','2004_73');
+    @development = ('100','101','102');
+    %developmentitems = ('100' => 1, '101' => '1', '102' => '1');
 }
 
 sub checkvalid {
@@ -134,7 +140,11 @@
    foreach my $item (@chosen) {
        if ($prereqs{$item}) {
           unless ($chosenproblems{$prereqs{$item}}) {
-             push(@errors,&mt('Problem [_1] requires problem [_2].',$item,$prereqs{$item}));
+              my $url = &fullurl($item);
+              my $title = &Apache::lonnet::metadata($url,'title');
+              my $prerequrl = &fullurl($prereqs{$item});
+              my $prereqtitle = &Apache::lonnet::metadata($prerequrl,'title');
+              push(@errors,&mt('[_1] requires [_2].',"'$title'","'$prereqtitle'"));
           }
        }
    }
@@ -143,10 +153,17 @@
 
 sub fullurl {
    my ($item)=@_;
-   unless ($item=~/\_/) { $item='_'.$item; }
+   unless ($item=~/^\_/) { $item='_'.$item; }
    return $path.'/'.$version.'/GCI'.$item.'.problem';
 }
 
+sub item_from_url {
+    my ($url)=@_;
+    if ($url =~ m{\Q$path\E/\Q$version\E/GCI_([^.]+)\.problem$}) {
+        return $1;
+    }
+}
+
 sub validcheck {
    my ($r)=@_;
    my @errors=&checkvalid();
@@ -207,7 +224,7 @@
                 &Apache::lonhtmlcommon::start_pick_box().
                 &Apache::lonhtmlcommon::row_title(&mt('Open date')).
                 $startform.
-                &Apache::lonhtmlcommon::row_closure().
+                &Apache::lonhtmlcommon::row_closure(1).
                 &Apache::lonhtmlcommon::row_title(&mt('Close date')).
                 $endform.
                  &Apache::lonhtmlcommon::end_pick_box().'<br />'. 
@@ -300,7 +317,26 @@
         } else {
             $output .= '<input type="checkbox" name="item'.$item.'"';
             if ($chosenitems->{$item}) { $output .= ' checked="checked"'; }
-            $output .= 'onclick="javascript:countChecked('."'$catname'".');" />'.
+            $output .= ' onclick="countChecked('."'$catname'".');';
+            my $binname;
+            if ($prereqs{$item}) {
+                for (my $i=0; $i<@bincats; $i++) {
+                    if ($bincats[$i] eq $probcat{$prereqs{$item}}) {
+                        $binname = 'bin'.$i; 
+                        last;
+                    }
+                }
+                $output .= 'checkPrereqs('."'dep','$item','$prereqs{$item}','$binname'".');';
+            } elsif ($revreqs{$item}) {
+                for (my $i=0; $i<@bincats; $i++) {
+                    if ($bincats[$i] eq $probcat{$item}) {
+                        $binname = 'bin'.$i;
+                        last;
+                    }
+                }
+                $output .= 'checkPrereqs('."'pre','$revreqs{$item}','$item','$binname'".');';
+            }
+            $output .= '" />'.
                        '<input type="hidden" name="container'.$item.'" value="'.
                        $catname.'"></td><td>';
         }
@@ -369,9 +405,16 @@
    for (my $idx=0;$idx<=$#allprobs;$idx++) {
        my $residx=$idx+1;
        if ($chosenproblems{$allprobs[$idx]}) {
+          my $url  = &LONCAPA::map::qtunescape(&fullurl($allprobs[$idx]));
+          if (($revreqs{$allprobs[$idx]}) && 
+              ($chosenproblems{$revreqs{$allprobs[$idx]}})) {
+              my $probnum = $allprobs[$idx].'_'.$revreqs{$allprobs[$idx]};
+              $url = &LONCAPA::map::qtunescape(&fullurl($probnum));
+          } elsif ($prereqs{$allprobs[$idx]}) {
+              next;
+          }
           push(@LONCAPA::map::order,$residx);
           $counter ++;
-          my $url  = &LONCAPA::map::qtunescape(&fullurl($allprobs[$idx]));
 	  my $name = &LONCAPA::map::qtunescape('Problem '.$counter);
 	  $LONCAPA::map::resources[$residx]=join(':', ($name, $url, 'false', 'normal', 'res'));
        }
@@ -381,9 +424,15 @@
 sub map_to_chosen {
     @chosen=();
     foreach my $idx (@LONCAPA::map::order) {
-       my ($title,$url)=split(':',$LONCAPA::map::resources[$LONCAPA::map::order[$idx]]);
+       my ($title,$url)=split(':',$LONCAPA::map::resources[$idx]);
+       my $item;
        unless ($url eq '') {
-           push(@chosen,$allprobs[$idx-1]);
+           $item = &item_from_url($url);
+           if (($item =~ /^(\d+)_(\d+)$/) && ($prereqs{$2} eq $1)) {
+               push(@chosen,($1,$2));
+           } else {
+               push(@chosen,$item);
+           }
        }
     }
     if (($env{'form.concepttest'} eq 'defchosen') || 
@@ -400,9 +449,16 @@
    my @errors=&checkvalid();
    if (@errors > 0) {
        if (($caller eq 'requestcrs') && ($env{'form.concepttest'} eq 'defchosen')) {
-           return 'Invalid concept test.';
+           return &mt('Invalid concept test.');
        } else {
-           return;
+           my $errormsg = '<span class="LC_warning">'.&mt('Invalid concept test:');
+           if (@errors > 1) {
+               $errormsg .= '<ul><li>'.join('</li><li>',@errors).'</li></ul>';
+           } else {
+               $errormsg .= '<br />'.$errors[0];
+           }
+           $errormsg .= '</span>';
+           return $errormsg;
        }
    }
    &chosen_to_map();
@@ -518,6 +574,58 @@
                                           show => 'Show',
                                           hide => 'Hide',
                                         );
+    my $prereqjs = "
+function checkPrereqs(caller,item,prereq,binname) {
+    var changedPrereq = 0;
+    if (document.selecteditems.elements['item'+item].checked == false) {
+        return;
+    } else {
+        if (!document.selecteditems.elements['item'+prereq].checked) {
+            document.selecteditems.elements['item'+prereq].checked = true;
+            changedPrereq = 1;
+            countChecked(binname);
+        }
+    }
+";
+    
+    my ($hasdep,$prereq,$hasdeptitle,$prereqtitle) = ('','','','');
+    foreach my $item (sort(keys(%prereqs))) {
+        $hasdep .= "'$item',";
+        $prereq .= "'$prereqs{$item}',";
+        my $url = &fullurl($item);
+        $hasdeptitle .= "'".&Apache::lonnet::metadata($url,'title')."',";
+        my $purl = &fullurl($prereqs{$item});
+        $prereqtitle .= "'".&Apache::lonnet::metadata($purl,'title')."',";
+    }
+    $hasdep =~ s/,$//;
+    $prereq =~ s/,$//;
+    $hasdeptitle =~ s/,$//;
+    $prereqtitle =~ s/,$//;
+
+    $prereqjs .= <<"ENDFN";
+
+    var hasDeps = Array($hasdep);
+    var preReqs = Array($prereq);
+    var hasDepTitles = Array($hasdeptitle);
+    var preReqTitles = Array($prereqtitle);
+    for (var i=0; i<hasDeps.length; i++) {
+        if (hasDeps[i] == item) {
+            var msg = hasDepTitles[i]+' question has a prerequisite: '+preReqTitles[i]+'.\\nThe two questions will appear together in a composite question.';
+            if (changedPrereq == 1) {
+                msg = msg+'\\n\\nAs the prerequisite was not checked, inclusion of '+hasDepTitles[i]+' has now caused '+preReqTitles[i]+' to also be checked automatically.';
+            }
+            if (caller == 'pre') {
+                msg = msg +'\\n\\nIf you do not wish to include '+preReqTitles[i]+' you will first need to uncheck '+hasDepTitles[i]+', then uncheck '+preReqTitles[i]+' again.'
+            }
+            alert(msg);
+            break;
+        }
+    }
+    return;
+}
+
+ENDFN
+
     return <<ENDJS;
 function showQuestions(content,title) {
     document.getElementById(content).style.display = "";
@@ -598,6 +706,8 @@
     return;
 }
 
+$prereqjs
+
 ENDJS
 
 }

--gci1261410689--