--- loncom/homework/edit.pm 2011/11/22 02:13:37 1.138 +++ loncom/homework/edit.pm 2017/10/04 12:55:09 1.155 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # edit mode helpers # -# $Id: edit.pm,v 1.138 2011/11/22 02:13:37 www Exp $ +# $Id: edit.pm,v 1.155 2017/10/04 12:55:09 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -134,10 +134,11 @@ package Apache::edit; use strict; use Apache::lonnet; +use Apache::loncommon; use HTML::Entities(); use Apache::lonlocal; use lib '/home/httpd/lib/perl/'; -use LONCAPA; +use LONCAPA qw(:DEFAULT :match); # Global Vars @@ -161,21 +162,18 @@ sub tag_start { if ($target eq "edit") { my $tag=$token->[1]; if (!$description) { - $description=&Apache::lonxml::description($token); + $description=&mt(&Apache::lonxml::description($token)); if (!$description) { $description="<$tag>"; } } - $result.= &start_table($token)."<tr><td>$description</td> - <td>".&mt('Delete?').' '. - &deletelist($target,$token) - ."</td> - <td>". - &insertlist($target,$token); + $result.= &start_table($token)."<tr><td>".&Apache::loncommon::insert_folding_button(). + " $description</td><td>".&mt('Delete?')." ".&deletelist($target,$token). + "</td><td>".&insertlist($target,$token); #<td>". # &movebuttons($target,$token). # "</tr><tr><td colspan=\"3\">\n"; my @help = Apache::lonxml::helpinfo($token); if ($help[0]) { - $result .= '</td><td align="right" valign="top">' . + $result .= '</td><td class="LC_edit_problem_latexhelper">'. Apache::loncommon::help_open_topic(@help); } else { $result .= "</td><td> "; } $result .= &end_row().&start_spanning_row(); @@ -203,7 +201,7 @@ sub start_table { } $Apache::edit::colordepth++; push(@Apache::edit::inserttag,$token->[1]); - my $result='<div align="right">'; + my $result='<div>'; $result.='<table bgcolor="'.$color.'" width="97%" border="0" cellspacing="3" cellpadding="2">'; return $result; } @@ -211,7 +209,7 @@ sub start_table { sub end_table { $Apache::edit::colordepth--; my $result='</table></div>'; - $result.='<div align="left"><table><tr><td>'; + $result.='<div><table><tr><td>'; my ($tagname,$closingtag); if (defined($Apache::edit::inserttag[-2])) { @@ -232,7 +230,10 @@ sub end_table { return $result; } -sub start_spanning_row { return '<tr><td colspan="5" bgcolor="#F0F0F0">';} +sub start_spanning_row { + return '<tr name="foldblock_'.$Apache::lonxml::curdepth. + '" style="visibility: \'\'"><td colspan="5" bgcolor="#F0F0F0">'; +} sub start_row { return '<tr><td bgcolor="#DDDDDD">'; } sub end_row { return '</td></tr>'; } @@ -296,7 +297,7 @@ sub get_insert_list { my $descrip=$Apache::lonxml::insertlist{"$tag.description"}; my $tagnum =$Apache::lonxml::insertlist{"$tag.num"}; $options{$descrip} ="<option value=\"$tagnum\">". - $descrip."</option>\n"; + &mt($descrip)."</option>\n"; } foreach my $option (sort(keys(%options))) {$result.=$options{$option};} if ($result) { $result='<option selected="selected"></option>'.$result; } @@ -401,10 +402,8 @@ sub insert_functionplotresponse { return ' <functionplotresponse> <functionplotelements> -<spline /> </functionplotelements> <functionplotruleset> -<functionplotrule /> </functionplotruleset> </functionplotresponse>'; } @@ -429,6 +428,12 @@ sub insert_plotvector { <plotvector />'; } +sub insert_drawvectorsum { + return ' +<drawvectorsum />'; +} + + sub insert_functionplotrule { return ' <functionplotrule />'; @@ -484,6 +489,13 @@ sub insert_numericalresponse { </numericalresponse>'; } +sub insert_externalresponse { + return ' +<externalresponse url="" answer="" answerdisplay="" form=""> + <textfield spellcheck="none" /> +</externalresponse>'; +} + sub insert_customresponse { return ' <customresponse> @@ -656,6 +668,9 @@ sub insert_matchresponse { <matchresponse max="10"> <foilgroup options=""> <itemgroup> + <item> + <startouttext /><endouttext /> + </item> </itemgroup> <foil> <startouttext /><endouttext /> @@ -740,6 +755,7 @@ sub js_change_detection { my $unsaved=&mt("There are unsaved changes"); return (<<SCRIPT); <script type="text/javascript"> +// <![CDATA[ var clean = true; var is_submit = false; var still_ask = false; @@ -758,6 +774,7 @@ function unClean() { clean=false; } window.onbeforeunload = compareForm; +// ]]> </script> SCRIPT } @@ -772,14 +789,59 @@ sub element_change_detection { sub submit_ask_anyway { my ($extra_action) = @_; - return ' onclick="still_ask=true;'.$extra_action.'" '; + my $resource = &Apache::loncommon::escape_single($env{'request.ambiguous'}); + return ' onclick="saveScrollPosition(\''.$resource.'\');still_ask=true;'.$extra_action.';" '; } sub submit_dont_ask { my ($extra_action) = @_; - return ' onclick="is_submit=true;'.$extra_action.'" '; + my $resource = &Apache::loncommon::escape_single($env{'request.ambiguous'}); + return ' onclick="saveScrollPosition(\''.$resource.'\');is_submit=true;'.$extra_action.';" '; +} + +sub js_update_linknum { + return (<<SCRIPT); +<script type="text/javascript"> +// <![CDATA[ +function updateNumber(name,index,caller,textprompt) { + var pickitem = document.getElementById(name+'_'+index); + var picknumtext = document.getElementById(name+'_numtext_'+index); + if (pickitem.checked) { + var showval = ''; + if (pickitem.value != 'nochoice') { + showval = pickitem.value; + } + var picknum=prompt(textprompt,showval); + if (picknum == '' || picknum == null) { + if (caller == 'check') { + pickitem.checked=false; + pickitem.value='nochoice'; + } + } else { + picknum.toString(); + var regexdigit=/^\\d+\$/; + if (regexdigit.test(picknum)) { + pickitem.value = picknum; + picknumtext.innerHTML = ' <a href="javascript:updateNumber(\\''+name+'\\',\\''+index+'\\',\\'link\\',\\''+textprompt+'\\');">'+picknum+'</a>'; + } else { + if (caller == 'check') { + pickitem.checked=false; + pickitem.value='nochoice'; + } + return; + } + } + } else { + pickitem.value = ''; + picknumtext.innerHTML = ''; + } } +// ]]> +</script> +SCRIPT + +} sub textarea_sizes { my ($data)=@_; @@ -822,7 +884,7 @@ sub editfield { if ($cols > 80) { $cols = 80; } if ($cols < $minwidth ) { $cols = $minwidth; } if ($rows < $minheight) { $rows = $minheight; } - if ($description) { $description=$description."<br />"; } + if ($description) { $description='<br />'.&mt($description).'<br />'; } # remove typesetting whitespace from between data and the end tag # to make the edit look prettier @@ -834,8 +896,8 @@ sub editfield { $Apache::lonxml::curdepth.'" '.&element_change_detection(). $textareaclass.'>'. &HTML::Entities::encode($data,'<>&"').'</textarea>'. - ($usehtmlarea?&Apache::lonhtmlcommon::spelllink('lonhomework', - 'homework_edit_'.$Apache::lonxml::curdepth):'')."\n"; + ($usehtmlarea?'<br />'.&Apache::lonhtmlcommon::spelllink('lonhomework', + 'homework_edit_'.$Apache::lonxml::curdepth):'')."\n"; } sub modifiedfield { @@ -925,7 +987,7 @@ sub hidden_arg { } sub checked_arg { - my ($description,$name,$list,$token) = @_; + my ($description,$name,$list,$token,$onclick,$useid) = @_; my $result; my $optionlist=""; my $allselected=$token->[2]{$name}; @@ -934,13 +996,13 @@ sub checked_arg { my ($value,$text); if ( ref($option) eq 'ARRAY') { $value='value="'.$$option[0].'"'; - $text=$$option[1]; + $text=&mt($$option[1]); $option=$$option[0]; } else { - $text=$option; + $text=&mt($option); $value='value="'.$option.'"'; } - $result.='<span class="LC_nobreak"><label><input type="checkbox" '.$value.' name="'. + $result.=' <span class="LC_edit_opt"><label><input type="checkbox" '.$value.' name="'. &html_element_name($name).'"'; foreach my $selected (split(/,/,$allselected)) { if ( $selected eq $option ) { @@ -948,20 +1010,26 @@ sub checked_arg { last; } } - $result.=&element_change_detection().' />'.$text.'</label></span>'."\n"; + if ($useid) { + $result .= ' id="'.&html_element_name($name).'" '; + } + $result.=&element_change_detection().$onclick.' />'.$text.'</label></span>'."\n"; } return $result; } sub text_arg { - my ($description,$name,$token,$size) = @_; + my ($description,$name,$token,$size, $class) = @_; my $result; if (!defined $size) { $size=20; } my $arg=$token->[2]{$name}; $result=&mt($description).' <input name="'.&html_element_name($name). - '" type="text" value="'.$arg.'" size="'.$size.'" '. - &element_change_detection().'/>'; - return '<span class="LC_nobreak">'.$result.'</span>'; + '" type="text" value="'.$arg.'" size="'.$size.'" '; + if (defined $class) { + $result .= 'class="' . $class . '" '; + } + $result .= &element_change_detection().'/>'; + return ' <span class="LC_edit_opt">'.$result.'</span>'; } sub select_arg { @@ -987,7 +1055,7 @@ sub select_arg { } } } - $result.='<span class="LC_nobreak">'.&mt($description).' <select name="'. + $result.=' <span class="LC_edit_opt">'.&mt($description).' <select name="'. &html_element_name($name).'" '.&element_change_detection().' > '.$optionlist.' </select></span>'; @@ -1038,16 +1106,16 @@ sub select_or_text_arg { $description=&mt($description); # return (<<ENDSELECTORTYPE); -<span class="LC_nobreak"> + <span class="LC_edit_opt"> $description <select name="$selectelement" -onChange="if ($selectedvalue!='TYPEDINVALUE') { $hiddenvalue=$selectedvalue; $typedinvalue=''; }" > +onchange="if ($selectedvalue!='TYPEDINVALUE') { $hiddenvalue=$selectedvalue; $typedinvalue=''; }" > $optionlist </select> <input type="text" size="$size" name="$typeinelement" value="$typeinvalue" -onChange="$hiddenvalue=$typedinvalue;" -onFocus="$selectedindex=$selecttypeinindex-1;" /> +onchange="$hiddenvalue=$typedinvalue;" +onfocus="$selectedindex=$selecttypeinindex-1;" /> <input type="hidden" name="$element" value="$selected" $change_code /> </span> ENDSELECTORTYPE @@ -1128,52 +1196,162 @@ sub deletecoorddata { &Apache::lonnet::delenv('imagechoice.'); } +#----------------------------------------------------- browse and search links +sub browse_or_search { + my ($id,$mode,$titleid,$only,$crsonly,$usesearch) = @_; + my $output; + my ($cnum,$cdom) = &Apache::loncommon::crsauthor_url(); + if ($cnum) { + my $form = 'lonhomework'; + my ($element,$bretitleelement,$srchtitleelement); + $element = &get_element($id,$mode); + my %lt = &Apache::lonlocal::texthash ( + uacf => 'Use a course file', + uanf => 'Use a new file', + impo => 'Import', + sear => 'Search', + sefi => 'Select File', + upfi => 'Upload File', + dire => 'Directory', + news => 'New sub-directory', + ); + my ($importcrsres,$uploadfile,$allonly); + if ($only) { + $allonly = $only; + if ($crsonly) { + $allonly .= ','.$crsonly; + } + } elsif ($crsonly) { + $allonly = $crsonly; + } + my ($numdirs,$pickfile) = + &Apache::loncommon::import_crsauthor_form($form,'coursepath_'.$element,'coursefile_'.$element,undef,$allonly,$element); + if ($pickfile) { + $importcrsres=(<<CRSRES); + <fieldset id="importcrsresform_$element" style="display:inline;"> + <legend>$lt{'uacf'}</legend> + $pickfile + <input type="button" name="crsres" value="$lt{'sefi'}" onclick="updateCrsFile(this.form,'$element');" /> + </fieldset> +CRSRES + } + my %subdirs; + my $toppath="/priv/$cdom/$cnum"; + my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'}; + &Apache::lonnet::recursedirs(1,'priv',$londocroot,$toppath,'',\%subdirs); + my $numcrsdirs = keys(%subdirs); + my $pickdir; + if ($numcrsdirs) { + $pickdir = $lt{'dire'}.'<select name="crsauthorpath_'.$element.'">'."\n". + '<option value="/">/</option>'."\n"; + foreach my $key (sort { lc($a) cmp lc($b) } (keys(%subdirs))) { + $pickdir .= '<option value="'.$key.'">'.$key.'</option>'."\n"; + } + $pickdir .= '</select><br />'; + } else { + $pickdir = '<input type="hidden" name="crsauthorpath_'.$element.'" value="/" />'."\n"; + } + my $uploadfile =(<<CRSUPL); + <fieldset id="uploadcrsresform_$element" style="display:inline;"> + <legend>$lt{'uanf'}</legend> + <p> + $pickdir + <span class="LC_nobreak">$lt{'news'}? + <label><input type="radio" name="newsubdir_$element" value="0" onclick="toggleNewsubdir(this.form,'$element');" checked="checked" />No</label> + + <label><input type="radio" name="newsubdir_$element" value="1" onclick="toggleNewsubdir(this.form,'$element');" />Yes</label> + </span><span id="newsubdir_$element"></span> + <input type="hidden" name="newsubdirname_$element" id="newsubdirname_$element" value="" autocomplete="off" /> + </p> + <input type="file" id="uploadcrsres_$element" name="uploadcrsres_$element" size="40" /> + <input type="hidden" id="crsuploadto_$element" name="filename_$element" value="$ENV{'REQUEST_URI'}" /> + <input type="submit" id="crsupload_$element" class="LC_uploadcrsres" value="$lt{'upfi'}" /> + <iframe id="crsupload_target_$element" name="crsupload_target_$element" src="" style="width:0px;height:0px;border:0px"></iframe> + </fieldset> +CRSUPL + if ($titleid) { + $bretitleelement=",'$only','','".&escape("$titleid\_$Apache::lonxml::curdepth")."'"; + $srchtitleelement=",'".&escape("$titleid\_$Apache::lonxml::curdepth")."'"; + } else { + $bretitleelement=",'$only'"; + } + $output = '<a href="javascript:toggleChooser(document.'.$form.",'$element'".');">'. + &mt('Choose File').'</a>'. + '<div id="chooser_'.$element.'" style="display:none" class="LC_left_float">'. + '<fieldset><legend>'.&mt('Choose File').'</legend>'; + if ($numdirs) { + $output .= '<label><input type="radio" name="chooser_'.$element.'" value="crsres" onclick="toggleCrsFile(this.form,'."'$element','$numdirs'".')" />'.$lt{'uacf'}.'</label> '; + } + $output .= '<label><input type="radio" name="chooser_'.$element.'" value="upload" onclick="toggleCrsUpload(this.form,'."'$element','$numcrsdirs'".')" />'.$lt{'uanf'}.'</label> '. + '<label><input type="radio" name="chooser_'.$element.'" value="import" onclick="toggleResImport(this.form,'."'$element'".');openbrowser('."'$form','$element'$bretitleelement)".'" />'.$lt{'impo'}.'</label>'; + if ($usesearch) { + $output .= ' <label><input type="radio" name="chooser_'.$element.'" value="search" onclick="opensearcher('."'$form','$element'$srchtitleelement".')" />'.$lt{'sear'}.'</label>'; + } + $output .= '<div id="chooser_'.$element.'_crsres" style="display:none">'. + $importcrsres. + '</div>'. + '<div id="chooser_'.$element.'_upload" style="display:none">'. + $uploadfile. + '</div>'. + '</fieldset></div>'; + + } else { + $output = &browse($id, $mode, $titleid, $only); + if ($usesearch) { + $output .= ' '.&search($id, $mode, $titleid); + } + } + return $output; +} + #----------------------------------------------------- browse sub browse { # insert a link to call up the filesystem browser (lonindexer) my ($id, $mode, $titleid, $only) = @_; + my %lt = &Apache::lonlocal::texthash ( + se => 'Select', + ); my $form = 'lonhomework'; - my $element; - if (! defined($mode) || $mode eq 'attribute') { - $element = &escape("$id\_$Apache::lonxml::curdepth"); - } elsif ($mode eq 'textnode') { # for data between <tag> ... </tag> - $element = &escape('homework_edit_'. - $Apache::lonxml::curdepth); - } + my $element = &get_element($id,$mode); my $titleelement; if ($titleid) { $titleelement=",'$only','','".&escape("$titleid\_$Apache::lonxml::curdepth")."'"; } else { $titleelement=",'$only'"; } - my $result = <<"ENDBUTTON"; -<a href=\"javascript:openbrowser('$form','$element'$titleelement)\"\>Select</a> + return <<"ENDBUTTON"; +<a href=\"javascript:openbrowser('$form','$element'$titleelement)\"\>$lt{'se'}</a> ENDBUTTON - return $result; } -#----------------------------------------------------- browse +#----------------------------------------------------- search sub search { # insert a link to call up the filesystem browser (lonindexer) my ($id, $mode, $titleid) = @_; my $form = 'lonhomework'; - my $element; - if (! defined($mode) || $mode eq 'attribute') { - $element = &escape("$id\_$Apache::lonxml::curdepth"); - } elsif ($mode eq 'textnode') { # for data between <tag> ... </tag> - $element = &escape('homework_edit_'. - $Apache::lonxml::curdepth); - } + my $element = &get_element($id,$mode); my $titleelement; if ($titleid) { $titleelement=",'".&escape("$titleid\_$Apache::lonxml::curdepth")."'"; } + my $linktext = &mt('Search'); my $result = <<"ENDBUTTON"; -<a href=\"javascript:opensearcher('$form','$element'$titleelement)\"\>Search</a> +<a href=\"javascript:opensearcher('$form','$element'$titleelement)\"\>$linktext</a> ENDBUTTON return $result; } +sub get_element { + my ($id,$mode) = @_; + my $element; + if (! defined($mode) || $mode eq 'attribute') { + $element = &escape("$id\_$Apache::lonxml::curdepth"); + } elsif ($mode eq 'textnode') { # for data between <tag> ... </tag> + $element = &escape('homework_edit_'. + $Apache::lonxml::curdepth); + } + return $element; +} 1; __END__