From 80ef82e3f3e9952e8b7121c503388dc89636d97e 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. # Conflicts: # grade/report/grader/module.js --- grade/report/grader/lib.php | 8 +++++++ grade/report/grader/module.js | 43 ++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/grade/report/grader/lib.php b/grade/report/grader/lib.php index 68b5702a357..48a0b1fa4e1 100644 --- a/grade/report/grader/lib.php +++ b/grade/report/grader/lib.php @@ -1102,6 +1102,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 2b368983314..b8523324a85 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; @@ -687,11 +688,14 @@ M.gradereport_grader.classes.existingfield = function(ajax, userid, itemid) { } } } else if (this.grade) { - this.keyevents.push(this.report.Y.on('key', this.keypress_tab, this.grade, 'press:9', this)); // Handle Tab and Shift+Tab + // Handle Tab and Shift+Tab. + this.keyevents.push(this.report.Y.on('key', this.keypress_tab, this.grade, 'down:9', this)); } if (this.grade) { - this.keyevents.push(this.report.Y.on('key', this.keypress_enter, this.grade, 'press:13', this)); // Handle the Enter key being pressed - this.keyevents.push(this.report.Y.on('key', this.keypress_arrows, this.grade, 'press:37,38,39,40+ctrl', this)); // Handle CTRL + arrow keys + // Handle the Enter key being pressed. + 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, 'down:37,38,39,40+ctrl', this)); } }; /** @@ -744,6 +748,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 @@ -770,6 +775,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(); @@ -1062,13 +1068,17 @@ M.gradereport_grader.classes.textfield.prototype.attach_key_events = function() // Setup the default key events for tab and enter if (this.editfeedback) { if (this.grade) { - this.keyevents.push(this.report.Y.on('key', a.keypress_tab, this.grade, 'press:9+shift', a)); // Handle Shift+Tab + // Handle Shift+Tab. + this.keyevents.push(this.report.Y.on('key', a.keypress_tab, this.grade, 'down:9+shift', a)); } - this.keyevents.push(this.report.Y.on('key', a.keypress_tab, this.feedback, 'press:9', a, true)); // Handle Tab - this.keyevents.push(this.report.Y.on('key', a.keypress_enter, this.feedback, 'press:13', a)); // Handle the Enter key being pressed + // Handle Tab. + 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, 'up:13', a)); } else { if (this.grade) { - this.keyevents.push(this.report.Y.on('key', a.keypress_tab, this.grade, 'press:9', a)); // Handle Tab and Shift+Tab + // Handle Tab and Shift+Tab. + this.keyevents.push(this.report.Y.on('key', a.keypress_tab, this.grade, 'down:9', a)); } } @@ -1076,7 +1086,8 @@ M.gradereport_grader.classes.textfield.prototype.attach_key_events = function() this.keyevents.push(this.report.Y.on('key', a.keypress_arrows, this.inputdiv.ancestor('td'), 'down:37,38,39,40+ctrl', a)); // Handle CTRL + arrow keys if (this.grade) { - this.keyevents.push(this.report.Y.on('key', a.keypress_enter, this.grade, 'press:13', a)); // Handle the Enter key being pressed + // Handle the Enter key being pressed. + 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'));