From 245f45f4d6e3a072793f1430b679b882093dee03 Mon Sep 17 00:00:00 2001 From: Paul Nicholls Date: Thu, 29 Oct 2015 09:29:16 +1300 Subject: [PATCH] MDL-51918 gradereport: Fix AJAX mode keyboard navigation Keyboard navigation (ctrl+up/down/left/right) with AJAX enabled ceased functioning with editing mode enabled after MDL-36606, as it was looking for cells with a "clickable" class - but was only applying that class when editing mode is NOT enabled. This patch uses a new "gbnavigable" class to control keyboard navigation, whether editing mode is on or not. It also addresses some browser compatibility and minor behavioural issues. --- grade/report/grader/lib.php | 8 ++++++++ grade/report/grader/module.js | 35 +++++++++++++++++++---------------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/grade/report/grader/lib.php b/grade/report/grader/lib.php index 85d3a9536a5..aba460fb9e0 100644 --- a/grade/report/grader/lib.php +++ b/grade/report/grader/lib.php @@ -1109,6 +1109,14 @@ class grade_report_grader extends grade_report { } } + // Enable keyboard navigation if the grade is editable (not locked, not in a unoverridable category, etc). + if ($enableajax && $grade->is_editable()) { + // If a grade item is type text, and we don't have show quick feedback on, it can't be edited. + if ($item->gradetype != GRADE_TYPE_TEXT || $showquickfeedback) { + $itemcell->attributes['class'] .= ' gbnavigable'; + } + } + if (!empty($this->gradeserror[$item->id][$userid])) { $itemcell->text .= $this->gradeserror[$item->id][$userid]; } diff --git a/grade/report/grader/module.js b/grade/report/grader/module.js index 2fac542b5bd..0199090585a 100644 --- a/grade/report/grader/module.js +++ b/grade/report/grader/module.js @@ -251,6 +251,7 @@ M.gradereport_grader.classes.ajax.prototype.keypress_enter = function(e) { * @param {Bool} ignoreshift If true and shift is pressed then don't exec */ M.gradereport_grader.classes.ajax.prototype.keypress_tab = function(e, ignoreshift) { + e.preventDefault(); var next = null; if (e.shiftKey) { if (ignoreshift) { @@ -328,8 +329,8 @@ M.gradereport_grader.classes.ajax.prototype.get_next_cell = function(cell) { if (!next) { return this.current.node; } - // Continue on until we find a clickable cell - if (!next.hasClass('clickable')) { + // Continue on until we find a navigable cell + if (!next.hasClass('gbnavigable')) { return this.get_next_cell(next); } return next; @@ -352,8 +353,8 @@ M.gradereport_grader.classes.ajax.prototype.get_prev_cell = function(cell) { if (!next) { return this.current.node; } - // Continue on until we find a clickable cell - if (!next.hasClass('clickable')) { + // Continue on until we find a navigable cell + if (!next.hasClass('gbnavigable')) { return this.get_prev_cell(next); } return next; @@ -380,8 +381,8 @@ M.gradereport_grader.classes.ajax.prototype.get_above_cell = function(cell) { if (!next) { return this.current.node; } - // Continue on until we find a clickable cell - if (!next.hasClass('clickable')) { + // Continue on until we find a navigable cell + if (!next.hasClass('gbnavigable')) { return this.get_above_cell(next); } return next; @@ -408,8 +409,8 @@ M.gradereport_grader.classes.ajax.prototype.get_below_cell = function(cell) { if (!next) { return this.current.node; } - // Continue on until we find a clickable cell - if (!next.hasClass('clickable')) { + // Continue on until we find a navigable cell + if (!next.hasClass('gbnavigable')) { return this.get_below_cell(next); } return next; @@ -700,13 +701,13 @@ M.gradereport_grader.classes.existingfield = function(ajax, userid, itemid) { } } else if (this.grade) { // Handle Tab and Shift+Tab. - this.keyevents.push(this.report.Y.on('key', this.keypress_tab, this.grade, 'press:9', this)); + this.keyevents.push(this.report.Y.on('key', this.keypress_tab, this.grade, 'down:9', this)); } if (this.grade) { // Handle the Enter key being pressed. - this.keyevents.push(this.report.Y.on('key', this.keypress_enter, this.grade, 'press:13', this)); + this.keyevents.push(this.report.Y.on('key', this.keypress_enter, this.grade, 'up:13', this)); // Handle CTRL + arrow keys. - this.keyevents.push(this.report.Y.on('key', this.keypress_arrows, this.grade, 'press:37,38,39,40+ctrl', this)); + this.keyevents.push(this.report.Y.on('key', this.keypress_arrows, this.grade, 'down:37,38,39,40+ctrl', this)); } }; /** @@ -759,6 +760,7 @@ M.gradereport_grader.classes.existingfield.prototype.keypress_tab = function(e, * @param {Event} e */ M.gradereport_grader.classes.existingfield.prototype.keypress_arrows = function(e) { + e.preventDefault(); var next = null; switch (e.keyCode) { case 37: // Left @@ -785,6 +787,7 @@ M.gradereport_grader.classes.existingfield.prototype.keypress_arrows = function( M.gradereport_grader.classes.existingfield.prototype.move_focus = function(node) { if (node) { var properties = this.report.get_cell_info(node); + this.report.ajax.current = node; switch(properties.itemtype) { case 'scale': properties.cell.one('select.select').focus(); @@ -1078,16 +1081,16 @@ M.gradereport_grader.classes.textfield.prototype.attach_key_events = function() if (this.editfeedback) { if (this.grade) { // Handle Shift+Tab. - this.keyevents.push(this.report.Y.on('key', a.keypress_tab, this.grade, 'press:9+shift', a)); + this.keyevents.push(this.report.Y.on('key', a.keypress_tab, this.grade, 'down:9+shift', a)); } // Handle Tab. - this.keyevents.push(this.report.Y.on('key', a.keypress_tab, this.feedback, 'press:9', a, true)); + this.keyevents.push(this.report.Y.on('key', a.keypress_tab, this.feedback, 'down:9', a, true)); // Handle the Enter key being pressed. - this.keyevents.push(this.report.Y.on('key', a.keypress_enter, this.feedback, 'press:13', a)); + this.keyevents.push(this.report.Y.on('key', a.keypress_enter, this.feedback, 'up:13', a)); } else { if (this.grade) { // Handle Tab and Shift+Tab. - this.keyevents.push(this.report.Y.on('key', a.keypress_tab, this.grade, 'press:9', a)); + this.keyevents.push(this.report.Y.on('key', a.keypress_tab, this.grade, 'down:9', a)); } } @@ -1097,7 +1100,7 @@ M.gradereport_grader.classes.textfield.prototype.attach_key_events = function() if (this.grade) { // Handle the Enter key being pressed. - this.keyevents.push(this.report.Y.on('key', a.keypress_enter, this.grade, 'press:13', a)); + this.keyevents.push(this.report.Y.on('key', a.keypress_enter, this.grade, 'up:13', a)); // Prevent the default key action on all fields for arrow keys on all key events! // Note: this still does not work in FF!!!!! this.keyevents.push(this.report.Y.on('key', function(e){e.preventDefault();}, this.grade, 'down:37,38,39,40+ctrl'));