quiz editing: MDL-17285 This is Olli Savolainen's new interface for editing quizzes.

This was started and usability tested as a Finnish Summer of Code project, and then Olli did further work on it in his own time to get it in shape for inclusion in Moodle 2.0. I reviewed all the code. There are a number of minor outstanding issues that will be fixed soon. See the subtasks of MDL-17284 for a list.

The goal of these changes is to:
* help teachers new to Moodle, so when they first see the quiz editing page, they don't go "Huh! What on earth am I supposed to do here?"
* help novice Moodle users understand and learn to use some of the more advanced quiz feature;
* but, without slowing down more experienced quiz users.

Naturally, with ambitous goals like that, we won't have managed to satisy everybody, but I think this change is a big step in the right direction.

There is extensive documentation on this project at http://docs.moodle.org/en/Development:Quiz_UI_redesign.
This commit is contained in:
tjhunt
2008-11-20 06:59:11 +00:00
parent b7cebc8ebc
commit fa583f5f6e
20 changed files with 3311 additions and 581 deletions
+25
View File
@@ -0,0 +1,25 @@
<h1>Basic ideas of making quizzes</h1>
<p>The main concepts while managing quiz content (questions) are:</p>
<ul>
<li>Quiz and pages</li>
<li>Question bank and its categories</li>
<li>Random question</li>
</ul>
<p>You can think of a <strong>quiz</strong>, in essence, to be like a
traditional pen&amp;paper quiz (or an exam/test). It contains questions.
You can divide the questions in a quiz on several <strong>pages</strong>
or you can keep them all on one page.
With Moodle Quiz, you can also give the grading beforehand for the
questions in a quiz (as well as the total for the entire quiz).</p>
<p>When you create questions, they are stored in the <strong>Question
Bank</strong>. In the Question Bank you can create categories, which are similar
to folders. You can use them to create a hierarchy for organizing
questions, for example, by topic. When you create a question into
an exam, a copy of it is stored in the Question Bank. If you decide to
remove your question from an exam, it will still be intact in the
question bank until you delete it from there, too.</p>
<p>You can use <strong>Random Questions</strong>, if you want a question to
vary between different attempts students make at the quiz (for example,
to avoid cheating by means of students copying questions to each other).
Just create a random question in the quiz and add questions in the
category of the random question.</p>
+40 -1
View File
@@ -678,5 +678,44 @@ $string['youcannotwait'] = 'This quiz closes before you will be allowed to start
$string['youneedtoenrol'] = 'You need to enrol in this course before you can attempt this quiz';
$string['yourfinalgradeis'] = 'Your final grade for this quiz is $a.';
$string['zerosignificantfiguresnotallowed'] = 'The correct answer cannot have zero significant figures!';
$string['totalquestionsinrandomqcategory'] = 'Total of $a questions in category.';
$string['selectquestiontype'] = ' -- Select question type -- ';
$string['adddescriptionlabel'] = 'Add description/label';
$string['addrandomquestion'] = 'Add random question';
$string['addrandomquestiontoquiz'] = 'Add random question to quiz $a';
$string['parentcategory'] = 'Parent category';
$string['selectcategory'] = 'Select category';
$string['createcategoryfornewrandomquestion'] = 'Create a question category for the new random question';
$string['qname'] = 'name';
$string['qtypename'] = 'type, name';
$string['age'] = 'age';
$string['sortquestionsbyx'] = 'Sort questions by: $a';
$string['addpagehere'] = 'Add page here';
$string['questionbankmanagement'] = 'Question Bank management';
$string['totalpoints'] = 'Total of grades';
$string['quizwillopen'] = 'This quiz will open $a';
$string['quizopenwillclose'] = 'This quiz is open, will close on $a at ';
$string['basicideasofquiz'] = 'Basic ideas of making quizzes';
$string['noquestionsinquiz'] = 'There are no questions in this quiz.';
$string['addquestion'] = 'Add question';
$string['questiontextisempty'] = '[Empty question text]';
$string['addrandomfromcategory'] = 'Add random questions from category';
$string['fromcategory'] = 'from category';
$string['questionbankcontents'] = 'Question Bank contents';
$string['quizorderrandom'] = '* Order of quiz is shuffled';
$string['quizordernotrandom'] = 'Order of quiz not shuffled';
$string['repaginatecommand'] = 'Repaginate';
$string['orderandpaging'] = 'Order and paging';
$string['noquestionsonpage'] = 'Empty page';
$string['orderingquiz'] = 'Order and paging';
$string['moveselectedonpage'] = 'Move selected questions to page';
$string['addnewpagesafterselected'] = 'Add new pages after selected questions';
$string['reorderquestions'] = 'Reorder questions';
$string['noquestionsnotinuse'] = 'This random question is not in use, since its category is empty.';
$string['addnewquestionsqbank'] = 'Add questions to the category $a in the \'Question bank contents\' tool >>';
$string['empty'] = 'Empty';
$string['quizopened'] = 'This quiz is open.';
$string['areyousuredeleteselected'] = 'Are you sure you want to delete the selected questions?';
$string['questionsperpageselected'] = 'Questions per page has been set so the paging is currently fixed. As a result, the paging controls have been disabled. You can change this in ';
$string['shufflequestionsselected'] = '* Shuffle questions has been set so question order is random. As a result, the button Reorder questions has been disabled. You can change this in ';
?>
+34 -23
View File
@@ -717,7 +717,7 @@ function close_window($delay=0) {
* @param mixed $listbox if false, display as a dropdown menu. If true, display as a list box.
* By default, the list box will have a number of rows equal to min(10, count($options)), but if
* $listbox is an integer, that number is used for size instead.
* @param
* @param
*/
function choose_from_menu ($options, $name, $selected='', $nothing='choose', $script='',
$nothingvalue='0', $return=false, $disabled=false, $tabindex=0,
@@ -990,26 +990,30 @@ function print_textfield ($name, $value, $alt = '',$size=50,$maxlength=0, $retur
/**
* Implements a complete little popup form
* Implements a complete little form with a dropdown menu. When JavaScript is on
* selecting an option from the dropdown automatically submits the form (while
* avoiding the usual acessibility problems with this appoach). With JavaScript
* off, a 'Go' button is printed.
*
* @uses $CFG
* @param string $common The URL up to the point of the variable that changes
* @param array $options Alist of value-label pairs for the popup list
* @param string $formid Id must be unique on the page (originaly $formname)
* @param string $selected The option that is already selected
* @param string $baseurl The target URL up to the point of the variable that changes
* @param array $options A list of value-label pairs for the popup list
* @param string $formid id for the control. Must be unique on the page. Used in the HTML.
* @param string $selected The option that is initially selected
* @param string $nothing The label for the "no choice" option
* @param string $help The name of a help page if help is required
* @param string $helptext The name of the label for the help button
* @param boolean $return Indicates whether the function should return the text
* @param boolean $return Indicates whether the function should return the HTML
* as a string or echo it directly to the page being rendered
* @param string $targetwindow The name of the target page to open the linked page in.
* @param string $selectlabel Text to place in a [label] element - preferred for accessibility.
* @param array $optionsextra TODO, an array?
* @param array $optionsextra an array with the same keys as $options. The values are added within the corresponding <option ...> tag.
* @param string $submitvalue Optional label for the 'Go' button. Defaults to get_string('go').
* @param boolean $disabled If true, the menu will be displayed disabled.
* @return string If $return is true then the entire form is returned as a string.
* @todo Finish documenting this function<br>
*/
function popup_form($common, $options, $formid, $selected='', $nothing='choose', $help='', $helptext='', $return=false,
$targetwindow='self', $selectlabel='', $optionsextra=NULL) {
function popup_form($baseurl, $options, $formid, $selected='', $nothing='choose', $help='', $helptext='', $return=false,
$targetwindow='self', $selectlabel='', $optionsextra=NULL, $submitvalue='', $disabled=false) {
global $CFG, $SESSION;
static $go, $choose; /// Locally cached, in case there's lots on a page
@@ -1018,16 +1022,23 @@ $targetwindow='self', $selectlabel='', $optionsextra=NULL) {
return '';
}
if (!isset($go)) {
$go = get_string('go');
if (empty($submitvalue)){
if (!isset($go)) {
$go = get_string('go');
$submitvalue=$go;
}
}
if ($nothing == 'choose') {
if (!isset($choose)) {
$choose = get_string('choose');
}
$nothing = $choose.'...';
}
if ($disabled) {
$disabled = 'disabled="disabled"';
} else {
$disabled = '';
}
// changed reference to document.getElementById('id_abc') instead of document.abc
// MDL-7861
@@ -1046,16 +1057,16 @@ $targetwindow='self', $selectlabel='', $optionsextra=NULL) {
$selectlabel = '<label for="'.$formid.'_jump">'.$selectlabel.'</label>';
}
//IE and Opera fire the onchange when ever you move into a dropdwown list with the keyboard.
//IE and Opera fire the onchange when ever you move into a dropdown list with the keyboard.
//onfocus will call a function inside dropdown.js. It fixes this IE/Opera behavior.
//Note: There is a bug on Opera+Linux with the javascript code (first mouse selection is inactive),
//so we do not fix the Opera behavior on Linux
if (check_browser_version('MSIE') || (check_browser_version('Opera') && !check_browser_operating_system("Linux"))) {
$output .= '<div>'.$selectlabel.$button.'<select id="'.$formid.'_jump" onfocus="initSelect(\''.$formid.'\','.$targetwindow.')" name="jump">'."\n";
$output .= '<div>'.$selectlabel.$button.'<select id="'.$formid.'_jump" onfocus="initSelect(\''.$formid.'\','.$targetwindow.')" name="jump" '.$disabled.'>'."\n";
}
//Other browser
else {
$output .= '<div>'.$selectlabel.$button.'<select id="'.$formid.'_jump" name="jump" onchange="'.$targetwindow.'.location=document.getElementById(\''.$formid.'\').jump.options[document.getElementById(\''.$formid.'\').jump.selectedIndex].value;">'."\n";
$output .= '<div>'.$selectlabel.$button.'<select id="'.$formid.'_jump" name="jump" onchange="'.$targetwindow.'.location=document.getElementById(\''.$formid.'\').jump.options[document.getElementById(\''.$formid.'\').jump.selectedIndex].value;" '.$disabled.'>'."\n";
}
if ($nothing != '') {
@@ -1105,10 +1116,10 @@ $targetwindow='self', $selectlabel='', $optionsextra=NULL) {
} else {
if (!empty($CFG->usesid) && !isset($_COOKIE[session_name()]))
{
$url = $SESSION->sid_process_url( $common . $value );
$url = $SESSION->sid_process_url( $baseurl . $value );
} else
{
$url=$common . $value;
$url=$baseurl . $value;
}
$optstr = ' <option value="' . $url . '"';
@@ -1144,7 +1155,7 @@ $targetwindow='self', $selectlabel='', $optionsextra=NULL) {
$output .= '</select>';
$output .= '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
$output .= '<div id="noscript'.$formid.'" style="display: inline;">';
$output .= '<input type="submit" value="'.$go.'" /></div>';
$output .= '<input type="submit" value="'.$submitvalue.'" '.$disabled.' /></div>';
$output .= '<script type="text/javascript">'.
"\n//<![CDATA[\n".
'document.getElementById("noscript'.$formid.'").style.display = "none";'.
@@ -2068,7 +2079,7 @@ function get_emoticons_list_for_help_file(){
$formname = 'theform';
$fieldname = 'message';
}
$output .= print_js_call('emoticons_help.init', array($formname, $fieldname, 'emoticonlist'), true);
return $output;
@@ -2596,7 +2607,7 @@ function print_header ($title='', $heading='', $navigation='', $focus='',
* require_once in PHP.
*
* There are two special-case calls to this function from print_header which are
* internal to weblib and use the second $extracthtmlparameter:
* internal to weblib and use the second $extracthtml parameter:
* $extracthtml = 1: this is used before printing the header.
* It returns the script tag code that should go inside the <head>.
* $extracthtml = 2: this is used after printing the header and handles any
@@ -2754,7 +2765,7 @@ function print_delayed_js_call($delay, $function, $args = array(), $return = fal
* variable, and then just output the configuration variables from PHP using
* this function.
*
* For example, look at the code in question_init_qenginejs_script() in
* For example, look at the code in question_init_qenginejs_script() in
* lib/questionlib.php. It writes out a bunch of $settings like
* 'pixpath' => $CFG->pixpath, with $prefix = 'qengine_config'. This gets output
* in print_header, then the code in question/qengine.js can access these variables
+73
View File
@@ -0,0 +1,73 @@
<?php // $Id$
/**
* Fallback page of /mod/quiz/edit.php add random question dialog,
* for users who do not use javascript.
*
* @author Olli Savolainen, as a part of the Quiz UI Redesign project in Summer 2008
* {@link http://docs.moodle.org/en/Development:Quiz_UI_redesign}.
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package quiz
*/
require_once("../../config.php");
require_once($CFG->dirroot.'/mod/quiz/editlib.php');
require_once($CFG->dirroot."/question/category_class.php");
list($thispageurl, $contexts, $cmid, $cm, $quiz, $pagevars) = question_edit_setup('editq', true);
$defaultcategoryobj = question_make_default_categories($contexts->all());
$defaultcategoryid=$defaultcategoryobj->id;
$defaultcategorycontext=$defaultcategoryobj->contextid;
$defaultcategory="$defaultcategoryid,$defaultcategorycontext";
$qcobject = new question_category_object(
$pagevars['cpage'],
$thispageurl,
$contexts->having_one_edit_tab_cap('categories'),
$defaultcategoryid,
$defaultcategory,
null,
$contexts->having_cap('moodle/question:add'));
//setting the second parameter of process_randomquestion_formdata to true causes it to redirect on success
//TODO: process if returns false?
quiz_process_randomquestion_formdata($qcobject,true, $cmid);
//these params are only passed from page request to request while we stay on this page
//otherwise they would go in question_edit_setup
$quiz_page = optional_param('quiz_page', 0, PARAM_SEQUENCE);
$returnurl = optional_param('returnurl', 0, PARAM_LOCALURL);
$strquizzes = get_string('modulenameplural', 'quiz');
$strquiz = get_string('modulename', 'quiz');
$streditingquestions = get_string('editquestions', "quiz");
$streditingquiz = get_string('editinga', 'moodle', $strquiz);
// Get the course object and related bits.
if (! $course = $DB->get_record("course", array("id"=> $quiz->course))) {
error("This course doesn't exist");
}
// TODO: Log this visit.
/*
add_to_log($cm->course, 'quiz', 'editquestions',
"view.php?id=$cm->id", "$quiz->id", $cm->id);
*/
//you need mod/quiz:manage in addition to question capabilities to access this page.
require_capability('mod/quiz:manage', $contexts->lowest());
// Print basic page layout.
$strupdatemodule = has_capability('moodle/course:manageactivities', $contexts->lowest())
? update_module_button($cm->id, $course->id, get_string('modulename', 'quiz'))
: "";
$navigation = build_navigation($streditingquiz, $cm);
print_header_simple($streditingquiz, '', $navigation, "", "", true, $strupdatemodule);
if (!$quizname = $DB->get_field($cm->modname, 'name', array('id'=> $cm->instance))) {
error('Cannot get the module name in build navigation.');
}
print_heading(get_string("addrandomquestiontoquiz","quiz",$quizname), 'left', 2);
$qcobject->display_randomquestion_user_interface();
print_footer($course);
?>
+130
View File
@@ -0,0 +1,130 @@
/** JavaScript for /mod/quiz/edit.php
*/
YAHOO.namespace("cats.container");
YAHOO.namespace("quiz.container");
function init() {
YAHOO.util.Dom.setStyle('randomquestiondialog', 'display', 'block');
YAHOO.cats.container.module = new YAHOO.widget.Module("module");
YAHOO.cats.container.show = new YAHOO.widget.Module("show");
YAHOO.cats.container.hide = new YAHOO.widget.Module("hide");
YAHOO.cats.container.module.render();
YAHOO.util.Event.addListener("show", "click", YAHOO.cats.container.module.show,
YAHOO.cats.container.module, true);
YAHOO.util.Event.addListener("show", "click",
function(e){
YAHOO.cats.container.hide.show;
// for some reason YUI sets element display "block" so we have to reverse that:
hideel.setStyle("display", "inline");
//TODO: get sURL from the phpdata object somehow
var sUrl="";
var transaction = YAHOO.util.Connect.asyncRequest("GET", sUrl, null, null);
YAHOO.util.Event.stopEvent(e);
}, YAHOO.cats.container.hide, true);
YAHOO.util.Event.addListener("show", "click", YAHOO.cats.container.show.hide, YAHOO.cats.container.show, true);
YAHOO.util.Event.addListener("hide", "click", YAHOO.cats.container.module.hide, YAHOO.cats.container.module, true);
YAHOO.util.Event.addListener("hide", "click",
function(e){
YAHOO.cats.container.show.show;
// for some reason YUI sets element display
// to "block" so we have to reverse that:
showel.setStyle("display", "inline");
var sUrl="$surl";
var transaction = YAHOO.util.Connect.asyncRequest("GET", sUrl, null, null);
YAHOO.util.Event.stopEvent(e);
}, YAHOO.cats.container.show, true);
YAHOO.util.Event.addListener("hide", "click", YAHOO.cats.container.hide.hide, YAHOO.cats.container.hide, true);
// Instantiate the Dialog
/* zIndex must be way above 99 to be above the active quiz tab*/
YAHOO.quiz.container.randomquestiondialog = new YAHOO.widget.Dialog("randomquestiondialog",
{
constraintoviewport : true,
visible : false,
modal:true,
width : "100%",
iframe:true,
zIndex:1000,
fixedcenter : true,
close: true,
draggable: true,
dragOnly: true,
postmethod: "form"
} );
//show the dialog and depending on from which form (corresponding
// a specific quiz page) it was triggered, set the value of the form's
// rqpage input element to the form number
YAHOO.util.Event.addListener(this.dialog_listeners, "click",
function(e){
this.show();
var rbutton = YAHOO.util.Event.getTarget(e);
var rbform = YAHOO.util.Dom.getAncestorByClassName(rbutton,"randomquestionform");
//this depends on the fact that the element hierarchy be:
// <form class="randomquestionform"><div>[input elements]</div></form>
var rbformelements = YAHOO.util.Dom.getChildren
(YAHOO.util.Dom.getFirstChild(rbform));
var rqpage=YAHOO.util.Dom.get("rform_qpage");
/*
//this should work, it doesn't, no time to debug.
var rqpagehiddenel=YAHOO.util.Dom.getFirstChildBy(rbformelements,function(el) {
//alert("infunc");
var result=YAHOO.util.Dom.hasClass(el,"addonpage_formelement");
//if (result) alert ("yes"); else alert("no");
return result;
});
//no element in rqpagehiddenel
//rqpage.value=rqpagehiddenel.value.value;
*/
//this works instead
for (var i = 0; i < rbformelements.length; i++) {
if(YAHOO.util.Dom.hasClass(rbformelements[i],"addonpage_formelement")){
//why is this not rqpage.value.value, the first "value" being the element property
// and the second the value of that property? I don't understand.
rqpage.value=rbformelements[i].attributes.value.value;
}
}
YAHOO.util.Event.stopEvent(e);
}, YAHOO.quiz.container.randomquestiondialog,
YAHOO.quiz.container.randomquestiondialog, true);
YAHOO.quiz.container.randomquestiondialog.render();
// Instantiate the Dialog
YAHOO.quiz.container.repaginatedialog = new YAHOO.widget.Dialog("repaginatedialog",
{
modal:true,
width : "100%",
iframe:true,
zIndex:1000,
fixedcenter : true,
visible : false,
close: true,
draggable: true,
dragOnly: true,
constraintoviewport : true,
postmethod: "form"
} );
YAHOO.util.Event.addListener("repaginatecommand", "click",
function(e){
YAHOO.util.Dom.setStyle('repaginatedialog', 'display', 'block');
this.show();
}, YAHOO.quiz.container.repaginatedialog,
YAHOO.quiz.container.repaginatedialog, true);
YAHOO.quiz.container.repaginatedialog.render();
}
YAHOO.util.Event.addListener(window, "load", init,phpGenerated,true);
YAHOO.util.Dom.setStyle('repaginatedialog', 'display', 'block');
//TODO: take this inside the init function to make sure
//YAHOO.cats.container.module is defined when run
if (YAHOO.cats.container.module && quiz_qbanktool){
YAHOO.cats.container.module.hide();
YAHOO.cats.container.show.show();
showel.setStyle("display", "inline");
YAHOO.cats.container.hide.hide();
}
+782 -302
View File
File diff suppressed because it is too large Load Diff
+7
View File
@@ -0,0 +1,7 @@
/** JavaScript for /mod/quiz/edit.php to be loaded in the header
* Adds a CSS class to display edit.php for users with JavaScript.
*/
YAHOO.util.Event.onDOMReady(
function(){
YAHOO.util.Dom.addClass('quizcontentsblock', 'usejs');
});
+1271 -200
View File
File diff suppressed because it is too large Load Diff
+118 -7
View File
@@ -81,9 +81,9 @@ function quiz_create_attempt($quiz, $attemptnumber, $lastattempt, $timenow, $isp
$attempt->userid = $USER->id;
$attempt->preview = 0;
if ($quiz->shufflequestions) {
$attempt->layout = quiz_repaginate($quiz->questions, $quiz->questionsperpage, true);
$attempt->layout = quiz_clean_layout(quiz_repaginate($quiz->questions, $quiz->questionsperpage, true),true);
} else {
$attempt->layout = $quiz->questions;
$attempt->layout = quiz_clean_layout($quiz->questions,true);
}
} else {
/// Build on last attempt.
@@ -229,7 +229,15 @@ function quiz_questions_on_page($layout, $page) {
* So 5,2,0,3,0 means questions 5 and 2 on page 1 and question 3 on page 2
*/
function quiz_questions_in_quiz($layout) {
return str_replace(',0', '', $layout);
if($layout){
$layout=str_replace(',0', '', $layout);
//remove also the zero in the beginning, if any
if(isset($layout[0]) && $layout[0]=="0" &&
isset($layout[1]) && $layout[1]==","){
$layout=substr($layout,2);
}
}
return $layout;
}
/**
@@ -239,7 +247,31 @@ function quiz_questions_in_quiz($layout) {
* @param string $layout The string representing the quiz layout.
*/
function quiz_number_of_pages($layout) {
return substr_count($layout, ',0');
$count=0;
if($layout){
//if the first page is empty, include it, too
if (strcmp($layout[0],"0")===0){
$count++;
}
$count+=substr_count($layout, ',0');
}
return $count;
}
/**
* Returns the number of questions in the quiz layout
*
* @return integer Comma separated list of question ids
* @param string $layout The string representing the quiz layout.
*/
function quiz_number_of_questions_in_quiz($layout) {
//TODO: clean layout before counting
//TODO: remove page breaks
$layout=quiz_questions_in_quiz($layout);
$count=substr_count($layout, ',');
if($count>0){
$count++;
}
return $count;
}
/**
@@ -275,6 +307,10 @@ function quiz_first_questionnumber($quizlayout, $pagelayout) {
function quiz_repaginate($layout, $perpage, $shuffle=false) {
$layout = str_replace(',0', '', $layout); // remove existing page breaks
$questions = explode(',', $layout);
//remove empty pages from beginning
while (reset($questions) == '0') {
array_shift($questions);
}
if ($shuffle) {
srand((float)microtime() * 1000000); // for php < 4.2
shuffle($questions);
@@ -705,7 +741,7 @@ function quiz_question_action_icons($quiz, $cmid, $question, $returnurl){
$stredit = get_string('edit');
$strview = get_string('view');
}
$html ='';
$html ='';
if (($question->qtype != 'random')){
$html .= quiz_question_preview_button($quiz, $question);
}
@@ -727,15 +763,19 @@ function quiz_question_action_icons($quiz, $cmid, $question, $returnurl){
* @param object $question the question
* @return the HTML for a preview question icon.
*/
function quiz_question_preview_button($quiz, $question) {
function quiz_question_preview_button($quiz, $question, $label=true) {
global $CFG, $COURSE;
if (!question_has_capability_on($question, 'use', $question->category)){
return '';
}
$strpreview = get_string('previewquestion', 'quiz');
$strpreviewlabel="";
if($label){
$strpreviewlabel = " ".get_string('preview', 'quiz');
}
$quizorcourseid = $quiz->id?('&amp;quizid=' . $quiz->id):('&amp;courseid=' .$COURSE->id);
return link_to_popup_window('/question/preview.php?id=' . $question->id . $quizorcourseid, 'questionpreview',
"<img src=\"$CFG->pixpath/t/preview.gif\" class=\"iconsmall\" alt=\"$strpreview\" />",
"<img src=\"$CFG->pixpath/t/preview.gif\" class=\"iconsmall\" alt=\"$strpreview\" />$strpreviewlabel",
0, 0, $strpreview, QUESTION_PREVIEW_POPUP_OPTIONS, true);
}
@@ -1085,7 +1125,78 @@ function quiz_send_notification_emails($course, $quiz, $attempt, $context, $cm)
// return the number of successfully sent emails
return $emailresult['good'];
}
function print_timing_information($quiz,$showopenstatus=false){
$timenow = time();
$available = ($quiz->timeopen < $timenow and ($timenow < $quiz->timeclose or !$quiz->timeclose));
if ($available) {
if ($quiz->timelimit) {
echo get_string("quiztimelimit","quiz", format_time($quiz->timelimit * 60))."</p>";
}
if ($quiz->timeopen) {
echo get_string('quizopens', 'quiz'), ': ', userdate($quiz->timeopen);
}
if ($quiz->timeclose) {
echo get_string('quizcloses', 'quiz'), ': ', userdate($quiz->timeclose);
}
if($showopenstatus){
if(!$quiz->timelimit && !$quiz->timeopen && !$quiz->timeclose){
echo get_string('quizopened', 'quiz');
}
}
} else if ($timenow < $quiz->timeopen) {
echo get_string("quiznotavailable", "quiz", userdate($quiz->timeopen));
} else {
echo get_string("quizclosed", "quiz", userdate($quiz->timeclose));
}
return $available;
}
function quiz_clean_layout($layout,$removeemptypages=false){
//remove duplicate "," (or triple, or...)
while(strstr($layout,",,")){
$layout = str_replace(',,', ',', $layout);
}
//remove duplicate question ids
$layout_arr=explode(",",$layout);
$new_arr=array();
$seen=array();
//remove duplicate questions
foreach($layout_arr as $key=>$value){
if(!in_array($value,$seen) && $value!=0){
$new_arr[]=$value;
$seen[]=$value;
}else if($value==0){
$new_arr[]=0;
}
}
if($removeemptypages){
// Avoid duplicate page breaks
// Go through all the array keys
for($i=0;$i<count($new_arr);$i++){
//check if the current position and the one after are both zeros
//remove the one after until they are not both zeros
while(isset($new_arr[$i+1]) &&
$new_arr[$i]==0 &&
$new_arr[$i+1]==0){
print_r($new_arr);
array_splice($new_arr,$i+1,1);
}
}
}
$layout=implode(",",$new_arr);
//remove extra "," from beginning and end
$layout=trim($layout, ",");
//add a ",0" (page break) at the end if there is none
$layoutlength=strlen($layout);
$last=(strlen($layout)-1);
if($layoutlength>1 AND
!($layout[$last-1] == ',' AND $layout[$last] == '0')){
$layout .= ',0';
}
return $layout;
}
/**
* Print a quiz error message. This is a thin wrapper around print_error, for convinience.
*
+8 -5
View File
@@ -31,7 +31,7 @@ $tabs = array();
$row = array();
$inactive = array();
$activated = array();
$stredit=get_string('edit');
if (has_capability('mod/quiz:view', $context)) {
$row[] = new tabobject('info', "$CFG->wwwroot/mod/quiz/view.php?id=$cm->id", get_string('info', 'quiz'));
}
@@ -39,10 +39,11 @@ if (has_capability('mod/quiz:viewreports', $context)) {
$row[] = new tabobject('reports', "$CFG->wwwroot/mod/quiz/report.php?q=$quiz->id", get_string('results', 'quiz'));
}
if (has_capability('mod/quiz:preview', $context)) {
$row[] = new tabobject('preview', "$CFG->wwwroot/mod/quiz/startattempt.php?cmid=$cm->id&amp;sesskey=" . sesskey(), get_string('preview', 'quiz'));
$strpreview = get_string('preview', 'quiz');
$row[] = new tabobject('preview', "$CFG->wwwroot/mod/quiz/startattempt.php?cmid=$cm->id&amp;sesskey=" . sesskey(), "<img src=\"$CFG->pixpath/t/preview.gif\" class=\"iconsmall\" alt=\"$strpreview\" /> $strpreview", $strpreview);
}
if (has_capability('mod/quiz:manage', $context)) {
$row[] = new tabobject('edit', "$CFG->wwwroot/mod/quiz/edit.php?cmid=$cm->id", get_string('edit'));
$row[] = new tabobject('edit', "$CFG->wwwroot/mod/quiz/edit.php?cmid=$cm->id", "<img src=\"$CFG->pixpath/t/edit.gif\" class=\"iconsmall\" alt=\"$stredit\" /> $stredit",$stredit);
}
if ($currenttab == 'info' && count($row) == 1) {
@@ -101,9 +102,11 @@ if ($currenttab == 'edit' and isset($mode)) {
$streditingquiz = get_string("editinga", "moodle", $strquiz);
if (has_capability('mod/quiz:manage', $context) && $contexts->have_one_edit_tab_cap('editq')) {
$row[] = new tabobject('editq', "$CFG->wwwroot/mod/quiz/edit.php?".$thispageurl->get_query_string(), $strquiz, $streditingquiz);
//TODO: ensure that removing get_query_string here won't hurt
$row[] = new tabobject('editq', "$CFG->wwwroot/mod/quiz/edit.php?cmid=$cm->id", $stredit, $streditingquiz);
$row[] = new tabobject('reorder', "$CFG->wwwroot/mod/quiz/edit.php?reordertool=1&amp;cmid=$cm->id", get_string('orderandpaging','quiz'), $streditingquiz);
}
questionbank_navigation_tabs($row, $contexts, $thispageurl->get_query_string());
//questionbank_navigation_tabs($row, $contexts, $thispageurl->get_query_string());
$tabs[] = $row;
}
+33 -3
View File
@@ -12,6 +12,7 @@ define("QUESTION_PAGE_LENGTH", 25);
require_once("$CFG->libdir/listlib.php");
require_once("$CFG->dirroot/question/category_form.php");
require_once("$CFG->dirroot/question/category_form_randomquestion.php");
require_once('move_form.php');
class question_category_list extends moodle_list {
@@ -135,6 +136,10 @@ class question_category_object {
* @var question_category_edit_form Object representing form for adding / editing categories.
*/
var $catform;
/**
* @var question_category_edit_form_randomquestion Object representing simplified form for adding a category in order to add it into a quiz as a random question.
*/
var $catform_rand;
/**
* Constructor
@@ -197,8 +202,10 @@ class question_category_object {
list($paged, $count) = $this->editlists[$key]->list_from_records($paged, $count);
}
$this->catform = new question_category_edit_form($this->pageurl, compact('contexts', 'currentcat'));
$this->catform_rand = new question_category_edit_form_randomquestion($this->pageurl, compact('contexts', 'currentcat'));
if (!$currentcat){
$this->catform->set_data(array('parent'=>$defaultcategory));
$this->catform_rand->set_data(array('parent'=>$defaultcategory));
}
}
/**
@@ -216,6 +223,16 @@ class question_category_object {
$this->output_new_table();
echo '<br />';
}
/**
* Displays the user interface
*
*/
function display_randomquestion_user_interface() {
/// Interface for adding a new category:
$this->output_new_randomquestion_table();
}
/**
@@ -225,6 +242,13 @@ class question_category_object {
$this->catform->display();
}
/**
* Outputs a table to allow entry of a new category
*/
function output_new_randomquestion_table() {
$this->catform_rand->display();
}
/**
* Outputs a list to allow editing/rearranging of existing categories
@@ -278,6 +302,8 @@ class question_category_object {
$category->categoryheader = $this->str->edit;
$this->catform->set_data($category);
$this->catform->display();
$this->catform_rand->set_data($category);
$this->catform_rand->display();
} else {
print_error('invalidcategory', '', '', $categoryid);
}
@@ -369,7 +395,7 @@ class question_category_object {
/**
* Creates a new category with given params
*/
public function add_category($newparent, $newcategory, $newinfo) {
public function add_category($newparent, $newcategory, $newinfo, $return=false) {
global $DB;
if (empty($newcategory)) {
print_error('categorynamecantbeblank', 'quiz');
@@ -391,10 +417,14 @@ class question_category_object {
$cat->info = $newinfo;
$cat->sortorder = 999;
$cat->stamp = make_unique_id_code();
if (!$DB->insert_record("question_categories", $cat)) {
if (!$categoryid=$DB->insert_record("question_categories", $cat)) {
print_error('cannotinsertquestioncate', 'question', '', $newcategory);
} else {
redirect($this->pageurl->out());//always redirect after successful action
if($return){
return $categoryid;
}else{
redirect($this->pageurl->out());//always redirect after successful action
}
}
}
+49
View File
@@ -0,0 +1,49 @@
<?php //$Id$
require_once($CFG->libdir.'/formslib.php');
class question_category_edit_form_randomquestion extends moodleform {
function definition() {
global $CFG, $DB;
$mform =& $this->_form;
$contexts = $this->_customdata['contexts'];
$currentcat = $this->_customdata['currentcat'];
//--------------------------------------------------------------------------------
$mform->addElement('header', 'categoryheader', get_string('createcategoryfornewrandomquestion', 'quiz'));
$questioncategoryel = $mform->addElement('questioncategory', 'parent', get_string('parentcategory', 'quiz'),
array('contexts'=>$contexts, 'top'=>true, 'currentcat'=>$currentcat, 'nochildrenof'=>$currentcat));
$mform->setType('parent', PARAM_SEQUENCE);
if (1 == $DB->count_records_sql("SELECT count(*)
FROM {question_categories} c1,
{question_categories} c2
WHERE c2.id = ?
AND c1.contextid = c2.contextid", array($currentcat))){
//TODO: Tim? why does the above evaluate true, breaking the form?
// and more importantly, if this is a valid situation, how should we react,
// that is, what does this mean?
//$mform->hardFreeze('parent');
}
$mform->setHelpButton('parent', array('categoryparent', get_string('parent', 'quiz'), 'question'));
$mform->addElement('text','name', get_string('name'),'maxlength="254" size="50"');
$mform->setDefault('name', '');
$mform->addRule('name', get_string('categorynamecantbeblank', 'quiz'), 'required', null, 'client');
$mform->setType('name', PARAM_MULTILANG);
$mform->addElement('hidden', 'info', '');
$mform->setType('info', PARAM_MULTILANG);
//--------------------------------------------------------------------------------
$this->add_action_buttons(false, get_string('addrandomquestion', 'quiz'));
//--------------------------------------------------------------------------------
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
//TODO: Tim: is this questionable? to add a hidden field right from a get parameter?
$mform->addElement('hidden', 'addonpage', optional_param("addonpage_form", 0, PARAM_SEQUENCE), 'id="rform_qpage"');
$mform->setType('addonpage', PARAM_SEQUENCE);
}
}
?>
+15 -10
View File
@@ -158,7 +158,7 @@ function question_list($contexts, $pageurl, $categoryandcontext, $cm = null,
$straddquestions = get_string("addquestions", "quiz");
$strimportquestions = get_string("importquestions", "quiz");
$strexportquestions = get_string("exportquestions", "quiz");
$strnoquestions = get_string("noquestions", "quiz");
$strnoquestions = get_string("noquestionsincategory", "quiz");
$strselect = get_string("select", "quiz");
$strselectall = get_string("selectall", "quiz");
$strselectnone = get_string("selectnone", "quiz");
@@ -244,7 +244,7 @@ function question_list($contexts, $pageurl, $categoryandcontext, $cm = null,
list($usql, $params) = $DB->get_in_or_equal($categorylist_array);
if (!$totalnumber = $DB->count_records_select('question', "category $usql AND parent = '0' $showhidden", $params)) {
echo "<p style=\"text-align:center;\">";
print_string("noquestions", "quiz");
echo $strnoquestions;
echo "</p>";
return;
}
@@ -255,14 +255,13 @@ function question_list($contexts, $pageurl, $categoryandcontext, $cm = null,
if (!$questions = $DB->get_records_select('question', "category $usql AND parent = '0' $showhidden", $params, $sortorderdecoded, '*', 0, $perpage)) {
// There are no questions at all
echo "<p style=\"text-align:center;\">";
print_string("noquestions", "quiz");
echo $strnoquestions;
echo "</p>";
return;
}
}
print_paging_bar($totalnumber, $page, $perpage, $pageurl, 'qpage');
echo question_sort_options($pageurl, $sortorder);
@@ -397,15 +396,21 @@ function question_list($contexts, $pageurl, $categoryandcontext, $cm = null,
function question_sort_options($pageurl, $sortorder){
global $USER;
//sort options
$html = "<div class=\"mdl-align\">";
$html .= '<form method="post" action="edit.php">';
$html = "<div class=\"mdl-align questionsortoptions\">";
// POST method should only be used for parameters that change data
// or if POST method has to be used, the user must be redirected immediately to
// non-POSTed page to not break the back button
$html .= '<form method="get" action="edit.php">';
$html .= '<fieldset class="invisiblefieldset" style="display: block;">';
$html .= '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
$html .= $pageurl->hidden_params_out(array('qsortorder'));
$sortoptions = array('alpha' => get_string("sortalpha", "quiz"),
'typealpha' => get_string("sorttypealpha", "quiz"),
'age' => get_string("sortage", "quiz"));
$html .= choose_from_menu ($sortoptions, 'qsortorder', $sortorder, false, 'this.form.submit();', '0', true);
//choose_from_menu concatenates the form name with
//"menu" so the label is for menuqsortorder
$sortoptions = array('alpha' => get_string("qname", "quiz"),
'typealpha' => get_string("qtypename", "quiz"),
'age' => get_string("age", "quiz"));
$a = choose_from_menu ($sortoptions, 'qsortorder', $sortorder, false, 'this.form.submit();', '0', true);
$html .= '<label for="menuqsortorder">'.get_string('sortquestionsbyx', 'quiz', $a).'</label>';
$html .= '<noscript><div><input type="submit" value="'.get_string("sortsubmit", "quiz").'" /></div></noscript>';
$html .= '</fieldset>';
$html .= "</form>\n";
+8 -1
View File
@@ -24,6 +24,7 @@ $wizardnow = optional_param('wizardnow', '', PARAM_ALPHA);
$movecontext = optional_param('movecontext', 0, PARAM_BOOL);//switch to make question
//uneditable - form is displayed to edit category only
$returnurl = optional_param('returnurl', 0, PARAM_LOCALURL);
$appendqnumstring = optional_param('appendqnumstring', '', PARAM_ALPHA);
$inpopup = optional_param('inpopup', 0, PARAM_BOOL);
@@ -132,6 +133,8 @@ $toform->category = "$category->id,$category->contextid";
if ($formeditable && $id){
$toform->categorymoveto = $toform->category;
}
$toform->appendqnumstring = $appendqnumstring;
$toform->returnurl = $returnurl;
$toform->movecontext = $movecontext;
if ($cm !== null){
@@ -186,10 +189,14 @@ if ($mform->is_cancelled()){
notify(get_string('changessaved'), '');
close_window(3);
} else {
if($appendqnumstring){
$returnurl_object=new moodle_url($returnurl);
$returnurl=$returnurl_object->out(false,array($appendqnumstring=>($question->id), "sesskey"=>sesskey(), "cmid"=>$cmid));
}
redirect($returnurl);
}
} else {
$nexturlparams = array('returnurl'=>$returnurl);
$nexturlparams = array('returnurl'=>$returnurl, 'appendqnumstring'=>$appendqnumstring);
if (isset($fromform->nextpageparam) && is_array($fromform->nextpageparam)){
$nexturlparams += $fromform->nextpageparam;//useful for passing data to the next page which is not saved in the database
}
+7 -4
View File
@@ -193,6 +193,10 @@ class question_edit_form extends moodleform {
$mform->setType('returnurl', PARAM_LOCALURL);
$mform->setDefault('returnurl', 0);
$mform->addElement('hidden', 'appendqnumstring');
$mform->setType('appendqnumstring', PARAM_ALPHA);
$mform->setDefault('appendqnumstring', 0);
$buttonarray = array();
if (!empty($this->question->id)){
//editing / moving question
@@ -219,17 +223,16 @@ class question_edit_form extends moodleform {
$mform->hardFreezeAllVisibleExcept(array('categorymoveto', 'buttonar', 'currentgrp'));
}
}
function validation($fromform, $files) {
$errors= parent::validation($fromform, $files);
if (empty($fromform->makecopy) && isset($this->question->id)
&& ($this->question->formoptions->canedit || $this->question->formoptions->cansaveasnew)
if (empty($fromform->makecopy) && isset($this->question->id)
&& ($this->question->formoptions->canedit || $this->question->formoptions->cansaveasnew)
&& empty($fromform->usecurrentcat) && !$this->question->formoptions->canmove){
$errors['currentgrp'] = get_string('nopermissionmove', 'question');
}
return $errors;
}
/**
* Add any question-type specific form fields.
+68
View File
@@ -1091,6 +1091,73 @@ table.quizreviewsummary td.cell {
#mod-quiz-report .negcovar{
border :medium solid pink;
}
#mod-quiz-edit .questionbankwindow div.header{
/*this color might need to be theme-specific,
but in terms of usability, as testing showed,
//TODO: add url
it must be ensured that the question
bank window's title is prominent enough*/
background-color:#009;
color:#fff;
background-image:none;
}
#mod-quiz-edit div.question div.content div.points,
#mod-quiz-edit div.question div.content div.qorder{
background-color:#ddf;
}
#mod-quiz-edit div.quizpage .pagecontent .pagestatus{
background-color:#eee;
}
#mod-quiz-edit .quizpagedelete img{
background-color:#d6d6d6;
}
#mod-quiz-edit div.quizpage .pagecontent form#addquestion{
background-color:#fff;
}
#mod-quiz-edit .questioncontentcontainer div.randomquestionqlist{
background-color:#eee;
color:#777;
}
#mod-quiz-edit .questioncontentcontainer div.randomquestionqlist .totalquestionsinrandomqcategory{
color:#000;
}
/*TODO: below applies to also question bank, so when
question bank is adapted to the new UI, add the appropriate
css id's of question bank*/
#mod-quiz-edit .categoryinfo{
background-color:#eee;
border-bottom:1px solid #bbb;
}
#mod-quiz-edit .paging{
background-color:#ddd;
}
#mod-quiz-edit .questionsortoptions{
background-color:#ddd;
}
#mod-quiz-edit .paging a:hover{
background-color:#eef;
}
#mod-quiz-edit div.questionbank{
background-color:#e6e6ff;
}
#mod-quiz-edit .questionbank div.categoryquestionscontainer,.questionbank .categorysortopotionscontainer,.questionbank .categorypagingbarcontainer,.questionbank .categoryselectallcontainer{
background-color:#FFF;
}
#mod-quiz-edit div.question div.content div.questioncontrols{
background-color:#FFF;
}
#mod-quiz-edit div.editq div.question div.content{
background-color:#fff;
}
#mod-quiz-edit .questionbankwindow div.header a{
color:#FFF;
}
/***
*** Modules: Resource
***/
@@ -1212,3 +1279,4 @@ form.mform .required .fgroup span label {
color:#000;
}
+54 -1
View File
@@ -1006,7 +1006,60 @@ body#mod-forum-index .generalbox .cell {
text-decoration: underline;
}
/***
#mod-quiz-edit div.reorder .reordercontrols .moveselectedonpage{
text-align:right;
}
#mod-quiz-edit div.question div.qnum{
text-align:right;
}
#mod-quiz-edit div.reorder div.question div.qnum{
text-align:right;
font-size:1em;
}
#mod-quiz-edit div.editq div.question div.qnum{
font-size:1.5em;
}
#mod-quiz-edit .questionbankwindow div.header a{
text-decoration:underline;
}
#mod-quiz-edit div.questioncontentcontainer a{
text-decoration:underline;
}
#mod-quiz-edit div.questioncontentcontainer div.singlequestion a{
text-decoration:underline;
}
#mod-quiz-edit div.editq div.question div.content .singlequestion a .questionname,div.editq div.question div.content .singlequestion a .questiontext{
text-decoration:underline;
}
#mod-quiz-edit div.question div.content .questiontext,
#categoryquestions .questiontext{
font-weight:bold;
}
#mod-quiz-edit div.question div.content div.questioncontrols{
text-align:right;
}
#mod-quiz-edit div.quizpage .pagecontent .pagestatus{
font-weight:bold;
}
#mod-quiz-edit div.question div.content .questiontype{
font-style:italic;
}
#mod-quiz-edit .questioncontentcontainer .randomquestioncategory{
font-weight:bold;
}
#mod-quiz-edit .categoryinfofield{
font-style:italic;
}
#mod-quiz-edit .categorynamefield{
font-weight:bold;
}
#mod-quiz-edit .questionbankwindow div.header{
font-weight:bold;
}
/***
*** Modules: Resource
***/
+19
View File
@@ -69,3 +69,22 @@ form.mform textarea {
#mod-quiz-review #middle-column {
height: 1%;
}
#mod-quiz-edit div.question div.content .questionname,
#categoryquestions .questionname{
/*ie6 shows this as an arrow if this is not specified*/
cursor: pointer;
}
#mod-quiz-edit #categoryquestions .questiontext{
/*ie6 shows this as an arrow if this is not specified*/
cursor: pointer;
}
#mod-quiz-edit div.tabtree a span img.iconsmall{
display:none;
}
#mod-quiz-edit div.question div.content .questiontext,#categoryquestions .questiontext{
width:50%;
}
#mod-quiz-edit div.question div.content .questionname,#categoryquestions .questionname{
width:20%;
}
+539 -22
View File
@@ -90,14 +90,6 @@ h6.main {
text-align: center;
}
#redirect #message {
}
#redirect #continue {
}
/* .clearfix {display: inline-table;} */
/* Hides from IE-mac \*/
@@ -4245,20 +4237,6 @@ table.quizreviewsummary td.cell {
margin-bottom: 0.5em;
}
#mod-quiz-edit #page .controls,
#mod-quiz-edit #page .quizattemptcounts
{
text-align: center;
}
#mod-quiz-edit .quizquestions h2 {
margin-top: 0;
}
#mod-quiz-edit #showhidepagingcontrols {
margin-top: 0.7em;
}
#mod-quiz-edit #showhidepagingcontrols .singlebutton {
display: inline;
}
.quizquestionlistcontrols {
text-align: center;
}
@@ -4421,6 +4399,545 @@ table.quizreviewsummary td.cell {
display: block;
margin: 0.5em 0;
}
#mod-quiz-edit div.sideblock{
float:right;
width:30%;
right:0.3em;
padding-bottom:0.5em;
display:block;
}
#mod-quiz-edit div.quizcontents{
float:left;
width:70%;
display:block;
}
#mod-quiz-edit div.quizcontents,h2.main{
clear:left;
}
#mod-quiz-edit .addpage{
clear:both;
padding-top:0.3em;
float:right;
margin-right:2em;
}
#mod-quiz-edit h2.main{
display:inline;
padding-right:1em;
}
#mod-quiz-edit .statusdisplay{
clear:both;
display:block;
border:0.2em #FFF solid;
margin-bottom:0.3em;
margin-right:1em;
margin-top:0.3em;
padding:0.1em;
}
#mod-quiz-edit div.quizpage{
display:block;
clear:both;
width:100%;
}
#mod-quiz-edit div.quizpage span.pagetitle{
margin-top:0.3em;
float:left;
display:block;
}
#mod-quiz-edit div.reorder .reordercontrols .moveselectedonpage{
clear:right;
float:right;
padding:0.5em 0.3em;
}
#mod-quiz-edit div.reorder .reordercontrols .addnewpagesafterselected,#mod-quiz-edit .repaginatecommand{
float:right;
clear:right;
padding-right:1em;
}
#mod-quiz-edit div.reorder .reordercontrols .deleteselected{
float:right;
margin-right:1em;
}
#mod-quiz-edit div.reorder .reordercontrols{
clear:both;
padding-right:1em;
margin-top:0.5em;
padding-top:0.5em;
padding-bottom:0.5em;
}
#mod-quiz-edit div.quizpage .pagecontent{
margin-top:0.3em;
display:block;
float:left;
position:relative;
margin-left:0.3em;
border-left:solid #777 thin;
line-height:1.3em;
-webkit-border-radius:0.6em;
-webkit-border-radius-bottomleft:0;
-webkit-border-radius-topleft:0;
border-radius:0.6em;
border-radius-bottomleft:0;
border-radius-topleft:0;
width:88%;
padding:0 0 0.5em;
}
#mod-quiz-edit div.question{
clear:left;
width:100%;
}
#mod-quiz-edit div.question div.qnum{
display:block;
float:left;
width:1.4em;
padding-right:0.3em;
padding-left:0;
z-index:99;
}
#mod-quiz-edit div.reorder div.question div.qnum{
width:2.9em;
padding-top:0.1em;
}
/*edit tab*/
#mod-quiz-edit div.editq div.question div.qnum{
padding-top:0.2em;
}
#mod-quiz-edit div.editq div.question{
padding-top:0.3em;
}
#mod-quiz-edit div.reorder div.question{
padding-top:0.2em;
}
#mod-quiz-edit div.question div.questioncontainer{
background-color:#ffc;
}
#mod-quiz-edit div.editq div.question div.content{
width:87%;
float:left;
position:relative;
-webkit-border-radius:0.6em;
-webkit-border-radius-bottomleft:0;
-webkit-border-radius-topleft:0;
border-radius:0.6em;
border-radius-bottomleft:0;
border-radius-topleft:0;
line-height:1.4em;
padding:0.5em;
}
#mod-quiz-edit .reorder div.question div.content{
width:87%;
float:left;
background-color:#fff;
position:relative;
-webkit-border-radius:0.3em;
-webkit-border-radius-bottomleft:0;
-webkit-border-radius-topleft:0;
border-radius:0.3em;
border-radius-bottomleft:0;
border-radius-topleft:0;
line-height:1.2em;
padding:0.1em;
}
#mod-quiz-edit div.question div.content div.points{
top:0.5em;
border-left:#FFF solid 0.4em;
width:7.5em;
padding:0.2em;
}
#mod-quiz-edit .questionbankwindow select#catmenu_jump{
/* In Opera9, IE6 the width of the
select obeys the width of its content
by default. This prevents that. */
width:100%;
}
#mod-quiz-edit .questionbankwindow div.header{
padding-top:0.2em;
}
#randomquestiondialog_c select{
width:100%;
}
#mod-quiz-edit div.question div.content div.points,
#mod-quiz-edit div.question div.content div.qorder{
line-height:1em;
float:right;
max-width:30%;
position:absolute;
right:50px;
-webkit-border-radius:0.2em;
-webkit-border-radius-bottomleft:0;
-webkit-border-radius-topleft:0;
border-radius:0.2em;
border-radius-bottomleft:0;
border-radius-topleft:0;
z-index:999;
display:block;
margin:0;
}
#mod-quiz-edit div.question div.content .editicon{
width:15px;
}
#mod-quiz-edit .editq div.questioncontentcontainer div.singlequestion img{
float:left;
padding-top:0.3em;
padding-right:0.3em;
}
#mod-quiz-edit div.question div.content .questionname,
#categoryquestions .questionname{
white-space:nowrap;
text-overflow:ellipsis;
overflow:hidden;
zoom:1;
position:relative;
max-width:20%;
/*ie-only:*/
text-overflow:ellipsis;
/*opera-only*/
-o-text-overflow:ellipsis;
}
#mod-quiz-edit div.question div.content .singlequestion .questionname,
#mod-quiz-edit div.question div.content .singlequestion .questiontext{
display:inline-block;
}
#mod-quiz-edit div.editq div.question div.content .singlequestion a .questionname,
#mod-quiz-edit div.editq div.question div.content .singlequestion a .questiontext{
float:left;
}
#mod-quiz-edit .quizquestionlistcontrols{
display:inline;
}
#mod-quiz-edit div.question div.content .questiontext,
#categoryquestions .questiontext{
-o-text-overflow:ellipsis;
text-overflow:ellipsis;
position:relative;
zoom:1;
padding-left:0.3em;
max-width:50%;
overflow:hidden;
white-space:nowrap;
text-overflow:ellipsis;
}
#mod-quiz-edit div.quizpage .pagecontent .pagestatus{
-webkit-border-radius-bottomright:0.3em;
-webkit-border-radius-topright:0.3em;
border-radius-bottomright:0.3em;
border-radius-topright:0.3em;
margin:0.3em;
padding:0.1em 0.1em 0.1em 0.3em;
}
#mod-quiz-edit div.question div.content .questiontype{
display:block;
clear:left;
float:left;
}
#mod-quiz-edit div.question div.content .questionpreview{
display:block;
float:left;
margin-left:0.3em;
padding-left:0.2em;
padding-right:0.2em;
background-color:#eee;
}
#mod-quiz-edit div.question div.content div.quiz_randomquestion .questionpreview{
display:inline;
float:none;
}
#mod-quiz-edit div.question div.content div.questioncontrols{
float:right;
width:45px;
position:absolute;
right:0.3em;
top:0;
z-index:999;
display:block;
padding:0.2em;
}
#mod-quiz-edit div.question div.content div.questioncontrols img.upwithoutdown{
padding-right:12px;
display:inline;
}
#mod-quiz-edit .quizpagedelete{
position:absolute;
top:0.2em;
right:0.2em;
display:inline;
z-index:999;
}
#mod-quiz-edit .quizpagedelete img{
background-color:#d6d6d6;
padding:0.5em;
}
#mod-quiz-edit .pagecontrols{
clear:both;
margin-left:0.5em;
padding-top:0.5em;
}
#mod-quiz-edit .pagecontrols .singlebutton{
float:left;
}
#mod-quiz-edit div.quizpage .pagecontent form#addquestion{
margin-right:1em;
-webkit-border-radius:0.2em;
border-radius:0.2em;
padding:0.3em;
}
#mod-quiz-edit div.quizpage .pagecontent form.randomquestionform{
padding-left:1em;
}
#mod-quiz-edit div.quizpage .pagecontent form.randomquestionform div{
/* it is a mystery why this has to be inline-table but
otherwise the layout gets screwed, even if
it is "inline" */
display:inline-table;
}
#mod-quiz-edit div.quizpage .pagecontent form.randomquestionform div input{
display:inline;
}
#mod-quiz-edit div.quizpage .pagecontent .adddescription{
clear:left;
margin-top:0.3em;
}
#mod-quiz-edit div.quizpage .pagecontent .addrandomquestion{
margin-top:0.3em;
}
/* a CSS class YUI container creates on the fly: */
#mod-quiz-edit div#randomquestiondialog_c{
width:90%;
}
#mod-quiz-edit #repaginatedialog .hd{
display:none;
}
#mod-quiz-edit div#randomquestiondialog{
display:none;
}
#mod-quiz-edit div#randomquestiondialog_c .mform,
#mod-quiz-edit div#repaginatedialog .mform{
margin-left:auto;
margin-right:auto;
}
#mod-quiz-edit div.container div.generalbox{
position:relative;
display:block;
border:0 none;
margin:0;
padding:0;
}
#mod-quiz-edit .questioncontentcontainer div.randomquestionqlist{
padding-left:0.2em;
padding-right:0.2em;
clear:both;
margin:0.5em;
}
#mod-quiz-edit .questioncontentcontainer div.randomquestionqlist ul{
list-style-type:none;
margin:0;
padding:0;
}
#mod-quiz-edit .reorder .questioncontentcontainer .randomquestioncategory,
#mod-quiz-edit .reorder .questioncontentcontainer .randomquestionfromcategory,
#mod-quiz-edit .reorder div.question div.content .questionpreview{
display:inline;
float:none;
}
#mod-quiz-edit .reorder .questioncontentcontainer{
position:relative;
overflow:hidden;
white-space:nowrap;
}
#mod-quiz-edit .reorder .questioncontentcontainer .randomquestioncategory{
overflow:hidden;
white-space:nowrap;
}
#mod-quiz-edit .reorder fieldset{
display:inline;
}
#mod-quiz-edit .questioncontentcontainer div.randomquestionqlist ul li{
clear:left;
width:100%;
overflow:hidden;
white-space:nowrap;
}
#mod-quiz-edit .questioncontentcontainer div.randomquestionqlist ul li span{
display:inline;
}
/*start question bank*/
/*TODO: below applies to also question bank, so when
question bank is adapted to the new UI, add the appropriate
css id's of question bank*/
#mod-quiz-edit .questionbankwindow .createnewquestion select,
#mod-quiz-edit .questionbankwindow #catmenu select{
width:80%;
}
#mod-quiz-edit table#categoryquestions{
width:100%;
overflow:hidden;
table-layout:fixed;
}
#mod-quiz-edit table#categoryquestions td,#mod-quiz-edit table#categoryquestions th{
overflow:hidden;
white-space:nowrap;
}
#mod-quiz-edit table#categoryquestions col#qaction{
width:20%;
}
#mod-quiz-edit table#categoryquestions col#qextraactions{
width:40px;
}
#mod-quiz-edit table#categoryquestions .iconsmall{
padding-left:5px;
}
#mod-quiz-edit .categoryinfo{
padding:0.3em;
}
#mod-quiz-edit .paging{
margin-top:0;
margin-bottom:0;
display:block;
}
#mod-quiz-edit .questionsortoptions{
margin-top:0.3em;
}
#mod-quiz-edit .pagingbottom{
padding-bottom:0.3em;
}
#mod-quiz-edit div.questionbank form .invisiblefieldset{
clear:both;
}
#mod-quiz-edit div.createnewquestion{
padding-top:0.3em;
clear:left;
}
#mod-quiz-edit .sideblock .content{
padding:0;
}
#mod-quiz-edit .questionbank .categorysortopotionscontainer{
padding-top:0.5em;
margin-top:0.3em;
}
#mod-quiz-edit .questionbank .categoryselectallcontainer{
padding-bottom:0.5em;
}
#mod-quiz-edit .questionbank div.categoryquestionscontainer,
#mod-quiz-edit .questionbank .categorysortopotionscontainer,
#mod-quiz-edit .questionbank .categorypagingbarcontainer,
#mod-quiz-edit .questionbank .categoryselectallcontainer{
padding-left:0.3em;
padding-right:0.3em;
}
#mod-quiz-edit .noquestionsincategory{
clear:both;
padding-top:1em;
padding-bottom:1em;
}
#mod-quiz-edit .modulespecificbuttonscontainer{
padding-left:0.3em;
padding-right:0.3em;
}
#mod-quiz-edit div#footer{
clear:both;
padding-top:1em;
}
#mod-quiz-edit #repaginatecommand{
display:none;
}
/*.usejs class is added via javascript so these will toggle if js is enabled*/
#mod-quiz-edit .usejs #repaginatedialog{
display:none;
}
#mod-quiz-edit .usejs #repaginatedialog .hd{
display:block;
}
#mod-quiz-edit .usejs #repaginatedialog .bd{
padding:1em;
}
#mod-quiz-edit .usejs .repaginatecommand #repaginatecommand{
display:block;
}
/***
*** Modules: Resource
+31 -2
View File
@@ -1,6 +1,6 @@
/*******************************************************************
styles_moz.css
This CSS file uses the non-standard Mozilla CSS extensions
to add round corners to the current theme.
@@ -80,7 +80,7 @@
-moz-border-radius:3px;
}
.categorybox, .categoryboxcontent,
.categorybox, .categoryboxcontent,
.coursebox {
-moz-border-radius:10px;
}
@@ -347,3 +347,32 @@ body#course-user .section {
#quiznavigation .qnbutton {
-moz-box-sizing: content-box;
}
#mod-quiz-edit div.quizpage .pagecontent{
-moz-border-radius:0.6em;
-moz-border-radius-bottomleft:0;
-moz-border-radius-topleft:0;
}
#mod-quiz-edit .reorder div.question div.content{
-moz-border-radius:0.3em;
-moz-border-radius-bottomleft:0;
-moz-border-radius-topleft:0;
}
#mod-quiz-edit div.editq div.question div.content{
-moz-border-radius:0.6em;
-moz-border-radius-bottomleft:0;
-moz-border-radius-topleft:0;
}
#mod-quiz-edit div.question div.content div.points,
#mod-quiz-edit div.question div.content div.qorder{
-moz-border-radius:0.2em;
-moz-border-radius-bottomleft:0;
-moz-border-radius-topleft:0;
}
#mod-quiz-edit div.quizpage .pagecontent .pagestatus{
-moz-border-radius-bottomright:0.3em;
-moz-border-radius-topright:0.3em;
}
#mod-quiz-edit div.quizpage .pagecontent form#addquestion{
-moz-border-radius:0.2em;
}