diff --git a/grade/report/singleview/classes/local/ui/dropdown_attribute.php b/grade/report/singleview/classes/local/ui/dropdown_attribute.php index aaaed88752c..19bc80c6f8e 100644 --- a/grade/report/singleview/classes/local/ui/dropdown_attribute.php +++ b/grade/report/singleview/classes/local/ui/dropdown_attribute.php @@ -83,7 +83,7 @@ class dropdown_attribute extends element { 'value' => $this->selected ); - $attributes = array(); + $attributes = array('tabindex' => '1'); if (!empty($this->isdisabled)) { $attributes['disabled'] = 'DISABLED'; diff --git a/grade/report/singleview/classes/local/ui/text_attribute.php b/grade/report/singleview/classes/local/ui/text_attribute.php index 2766a9de8d6..01021993f69 100644 --- a/grade/report/singleview/classes/local/ui/text_attribute.php +++ b/grade/report/singleview/classes/local/ui/text_attribute.php @@ -85,9 +85,11 @@ class text_attribute extends element { $label = ''; if (preg_match("/^feedback/", $this->name)) { $labeltitle = get_string('feedbackfor', 'gradereport_singleview', $this->label); + $attributes['tabindex'] = '2'; $label = html_writer::tag('label', $labeltitle, array('for' => $this->name, 'class' => 'accesshide')); } else if (preg_match("/^finalgrade/", $this->name)) { $labeltitle = get_string('gradefor', 'gradereport_singleview', $this->label); + $attributes['tabindex'] = '1'; $label = html_writer::tag('label', $labeltitle, array('for' => $this->name, 'class' => 'accesshide')); } diff --git a/grade/report/singleview/js/singleview.js b/grade/report/singleview/js/singleview.js index 0c377b882a7..7ee45eb206b 100644 --- a/grade/report/singleview/js/singleview.js +++ b/grade/report/singleview/js/singleview.js @@ -1,6 +1,96 @@ M.gradereport_singleview = {}; M.gradereport_singleview.init = function(Y) { + var getColumnIndex = function(cell) { + var rowNode = cell.ancestor('tr'); + if (!rowNode || !cell) { + return; + } + var cells = rowNode.all('td, th'); + return cells.indexOf(cell); + }, + getNextCell = function(cell) { + var n = cell || document.activeElement, + next = n.next('td.cell, th.cell'); + if (!next) { + return null; + } + // Continue on until we find a navigable cell + if (!next || !Y.one(next).one('input:not([type="hidden"]):not([disabled="DISABLED"]), select, a')) { + return getNextCell(next); + } + return next; + }, + getPrevCell = function(cell) { + var n = cell || document.activeElement, + next = n.previous('td.cell, th.cell'); + if (!next) { + return null; + } + // Continue on until we find a navigable cell + if (!Y.one(next).one('input:not([type="hidden"]):not([disabled="DISABLED"]), select, a')) { + return getPrevCell(next); + } + return next; + }, + getAboveCell = function(cell) { + var n = cell || document.activeElement, + tr = n.ancestor('tr').previous('tr'), + columnIndex = getColumnIndex(n), + next = null; + if (tr) { + next = tr.all('td, th').item(columnIndex); + } else { + return null; + } + // Continue on until we find a navigable cell + if (!Y.one(next).one('input:not([type="hidden"]):not([disabled="DISABLED"]), select, a')) { + return getAboveCell(next); + } + return next; + }, + getBelowCell = function(cell) { + var n = cell || document.activeElement, + tr = n.ancestor('tr').next('tr'), + columnIndex = getColumnIndex(n), + next = null; + if (tr) { + next = tr.all('td, th').item(columnIndex); + } else { + return null; + } + // Continue on until we find a navigable cell + if (!Y.one(next).one('input:not([type="hidden"]):not([disabled="DISABLED"]), select, a')) { + return getBelowCell(next); + } + return next; + }; + + // Add ctrl+arrow controls for navigation + Y.one(Y.config.doc.body).delegate('key', function(e) { + e.preventDefault(); + e.stopPropagation(); + var next = null; + switch (e.keyCode) { + case 37: + next = getPrevCell(this.ancestor('td, th')); + break; + case 38: + next = getAboveCell(this.ancestor('td, th')); + break; + case 39: + next = getNextCell(this.ancestor('td, th')); + break; + case 40: + next = getBelowCell(this.ancestor('td, th')); + break; + } + if (next) { + Y.one(next).one('input:not([type="hidden"]):not([disabled="DISABLED"]), select, a').focus(); + } + return; + }, 'down:37,38,39,40+ctrl', 'table input, table select, table a'); + // Make toggle links Y.all('.include').each(function(link) { var type = link.getAttribute('class').split(" ")[2];