Commit ec2aa2cb authored by Cecilia Vela Gurovic's avatar Cecilia Vela Gurovic Committed by Robert Lyon
Browse files

Bug 1701083: SE matrix accessibility

 - Modified tags in template so screen readers
can see them correctly
 - Tabbing goes through each cell of the table
and collapsible sections heading
 - Opening a modal sets focus on the delete button
of the modal ('X')
 - Tabbing inside a modal dialog loops through the
elements of that dialog
 - Closing modal dialog sets focus back on the
annotation cell
 - Clicking on standard title (first cell of a row)
will display description of standard. The element
can also be reached with tab key and description
can be opened with enter key. The description box
disappears when it loses focus

behatnotneeded

Change-Id: Ia164cca7517bad89c60685757947dd14e27aef75
parent 0f01e034
......@@ -988,3 +988,21 @@ function parseQueryString(encodedString, useArrays) {
}
return o;
}
/**
* Make sure the previous/next key tabbing will move within the dialog
*/
function keytabbinginadialog(dialog, firstelement, lastelement) {
firstelement.keydown(function(e) {
if (e.keyCode === $j.ui.keyCode.TAB && e.shiftKey) {
lastelement.focus();
e.preventDefault();
}
});
lastelement.keydown(function(e) {
if (e.keyCode === $j.ui.keyCode.TAB && !e.shiftKey) {
firstelement.focus();
e.preventDefault();
}
});
}
......@@ -358,24 +358,6 @@
});
}
/**
* Make sure the previous/next key tabbing will move within the dialog
*/
function keytabbinginadialog(dialog, firstelement, lastelement) {
firstelement.keydown(function(e) {
if (e.keyCode === $j.ui.keyCode.TAB && e.shiftKey) {
lastelement.focus();
e.preventDefault();
}
});
lastelement.keydown(function(e) {
if (e.keyCode === $j.ui.keyCode.TAB && !e.shiftKey) {
firstelement.focus();
e.preventDefault();
}
});
}
function startAddBlock(element) {
var addblockdialog = $('#addblock');
addblockdialog.modal('show');
......
This diff is collapsed.
......@@ -53,3 +53,20 @@ $string['selfassess'] = 'Self-assess';
$string['uploadframeworkdesc1'] = 'Upload a JSON encoded .matrix file. See the <a href="https://git.mahara.org/mahara/mahara/blob/16.10_STABLE/test/behat/upload_files/example.matrix">Mahara git repository</a> for an example of the markup and the <a href="http://manual.mahara.org/en/16.10/administration/smartevidence.html#create-a-framework-file">Mahara user manual</a> for an explanation of the individual components.';
$string['savematrix'] = 'Upload matrix';
$string['frameworkmissing'] = 'Framework not found';
$string['noannotation'] = 'There are no annotations on page "%s" for standard element "%s"';
$string['addannotation'] = 'Add annotation for standard "%s" to page "%s"';
$string['completedcount'] = 'Number of pages that contain the completed standard element:';
$string['tabledesc'] = 'Below is the structure for the collection\'s SmartEvidence matrix.';
$string['standardbegin'] = 'Beginning of a standard section';
$string['uncollapsesection'] = 'Click to show the table section for standard "%s"';
$string['collapsesection'] = 'Click to hide the section for standard "%s"';
$string['collapsedsection'] = 'This table section for the standard is hidden';
$string['gonextpages'] = 'Click the "Next" button to display more pages of the collection in the SmartEvidence matrix.';
$string['goprevpages'] = 'Click the "Previous" button to display pages in the SmartEvidence matrix that come earlier in the collection.';
$string['headerelements'] = 'Column header: Standar elements';
$string['headercompletedcount'] = 'Column header: Number of pages that contain the completed standard element';
$string['headerpage'] = 'Column header: Page title';
$string['headerrow'] = 'Row header: Standard element';
$string['showelementdetails'] = 'Click to show standard element details';
$string['statusdetail'] = 'Page "%s": %s';
......@@ -77,7 +77,7 @@ foreach ($standards['standards'] as $standard) {
define('TITLE', $collection->get('name'));
$javascript = array('js/collection-navigation.js', 'tinymce', 'module/framework/js/matrix.js');
$javascript = array('js/collection-navigation.js', 'tinymce', 'module/framework/js/matrix.js', 'js/jquery/jquery-ui/js/jquery-ui.min.js');
// Set up theme
$viewtheme = $view->get('theme');
......
......@@ -26,7 +26,7 @@ $collectionid = param_integer('collection');
$state = param_alphanum('state', 'open');
form_validate(param_variable('sesskey', null));
if ($frameworkid = get_record_sql("SELECT fs.framework FROM {framework_standard} fs
if ($frameworksection = get_record_sql("SELECT fs.framework, fs.shortname FROM {framework_standard} fs
JOIN {collection} c on c.framework = fs.framework
WHERE fs.id = ? and c.id = ?", array($sectionid, $collectionid))) {
if (isset($_SESSION['matrixsettings'])) {
......@@ -35,10 +35,15 @@ if ($frameworkid = get_record_sql("SELECT fs.framework FROM {framework_standard}
else {
$matrixsettings = array();
}
$title = isset($frameworksection->shortname) ? hsc($frameworksection->shortname) : '';
$matrixsettings[$collectionid][$sectionid] = $state;
$matrixsettings['description']['open'] = get_string('collapsesection', 'module.framework', $title);
$matrixsettings['description']['close'] = get_string('uncollapsesection', 'module.framework', $title);
$matrixsettings['description']['sectioncollapsed'] = get_string('collapsedsection','module.framework');
$SESSION->set('matrixsettings', $matrixsettings);
json_reply(false, (object) array('settings' => $matrixsettings));
}
else {
json_reply(true, get_string('frameworkstateerror', 'module.framework'));
}
\ No newline at end of file
}
......@@ -14,24 +14,36 @@
<p>{$description|clean_html|safe}</p>
<p>{str tag="addpages" section="module.framework"}</p>
<table class="fullwidth table tablematrix" id="tablematrix">
<caption class="sr-only">{str tag="tabledesc" section="module.framework"}</caption>
<tr class="table-pager">
<td colspan="2">&nbsp;</td>
<td colspan="{$viewcount}" class="special">
<button class="btn btn-default" id="prev">
<span class="icon left icon-chevron-left" aria-hidden="true" role="presentation"></span>
Prev
<span class="sr-only">{str tag="goprevpages" section="module.framework"}</span>
</button>
<button class="btn btn-default next" id="next">
Next
<span class="icon right icon-chevron-right" aria-hidden="true" role="presentation"></span>
<span class="sr-only">{str tag="gonextpages" section="module.framework"}</span>
</button>
</td>
</tr>
<tr class="pages">
<th>&nbsp;</th>
<th>&nbsp;</th>
<th>
<span class="sr-only">{str tag="headerelements" section="module.framework"}</span>
&nbsp;
</th>
<th>
<span class="sr-only">{str tag="headercompletedcount" section="module.framework"}</span>
&nbsp;
</th>
{foreach from=$views key=vk item=view}
<th class="viewtab"><a href="{$view->fullurl}">{$view->title}</a></th>
<th class="viewtab" scope="col">
<span class="sr-only">{str tag="headerpage" section="module.framework"}</span>
<a href="{$view->fullurl}">{$view->title}</a>
</th>
{/foreach}
</tr>
{foreach from=$standards key=sk item=standard}
......@@ -39,8 +51,19 @@
data-toggle="collapse" aria-expanded="{if $standard->settingstate == 'closed'}false{else}true{/if}">
<td colspan="{$viewcount + 2}">
<div class="shortname-container">
<span class="sr-only">{str tag="standardbegin" section="module.framework"}</span>
<span class="icon icon-chevron-down collapse-indicator right pull-right"></span>
<h3>{$standard->name}</h3>
<span class="sr-only status">{if $standard->settingstate == 'closed'}{str tag="collapsedsection" section="module.framework"}{/if}</span>
<a href="#">
<span class="sr-only action">
{if $standard->settingstate == 'closed'}
{str tag="uncollapsesection" arg1="$standard->name" section="module.framework"}
{else}
{str tag="collapsesection" arg1="$standard->name" section="module.framework"}
{/if}
</span>
</a>
<div class="matrixtooltip popover hidden">
<h3 class="popover-title">{$standard->name}</h3>
<div class="popover-content">
......@@ -56,11 +79,14 @@
<tr class="matrixlevel{$option->level} examplefor{$standard->id}{if $standard->settingstate == 'closed'} hidden{/if}">
<td colspan="{$viewcount + 2}" class="code">
<div class="shortname-container">
<span class="sr-only">{str tag="headerrow" section="module.framework"}</span>
{for name=foo from=0 to=$option->level step=1}
{if $dwoo.for.foo.index != $option->level}
<span class="matrixindent"></span>
{/if}
{/for} {$option->name}
{/for}
{$option->name}
<span class="sr-only">{str tag="showelementdetails" section="module.framework"}</span>
<div class="matrixtooltip popover hidden">
<h3 class="popover-title">{$option->name}</h3>
<div class="popover-content">
......@@ -73,12 +99,15 @@
{else}
<tr class="matrixlevel{$option->level} examplefor{$standard->id}{if $standard->settingstate == 'closed'} hidden{/if}">
<td class="code">
<div class="shortname-container">
<div class="shortname-container" tabindex="0">
<span class="sr-only">{str tag="headerrow" section="module.framework"}</span>
{for name=foo2 from=0 to=$option->level step=1}
{if $dwoo.for.foo2.index != $option->level}
<span class="matrixindent"></span>
{/if}
{/for}{$option->shortname}
{/for}
{$option->shortname}
<span class="sr-only">{str tag="showelementdetails" section="module.framework"}</span>
<div class="matrixtooltip popover hidden">
<h3 class="popover-title">{$option->name}</h3>
<div class="popover-content">
......@@ -87,15 +116,32 @@
</div>
</div>
</td>
<td class="completedcount">{if $completed[$option->id]}{$completed[$option->id]}{else}0{/if}</td>
<td class="completedcount">
<span class="sr-only">{str tag="completedcount" section="module.framework"}</span>
<span>
{if $completed[$option->id]}{$count = $completed[$option->id]}{else}{$count = 0}{/if}
{$count}
</span>
</td>
{foreach from=$views key=vk item=view}
<td class="mid"><span data-view="{$view->id}" data-option="{$option->id}"
<td class="mid">
<span data-view="{$view->id}" data-option="{$option->id}"
{if $evidence[$framework][$option->id][$view->id].state}
class="{$evidence[$framework][$option->id][$view->id].classes}" title="{$evidence[$framework][$option->id][$view->id].title}">
class="{$evidence[$framework][$option->id][$view->id].classes}" title="{$evidence[$framework][$option->id][$view->id].title}">
<a href="#"></a></span>
<span class="sr-only">{str tag="statusdetail" arg1=$view->title arg2=$evidence[$framework][$option->id][$view->id].title section="module.framework"}</span>
{else}
class="icon icon-circle dot {if !$canaddannotation}disabled{/if}">
class="icon icon-circle dot {if !$canaddannotation}disabled{/if}">
{if !$canaddannotation}
<a href="#"></a></span><span class="sr-only">
{str tag="noannotation" arg1="$view->title" arg2="$option->shortname" section="module.framework"}
</span>
{else}
<a href="#"></a></span><span class="sr-only">
{str tag="addannotation" arg1="$option->shortname" arg2="$view->title" section="module.framework"}
</span>
{/if}
{/if}
</span>
</td>
{/foreach}
</tr>
......@@ -121,4 +167,4 @@
</div>
</div>
</div>
{include file="footer.tpl"}
\ No newline at end of file
{include file="footer.tpl"}
......@@ -46,5 +46,6 @@ Scenario: Accessing annotation block
# Click the matrix point and test empty annotation message
And I click on the matrix point "3,4"
And I wait "1" seconds
And I press "Save"
And I should see "This field is required"
......@@ -103,6 +103,7 @@ Scenario: Installing framework module and activating for an institution
Given I log in as "userA" with password "Kupuhipa1"
And I follow "CollA"
And I click on the matrix point "3,4"
And I wait "1" seconds
And I select "Partially meets the standard" from "Assessment"
And I press "Save"
Then I should see "SmartEvidence updated"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment