Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

MDL-32932: Add quickgrading support to mod_assign

  • Loading branch information...
commit bf78ebd650779231fc16bb0c50c9e2d80fd47bc9 1 parent a769a00
Damyon Wiese authored
2  mod/assign/gradingbatchoperationsform.php
@@ -53,7 +53,7 @@ function definition() {
53 53 if ($instance['submissiondrafts']) {
54 54 $options['reverttodraft'] = get_string('reverttodraft', 'assign');
55 55 }
56   - $mform->addElement('select', 'operation', get_string('batchoperationsdescription', 'assign'), $options, array('class'=>'operation'));
  56 + $mform->addElement('select', 'operation', get_string('batchoperationsdescription', 'assign'), $options, array('class'=>'operation ignoredirty'));
57 57 $mform->addHelpButton('operation', 'batchoperationsdescription', 'assign');
58 58 $mform->addElement('hidden', 'action', 'batchgradingoperation');
59 59 $mform->addElement('hidden', 'id', $instance['cm']);
12 mod/assign/gradingoptionsform.php
@@ -48,10 +48,16 @@ function definition() {
48 48 $mform->addElement('header', 'general', get_string('gradingoptions', 'assign'));
49 49 // visible elements
50 50 $options = array(-1=>'All',10=>'10', 20=>'20', 50=>'50', 100=>'100');
51   - $autosubmit = array('onchange'=>'form.submit();');
52   - $mform->addElement('select', 'perpage', get_string('assignmentsperpage', 'assign'), $options, $autosubmit);
  51 + $mform->addElement('select', 'perpage', get_string('assignmentsperpage', 'assign'), $options, array('class'=>'ignoredirty'));
53 52 $options = array(''=>get_string('filternone', 'assign'), ASSIGN_FILTER_SUBMITTED=>get_string('filtersubmitted', 'assign'), ASSIGN_FILTER_REQUIRE_GRADING=>get_string('filterrequiregrading', 'assign'));
54   - $mform->addElement('select', 'filter', get_string('filter', 'assign'), $options, $autosubmit);
  53 + $mform->addElement('select', 'filter', get_string('filter', 'assign'), $options, array('class'=>'ignoredirty'));
  54 +
  55 + // quickgrading
  56 + if ($instance['showquickgrading']) {
  57 + $mform->addElement('checkbox', 'quickgrading', get_string('quickgrading', 'assign'), '', array('class'=>'ignoredirty'));
  58 + $mform->addHelpButton('quickgrading', 'quickgrading', 'assign');
  59 + $mform->setDefault('quickgrading', $instance['quickgrading']);
  60 + }
55 61
56 62 // hidden params
57 63 $mform->addElement('hidden', 'contextid', $instance['contextid']);
39 mod/assign/gradingtable.php
@@ -48,6 +48,8 @@ class assign_grading_table extends table_sql implements renderable {
48 48 private $gradinginfo = null;
49 49 /** @var int $tablemaxrows */
50 50 private $tablemaxrows = 10000;
  51 + /** @var boolean $quickgrading */
  52 + private $quickgrading = false;
51 53
52 54 /**
53 55 * overridden constructor keeps a reference to the assignment class that is displaying this table
@@ -56,12 +58,14 @@ class assign_grading_table extends table_sql implements renderable {
56 58 * @param int $perpage how many per page
57 59 * @param string $filter The current filter
58 60 * @param int $rowoffset For showing a subsequent page of results
  61 + * @param bool $quickgrading Is this table wrapped in a quickgrading form?
59 62 */
60   - function __construct(assign $assignment, $perpage, $filter, $rowoffset=0) {
  63 + function __construct(assign $assignment, $perpage, $filter, $rowoffset, $quickgrading) {
61 64 global $CFG, $PAGE, $DB;
62 65 parent::__construct('mod_assign_grading');
63 66 $this->assignment = $assignment;
64 67 $this->perpage = $perpage;
  68 + $this->quickgrading = $quickgrading;
65 69 $this->output = $PAGE->get_renderer('mod_assign');
66 70
67 71 $this->define_baseurl(new moodle_url($CFG->wwwroot . '/mod/assign/view.php', array('action'=>'grading', 'id'=>$assignment->get_course_module()->id)));
@@ -115,7 +119,7 @@ function __construct(assign $assignment, $perpage, $filter, $rowoffset=0) {
115 119
116 120 // Select
117 121 $columns[] = 'select';
118   - $headers[] = get_string('select') . '<div class="selectall"><input type="checkbox" name="selectall" title="' . get_string('selectall') . '"/></div>';
  122 + $headers[] = get_string('select') . '<div class="selectall"><input type="checkbox" class="ignoredirty" name="selectall" title="' . get_string('selectall') . '"/></div>';
119 123
120 124 // Edit links
121 125 if (!$this->is_downloading()) {
@@ -224,13 +228,14 @@ function get_rows_per_page() {
224 228 * Display a grade with scales etc.
225 229 *
226 230 * @param string $grade
  231 + * @param boolean $editable
227 232 * @return string The formatted grade
228 233 */
229   - function display_grade($grade) {
  234 + function display_grade($grade, $editable, $userid, $modified) {
230 235 if ($this->is_downloading()) {
231 236 return $grade;
232 237 }
233   - $o = $this->assignment->display_grade($grade);
  238 + $o = $this->assignment->display_grade($grade, $editable, $userid, $modified);
234 239
235 240 return $o;
236 241 }
@@ -247,7 +252,20 @@ function col_outcomes(stdClass $row) {
247 252 $options = make_grades_menu(-$outcome->scaleid);
248 253
249 254 $options[0] = get_string('nooutcome', 'grades');
250   - $outcomes .= $this->output->container($outcome->name . ': ' . $options[$outcome->grades[$row->userid]->grade], 'outcome');
  255 + if ($this->quickgrading&& !($outcome->grades[$row->userid]->locked)) {
  256 + $select = '<select name="outcome_' . $index . '_' . $row->userid . '" class="quickgrade">';
  257 + foreach ($options as $optionindex => $optionvalue) {
  258 + $selected = '';
  259 + if ($outcome->grades[$row->userid]->grade == $optionindex) {
  260 + $selected = 'selected="selected"';
  261 + }
  262 + $select .= '<option value="' . $optionindex . '"' . $selected . '>' . $optionvalue . '</option>';
  263 + }
  264 + $select .= '</select>';
  265 + $outcomes .= $this->output->container($outcome->name . ': ' . $select, 'outcome');
  266 + } else {
  267 + $outcomes .= $this->output->container($outcome->name . ': ' . $options[$outcome->grades[$row->userid]->grade], 'outcome');
  268 + }
251 269 }
252 270
253 271 return $outcomes;
@@ -284,7 +302,7 @@ function col_fullname($row) {
284 302 * @return string
285 303 */
286 304 function col_select(stdClass $row) {
287   - return '<input type="checkbox" name="selectedusers" value="' . $row->userid . '"/>';
  305 + return '<input type="checkbox" name="selectedusers" value="' . $row->userid . '" class="ignoredirty"/>';
288 306 }
289 307
290 308 /**
@@ -322,12 +340,7 @@ function col_grade(stdClass $row) {
322 340 $separator = $this->output->spacer(array(), true);
323 341 }
324 342
325   -
326   - if ($row->grade) {
327   - $grade = $this->display_grade($row->grade);
328   - } else {
329   - $grade = '-';
330   - }
  343 + $grade = $this->display_grade($row->grade, $this->quickgrading, $row->userid, $row->timemarked);
331 344
332 345
333 346 //return $grade . $separator . $link;
@@ -345,7 +358,7 @@ function col_finalgrade(stdClass $row) {
345 358
346 359 $grade = $this->get_gradebook_data_for_user($row->userid);
347 360 if ($grade) {
348   - $o = $this->display_grade($grade->grade);
  361 + $o = $this->display_grade($grade->grade, false, $row->userid, $row->timemarked);
349 362 }
350 363
351 364 return $o;
7 mod/assign/lang/en/assign.php
@@ -101,6 +101,8 @@
101 101 It is <a href="{$a->url}">available on the web site</a>.';
102 102 $string['enabled'] = 'Enabled';
103 103 $string['errornosubmissions'] = 'There are no submissions to download';
  104 +$string['errorquickgradingnotcompatiblewithadvancedgrading'] = 'The grades were not saved because this assignment is currently using advanced grading';
  105 +$string['errorrecordmodified'] = 'The grades were not saved because someone has modified one or more records more recently than when you loaded the page.';
104 106 $string['feedbackcomments'] = 'Feedback comments';
105 107 $string['feedback'] = 'Feedback';
106 108 $string['feedbackplugins'] = 'Feedback plugins';
@@ -168,11 +170,16 @@
168 170 $string['preventsubmissions'] = 'Prevent the user from making any more submissions to this assignment.';
169 171 $string['preventsubmissionsshort'] = 'Prevent submission changes';
170 172 $string['previous'] = 'Previous';
  173 +$string['quickgrading'] = 'Quick grading';
  174 +$string['quickgradingresult'] = 'Quick grading';
  175 +$string['quickgradingchangessaved'] = 'The grade changes were saved';
  176 +$string['quickgrading_help'] = 'Quick grading allows you to assign grades (and outcomes) directly in the submissions table. Quick grading is not compatible with advanced grading and is not recommended when there are multiple markers.';
171 177 $string['reverttodraftforstudent'] = 'Revert submission to draft for student: (id={$a->id}, fullname={$a->fullname}).';
172 178 $string['reverttodraft'] = 'Revert the submission to draft status.';
173 179 $string['reverttodraftshort'] = 'Revert the submission to draft';
174 180 $string['reviewed'] = 'Reviewed';
175 181 $string['savechanges'] = 'Save changes';
  182 +$string['saveallchanges'] = 'Save all changes';
176 183 $string['savenext'] = 'Save and show next';
177 184 $string['sendnotifications'] = 'Send notifications to graders';
178 185 $string['sendnotifications_help'] = 'If enabled, graders (usually teachers) receive a message whenever a student submits an assignment, early, on time and late. Message methods are configurable.';
214 mod/assign/locallib.php
@@ -348,6 +348,9 @@ public function view($action='') {
348 348 //cancel button
349 349 $action = 'grading';
350 350 }
  351 + }else if ($action == 'quickgrade') {
  352 + $message = $this->process_save_quick_grades();
  353 + $action = 'quickgradingresult';
351 354 }else if ($action == 'saveoptions') {
352 355 $this->process_save_grading_options();
353 356 $action = 'grading';
@@ -360,6 +363,9 @@ public function view($action='') {
360 363 if ($action == 'previousgrade') {
361 364 $mform = null;
362 365 $o .= $this->view_single_grade_page($mform, -1);
  366 + } else if ($action == 'quickgradingresult') {
  367 + $mform = null;
  368 + $o .= $this->view_quickgrading_result($message);
363 369 } else if ($action == 'nextgrade') {
364 370 $mform = null;
365 371 $o .= $this->view_single_grade_page($mform, 1);
@@ -882,17 +888,20 @@ public function get_course() {
882 888 * Return a grade in user-friendly form, whether it's a scale or not
883 889 *
884 890 * @param mixed $grade int|null
  891 + * @param boolean $editing Are we allowing changes to this grade?
885 892 * @return string User-friendly representation of grade
886 893 */
887   - public function display_grade($grade) {
  894 + public function display_grade($grade, $editing, $userid=0, $modified=0) {
888 895 global $DB;
889 896
890 897 static $scalegrades = array();
891 898
892   -
893   -
894 899 if ($this->get_instance()->grade >= 0) { // Normal number
895   - if ($grade == -1 || $grade === null) {
  900 + if ($editing) {
  901 + $o = '<input type="text" name="quickgrade_' . $userid . '" value="' . $grade . '" size="6" maxlength="10" class="quickgrade"/>';
  902 + $o .= '&nbsp;/&nbsp;' . format_float($this->get_instance()->grade,2);
  903 + return $o;
  904 + } else if ($grade == -1 || $grade === null) {
896 905 return '-';
897 906 } else {
898 907 return format_float(($grade),2) .'&nbsp;/&nbsp;'. format_float($this->get_instance()->grade,2);
@@ -906,11 +915,26 @@ public function display_grade($grade) {
906 915 return '-';
907 916 }
908 917 }
909   - $scaleid = (int)$grade;
910   - if (isset($this->cache['scale'][$scaleid])) {
911   - return $this->cache['scale'][$scaleid];
  918 + if ($editing) {
  919 + $o = '<select name="quickgrade_' . $userid . '" class="quickgrade">';
  920 + $o .= '<option value="-1">' . get_string('nograde') . '</option>';
  921 + foreach ($this->cache['scale'] as $optionid => $option) {
  922 + $selected = '';
  923 + if ($grade == $optionid) {
  924 + $selected = 'selected="selected"';
  925 + }
  926 + $o .= '<option value="' . $optionid . '" ' . $selected . '>' . $option . '</option>';
  927 + }
  928 + $o .= '</select>';
  929 + $o .= '<input type="hidden" name="grademodified_' . $userid . '" value="' . $modified . '"/>';
  930 + return $o;
  931 + } else {
  932 + $scaleid = (int)$grade;
  933 + if (isset($this->cache['scale'][$scaleid])) {
  934 + return $this->cache['scale'][$scaleid];
  935 + }
  936 + return '-';
912 937 }
913   - return '-';
914 938 }
915 939 }
916 940
@@ -961,7 +985,7 @@ public function count_submissions_with_status($status) {
961 985 */
962 986 private function get_grading_userid_list(){
963 987 $filter = get_user_preferences('assign_filter', '');
964   - $table = new assign_grading_table($this, 0, $filter);
  988 + $table = new assign_grading_table($this, 0, $filter, 0, false);
965 989
966 990 $useridlist = $table->get_column_data('userid');
967 991
@@ -987,7 +1011,7 @@ private function get_userid_for_row($num, $last){
987 1011 }
988 1012
989 1013 $filter = get_user_preferences('assign_filter', '');
990   - $table = new assign_grading_table($this, 0, $filter);
  1014 + $table = new assign_grading_table($this, 0, $filter, 0, false);
991 1015
992 1016 $userid = $table->get_cell_data($num, 'userid', $last);
993 1017
@@ -1203,11 +1227,28 @@ public function render_editor_content($filearea, $submissionid, $plugintype, $ed
1203 1227 return $result;
1204 1228 }
1205 1229
  1230 + /**
  1231 + * Display a grading error
  1232 + *
  1233 + * @param string $message - The description of the result
  1234 + * @return string
  1235 + */
  1236 + private function view_quickgrading_result($message) {
  1237 + $o = '';
  1238 + $o .= $this->output->render(new assign_header($this->get_instance(),
  1239 + $this->get_context(),
  1240 + $this->show_intro(),
  1241 + $this->get_course_module()->id,
  1242 + get_string('quickgradingresult', 'assign')));
  1243 + $o .= $this->output->render(new assign_quickgrading_result($message, $this->get_course_module()->id));
  1244 + $o .= $this->view_footer();
  1245 + return $o;
  1246 + }
1206 1247
1207 1248 /**
1208 1249 * Display the page footer
1209 1250 *
1210   - * @return None
  1251 + * @return string
1211 1252 */
1212 1253 private function view_footer() {
1213 1254 return $this->output->render_footer();
@@ -1523,6 +1564,7 @@ private function view_grading_table() {
1523 1564 // Include grading options form
1524 1565 require_once($CFG->dirroot . '/mod/assign/gradingoptionsform.php');
1525 1566 require_once($CFG->dirroot . '/mod/assign/gradingactionsform.php');
  1567 + require_once($CFG->dirroot . '/mod/assign/quickgradingform.php');
1526 1568 require_once($CFG->dirroot . '/mod/assign/gradingbatchoperationsform.php');
1527 1569 $o = '';
1528 1570
@@ -1548,13 +1590,25 @@ private function view_grading_table() {
1548 1590 'post', '',
1549 1591 array('class'=>'gradingactionsform'));
1550 1592
  1593 + $gradingmanager = get_grading_manager($this->get_context(), 'mod_assign', 'submissions');
  1594 +
1551 1595 $perpage = get_user_preferences('assign_perpage', 10);
1552 1596 $filter = get_user_preferences('assign_filter', '');
  1597 + $controller = $gradingmanager->get_active_controller();
  1598 + $showquickgrading = empty($controller);
  1599 + if (optional_param('action', '', PARAM_ALPHA) == 'saveoptions') {
  1600 + $quickgrading = optional_param('quickgrading', false, PARAM_BOOL);
  1601 + set_user_preference('assign_quickgrading', $quickgrading);
  1602 + }
  1603 + $quickgrading = get_user_preferences('assign_quickgrading', false);
  1604 +
1553 1605 // print options for changing the filter and changing the number of results per page
1554 1606 $gradingoptionsform = new mod_assign_grading_options_form(null,
1555 1607 array('cm'=>$this->get_course_module()->id,
1556 1608 'contextid'=>$this->context->id,
1557   - 'userid'=>$USER->id),
  1609 + 'userid'=>$USER->id,
  1610 + 'showquickgrading'=>$showquickgrading,
  1611 + 'quickgrading'=>$quickgrading),
1558 1612 'post', '',
1559 1613 array('class'=>'gradingoptionsform'));
1560 1614
@@ -1577,10 +1631,18 @@ private function view_grading_table() {
1577 1631 }
1578 1632
1579 1633 $o .= $this->output->render(new assign_form('gradingactionsform', $gradingactionsform));
1580   - $o .= $this->output->render(new assign_form('gradingoptionsform', $gradingoptionsform));
  1634 + $o .= $this->output->render(new assign_form('gradingoptionsform', $gradingoptionsform, 'M.mod_assign.init_grading_options'));
1581 1635
1582 1636 // load and print the table of submissions
1583   - $o .= $this->output->render(new assign_grading_table($this, $perpage, $filter));
  1637 + if ($showquickgrading && $quickgrading) {
  1638 + $table = $this->output->render(new assign_grading_table($this, $perpage, $filter, 0, true));
  1639 + $quickgradingform = new mod_assign_quick_grading_form(null,
  1640 + array('cm'=>$this->get_course_module()->id,
  1641 + 'gradingtable'=>$table));
  1642 + $o .= $this->output->render(new assign_form('quickgradingform', $quickgradingform));
  1643 + } else {
  1644 + $o .= $this->output->render(new assign_grading_table($this, $perpage, $filter, 0, false));
  1645 + }
1584 1646
1585 1647 $currentgroup = groups_get_activity_group($this->get_course_module(), true);
1586 1648 $users = array_keys($this->list_participants($currentgroup, true));
@@ -1658,7 +1720,7 @@ private function view_student_error_message() {
1658 1720 $this->get_course_module()->id,
1659 1721 get_string('editsubmission', 'assign')));
1660 1722
1661   - $o .= $this->output->notification('This assignment is no longer accepting submissions');
  1723 + $o .= $this->output->notification(get_string('submissionsclosed', 'assign'));
1662 1724
1663 1725 $o .= $this->view_footer();
1664 1726
@@ -1682,9 +1744,7 @@ private function view_edit_submission_page($mform) {
1682 1744 require_capability('mod/assign:submit', $this->context);
1683 1745
1684 1746 if (!$this->submissions_open()) {
1685   - $subclosed = '';
1686   - $subclosed .= $this->view_student_error_message();
1687   - return $subclosed;
  1747 + return $this->view_student_error_message();
1688 1748 }
1689 1749 $o .= $this->output->render(new assign_header($this->get_instance(),
1690 1750 $this->get_context(),
@@ -1875,7 +1935,7 @@ public function view_student_summary($user, $showlinks) {
1875 1935 $gradebookgrade->str_long_grade,
1876 1936 has_capability('mod/assign:grade', $this->get_context()));
1877 1937 } else {
1878   - $gradefordisplay = $this->display_grade($gradebookgrade->grade);
  1938 + $gradefordisplay = $this->display_grade($gradebookgrade->grade, false);
1879 1939 }
1880 1940
1881 1941 $gradeddate = $gradebookgrade->dategraded;
@@ -2257,6 +2317,118 @@ private function process_submit_for_grading() {
2257 2317 }
2258 2318
2259 2319 /**
  2320 + * save quick grades
  2321 + *
  2322 + * @return string - The result of the save operation
  2323 + */
  2324 + private function process_save_quick_grades() {
  2325 + global $USER, $DB, $CFG;
  2326 +
  2327 + // Need grade permission
  2328 + require_capability('mod/assign:grade', $this->context);
  2329 +
  2330 + // make sure advanced grading is disabled
  2331 + $gradingmanager = get_grading_manager($this->get_context(), 'mod_assign', 'submissions');
  2332 + $controller = $gradingmanager->get_active_controller();
  2333 + if (!empty($controller)) {
  2334 + return get_string('errorquickgradingnotcompatiblewithadvancedgrading', 'assign');
  2335 + }
  2336 +
  2337 + $users = array();
  2338 + // first check all the last modified values
  2339 + $len = strlen('grademodified_');
  2340 + foreach ($_POST as $key => $value) {
  2341 + if (substr($key, 0, $len) === 'grademodified_') {
  2342 + // gather the userid, updated grade and last modified value
  2343 + $record = new stdClass();
  2344 + $record->userid = (int)substr($key, $len);
  2345 + $record->grade = required_param('quickgrade_' . $record->userid, PARAM_INT);
  2346 + $record->lastmodified = $value;
  2347 + $record->gradinginfo = grade_get_grades($this->get_course()->id, 'mod', 'assign', $this->get_instance()->id, array($record->userid));
  2348 + $users[$record->userid] = $record;
  2349 + }
  2350 + }
  2351 + list($userids, $useridparams) = $DB->get_in_or_equal(array_keys($users));
  2352 +
  2353 + // check them all for currency
  2354 + $currentgrades = $DB->get_recordset_sql('SELECT u.id as userid,
  2355 + g.grade as grade,
  2356 + g.timemodified as lastmodified
  2357 + FROM {user} u
  2358 + LEFT JOIN {assign_grades} g ON
  2359 + u.id = g.userid AND
  2360 + g.assignment = ? WHERE u.id ' .
  2361 + $userids,
  2362 + array_merge(array($this->get_instance()->id),
  2363 + $useridparams));
  2364 +
  2365 + $modifiedusers = array();
  2366 + foreach ($currentgrades as $current) {
  2367 + $modified = $users[(int)$current->userid];
  2368 +
  2369 + // check to see if the outcomes were modified
  2370 + if ($CFG->enableoutcomes) {
  2371 + foreach ($modified->gradinginfo->outcomes as $outcomeid => $outcome) {
  2372 + $oldoutcome = $outcome->grades[$modified->userid]->grade;
  2373 + $newoutcome = optional_param('outcome_' . $outcomeid . '_' . $modified->userid, -1, PARAM_INT);
  2374 + if ($oldoutcome != $newoutcome) {
  2375 + // can't check modified time for outcomes because it is not reported
  2376 + $modifiedusers[$modified->userid] = $modified;
  2377 + continue;
  2378 + }
  2379 + }
  2380 + }
  2381 +
  2382 +
  2383 + if (($current->grade < 0 || $current->grade === NULL) &&
  2384 + ($modified->grade < 0 || $modified->grade === NULL)) {
  2385 + // different ways to indicate no grade
  2386 + continue;
  2387 + }
  2388 + if ($current->grade != $modified->grade) {
  2389 + // grade changed
  2390 + if ((int)$current->lastmodified > (int)$modified->lastmodified) {
  2391 + // error - record has been modified since viewing the page
  2392 + return get_string('errorrecordmodified', 'assign');
  2393 + } else {
  2394 + $modifiedusers[$modified->userid] = $modified;
  2395 + }
  2396 + }
  2397 +
  2398 + }
  2399 +
  2400 + // ok - ready to process the updates
  2401 + foreach ($modifiedusers as $userid => $modified) {
  2402 + $grade = $this->get_user_grade($userid, true);
  2403 + $grade->grade= grade_floatval($modified->grade);
  2404 + $grade->grader= $USER->id;
  2405 +
  2406 + $this->update_grade($grade);
  2407 +
  2408 + // save outcomes
  2409 + if ($CFG->enableoutcomes) {
  2410 + $data = array();
  2411 + foreach ($modified->gradinginfo->outcomes as $outcomeid => $outcome) {
  2412 + $oldoutcome = $outcome->grades[$modified->userid]->grade;
  2413 + $newoutcome = optional_param('outcome_' . $outcomeid . '_' . $modified->userid, -1, PARAM_INT);
  2414 + if ($oldoutcome != $newoutcome) {
  2415 + $data[$outcomeid] = $newoutcome;
  2416 + }
  2417 + }
  2418 + if (count($data) > 0) {
  2419 + grade_update_outcomes('mod/assign', $this->course->id, 'mod', 'assign', $this->get_instance()->id, $userid, $data);
  2420 + }
  2421 + }
  2422 +
  2423 + $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
  2424 +
  2425 + $this->add_to_log('grade submission', $this->format_grade_for_log($grade));
  2426 + }
  2427 +
  2428 + return get_string('quickgradingchangessaved', 'assign');
  2429 + }
  2430 +
  2431 + /**
2260 2432 * save grading options
2261 2433 *
2262 2434 * @return void
@@ -2272,7 +2444,7 @@ private function process_save_grading_options() {
2272 2444
2273 2445
2274 2446
2275   - $mform = new mod_assign_grading_options_form(null, array('cm'=>$this->get_course_module()->id, 'contextid'=>$this->context->id, 'userid'=>$USER->id));
  2447 + $mform = new mod_assign_grading_options_form(null, array('cm'=>$this->get_course_module()->id, 'contextid'=>$this->context->id, 'userid'=>$USER->id, 'showquickgrading'=>false));
2276 2448
2277 2449 if ($formdata = $mform->get_data()) {
2278 2450 set_user_preference('assign_perpage', $formdata->perpage);
@@ -2295,7 +2467,7 @@ private function format_grade_for_log(stdClass $grade) {
2295 2467
2296 2468 $info = get_string('gradestudent', 'assign', array('id'=>$user->id, 'fullname'=>fullname($user)));
2297 2469 if ($grade->grade != '') {
2298   - $info .= get_string('grade') . ': ' . $this->display_grade($grade->grade) . '. ';
  2470 + $info .= get_string('grade') . ': ' . $this->display_grade($grade->grade, false) . '. ';
2299 2471 } else {
2300 2472 $info .= get_string('nograde', 'assign');
2301 2473 }
100 mod/assign/module.js
@@ -39,23 +39,25 @@ M.mod_assign.init_grading_table = function(Y) {
39 39 });
40 40
41 41 var selectall = Y.one('th.c0 input');
42   - selectall.on('change', function(e) {
43   - if (e.currentTarget.get('checked')) {
44   - checkboxes = Y.all('td.c0 input');
45   - checkboxes.each(function(node) {
46   - rowelement = node.get('parentNode').get('parentNode');
47   - node.set('checked', true);
48   - rowelement.setAttribute('class', 'selectedrow');
49   - });
50   - } else {
51   - checkboxes = Y.all('td.c0 input');
52   - checkboxes.each(function(node) {
53   - rowelement = node.get('parentNode').get('parentNode');
54   - node.set('checked', false);
55   - rowelement.setAttribute('class', 'unselectedrow');
56   - });
57   - }
58   - });
  42 + if (selectall) {
  43 + selectall.on('change', function(e) {
  44 + if (e.currentTarget.get('checked')) {
  45 + checkboxes = Y.all('td.c0 input');
  46 + checkboxes.each(function(node) {
  47 + rowelement = node.get('parentNode').get('parentNode');
  48 + node.set('checked', true);
  49 + rowelement.setAttribute('class', 'selectedrow');
  50 + });
  51 + } else {
  52 + checkboxes = Y.all('td.c0 input');
  53 + checkboxes.each(function(node) {
  54 + rowelement = node.get('parentNode').get('parentNode');
  55 + node.set('checked', false);
  56 + rowelement.setAttribute('class', 'unselectedrow');
  57 + });
  58 + }
  59 + });
  60 + }
59 61
60 62 var batchform = Y.one('form.gradingbatchoperationsform');
61 63 batchform.on('submit', function(e) {
@@ -99,8 +101,72 @@ M.mod_assign.init_grading_table = function(Y) {
99 101
100 102
101 103 });
  104 + quickgrade = Y.all('.gradingtable .quickgrade');
  105 + quickgrade.each(function(quick) {
  106 + quick.on('change', function(e) {
  107 + parent = this.get('parentNode');
  108 + parent.addClass('quickgrademodified');
  109 + });
  110 + });
  111 + });
  112 +};
  113 +
  114 +M.mod_assign.check_dirty_quickgrading_form = function(e) {
  115 +
  116 + if (!M.core_formchangechecker.get_form_dirty_state()) {
  117 + // the form is not dirty, so don't display any message
  118 + return;
  119 + }
  120 +
  121 + // This is the error message that we'll show to browsers which support it
  122 + var warningmessage = 'There are unsaved quickgrading changes. Do you really wanto to leave this page?';
  123 +
  124 + // Most browsers are happy with the returnValue being set on the event
  125 + // But some browsers do not consistently pass the event
  126 + if (e) {
  127 + e.returnValue = warningmessage;
  128 + }
  129 +
  130 + // But some require it to be returned instead
  131 + return warningmessage;
  132 +}
  133 +M.mod_assign.init_grading_options = function(Y) {
  134 + Y.use('node', function(Y) {
  135 +
  136 + var paginationelement = Y.one('#id_perpage');
  137 + paginationelement.on('change', function(e) {
  138 + Y.one('form.gradingoptionsform').submit();
  139 + });
  140 + var filterelement = Y.one('#id_filter');
  141 + filterelement.on('change', function(e) {
  142 + Y.one('form.gradingoptionsform').submit();
  143 + });
  144 + var quickgradingelement = Y.one('#id_quickgrading');
  145 + quickgradingelement.on('change', function(e) {
  146 + Y.one('form.gradingoptionsform').submit();
  147 + });
102 148
103 149 });
104 150
105 151
106 152 };
  153 +// override the default dirty form behaviour to ignore any input with the class "ignoredirty"
  154 +M.mod_assign.set_form_changed = M.core_formchangechecker.set_form_changed;
  155 +M.core_formchangechecker.set_form_changed = function(e) {
  156 + target = e.currentTarget;
  157 + if (!target.hasClass('ignoredirty')) {
  158 + M.mod_assign.set_form_changed(e);
  159 + }
  160 +}
  161 +
  162 +M.mod_assign.get_form_dirty_state = M.core_formchangechecker.get_form_dirty_state;
  163 +M.core_formchangechecker.get_form_dirty_state = function() {
  164 + var state = M.core_formchangechecker.stateinformation;
  165 + if (state.focused_element) {
  166 + if (state.focused_element.element.hasClass('ignoredirty')) {
  167 + state.focused_element.initial_value = state.focused_element.element.get('value')
  168 + }
  169 + }
  170 + return M.mod_assign.get_form_dirty_state();
  171 +}
  172 +
62 mod/assign/quickgradingform.php
... ... @@ -0,0 +1,62 @@
  1 +<?php
  2 +// This file is part of Moodle - http://moodle.org/
  3 +//
  4 +// Moodle is free software: you can redistribute it and/or modify
  5 +// it under the terms of the GNU General Public License as published by
  6 +// the Free Software Foundation, either version 3 of the License, or
  7 +// (at your option) any later version.
  8 +//
  9 +// Moodle is distributed in the hope that it will be useful,
  10 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12 +// GNU General Public License for more details.
  13 +//
  14 +// You should have received a copy of the GNU General Public License
  15 +// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16 +
  17 +/**
  18 + * This file contains the forms to create and edit an instance of this module
  19 + *
  20 + * @package mod_assign
  21 + * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
  22 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23 + */
  24 +
  25 +defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.');
  26 +
  27 +
  28 +/** Include formslib.php */
  29 +require_once ($CFG->libdir.'/formslib.php');
  30 +/** Include locallib.php */
  31 +require_once($CFG->dirroot . '/mod/assign/locallib.php');
  32 +
  33 +/**
  34 + * Assignment quick grading form
  35 + *
  36 + * @package mod_assign
  37 + * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
  38 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  39 + */
  40 +class mod_assign_quick_grading_form extends moodleform {
  41 + /**
  42 + * Define this form - called from the parent constructor
  43 + */
  44 + function definition() {
  45 + $mform = $this->_form;
  46 + $instance = $this->_customdata;
  47 +
  48 + // visible elements
  49 + $mform->addElement('html', $instance['gradingtable']);
  50 +
  51 + // hidden params
  52 + $mform->addElement('hidden', 'id', $instance['cm']);
  53 + $mform->setType('id', PARAM_INT);
  54 + $mform->addElement('hidden', 'action', 'quickgrade');
  55 + $mform->setType('action', PARAM_ALPHA);
  56 +
  57 + // buttons
  58 + $mform->addElement('header', 'general', get_string('quickgrading', 'assign'));
  59 + $mform->addElement('submit', 'savequickgrades', get_string('saveallchanges', 'assign'));
  60 + }
  61 +}
  62 +
34 mod/assign/renderable.php
@@ -49,6 +49,29 @@ public function __construct($notifications, $coursemoduleid) {
49 49 }
50 50
51 51 /**
  52 + * Implements a renderable grading error notification
  53 + * @package mod_assign
  54 + * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
  55 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  56 + */
  57 +class assign_quickgrading_result implements renderable {
  58 + /** @var string $message is the message to display to the user */
  59 + var $message = '';
  60 + /** @var int $coursemoduleid */
  61 + var $coursemoduleid = 0;
  62 +
  63 + /**
  64 + * Constructor
  65 + * @param string $message This is the message to display
  66 + */
  67 + public function __construct($message, $coursemoduleid) {
  68 + $this->message = $message;
  69 + $this->coursemoduleid = $coursemoduleid;
  70 + }
  71 +
  72 +}
  73 +
  74 +/**
52 75 * Implements a renderable grading options form
53 76 * @package mod_assign
54 77 * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
@@ -59,19 +82,24 @@ class assign_form implements renderable {
59 82 var $form = null;
60 83 /** @var string $classname is the name of the class to assign to the container */
61 84 var $classname = '';
  85 + /** @var string $jsinitfunction is an optional js function to add to the page requires */
  86 + var $jsinitfunction = '';
62 87
63 88 /**
64 89 * Constructor
65   - * @param string $classname
66   - * @param moodleform $form
  90 + * @param string $classname This is the class name for the container div
  91 + * @param moodleform $form This is the moodleform
  92 + * @param string $jsinitfunction This is an optional js function to add to the page requires
67 93 */
68   - public function __construct($classname, moodleform $form) {
  94 + public function __construct($classname, moodleform $form, $jsinitfunction = '') {
69 95 $this->classname = $classname;
70 96 $this->form = $form;
  97 + $this->jsinitfunction = $jsinitfunction;
71 98 }
72 99
73 100 }
74 101
  102 +
75 103 /**
76 104 * Implements a renderable user summary
77 105 * @package mod_assign
21 mod/assign/renderer.php
@@ -87,12 +87,33 @@ private function add_table_row_tuple(html_table $table, $first, $second) {
87 87 }
88 88
89 89 /**
  90 + * Render a grading error notification
  91 + * @param assign_quickgrading_result $result The result to render
  92 + * @return string
  93 + */
  94 + public function render_assign_quickgrading_result(assign_quickgrading_result $result) {
  95 + $o = '';
  96 + $o .= $this->output->heading(get_string('quickgradingresult', 'assign'), 4);
  97 +
  98 + $o .= $this->output->notification($result->message);
  99 +
  100 + $o .= $this->output->continue_button(new moodle_url('/mod/assign/view.php',
  101 + array('id' => $result->coursemoduleid,
  102 + 'action'=>'grading')));
  103 +
  104 + return $o;
  105 + }
  106 +
  107 + /**
90 108 * Render the generic form
91 109 * @param assign_form $form The form to render
92 110 * @return string
93 111 */
94 112 public function render_assign_form(assign_form $form) {
95 113 $o = '';
  114 + if ($form->jsinitfunction) {
  115 + $this->page->requires->js_init_call($form->jsinitfunction, array());
  116 + }
96 117 $o .= $this->output->box_start('boxaligncenter ' . $form->classname);
97 118 $o .= $this->moodleform($form->form);
98 119 $o .= $this->output->box_end();
4 mod/assign/styles.css
@@ -128,3 +128,7 @@ div.earlysubmission {
128 128 border: 0px;
129 129 }
130 130
  131 +#page-mod-assign-view div.gradingtable tr .quickgrademodified {
  132 + background-color: #FFCC99;
  133 +}
  134 +

0 comments on commit bf78ebd

Please sign in to comment.
Something went wrong with that request. Please try again.