Commit b90f215f authored by Jono Mingard's avatar Jono Mingard
Browse files

Link form inputs to description text with aria-describedby (Bug #1259388)



All pieform elements (and inputs within composite elements) are now linked
using the aria-describedby attribute to their help text, to aid screen reader
users.

Change-Id: I5eb4ab7b7561c1dabb74a6b772b84eb6a3e197d4
Signed-off-by: default avatarJono Mingard <jonom@catalyst.net.nz>
parent b1b62431
......@@ -57,6 +57,10 @@ function pieform_element_emaillist(Pieform $form, $element) {
$smarty->assign('validationemailstr', json_encode(get_string('validationemailwillbesent', 'artefact.internal')));
$smarty->assign('disabled', !empty($element['disabled']));
if (isset($element['description'])) {
$smarty->assign('describedby', $form->get_name() . '_' . $element['id'] . '_description');
}
return $smarty->fetch('form/emaillist.tpl');
}
......
......@@ -45,6 +45,9 @@ function pieform_element_tags(Pieform $form, $element) {
$smarty->assign('size', $element['size']);
$smarty->assign('id', $form->get_name() . '_' . $element['id']);
$smarty->assign('value', join(', ', $value));
if (isset($element['description'])) {
$smarty->assign('describedby', $form->get_name() . '_' . $element['id'] . '_description');
}
$smarty->left_delimiter = '{{';
$smarty->right_delimiter = '}}';
......
......@@ -1116,6 +1116,10 @@ EOF;
$result .= ' title="' . self::hsc($element['elementtitle']) . '"';
}
if (isset($element['description'])) {
$result .= ' aria-describedby="' . $element['id'] . '_description"';
}
if (!in_array('maxlength', $exclude) && isset($element['rules']['maxlength'])) {
$result .= ' maxlength="' . intval($element['rules']['maxlength']) . '"';
}
......
......@@ -68,9 +68,17 @@ function pieform_element_bytes(Pieform $form, $element) {/*{{{*/
$numberinput = '<input';
$numberinput .= ' type="text" size="6" name="' . $name . '"';
$numberinput .= ' id="' . $formname . '_' . $name . '" value="' . Pieform::hsc($values['number']) . '" tabindex="' . Pieform::hsc($element['tabindex']) . '"';
$numberinput .= (isset($element['error']) ? ' class="error"' : '') . ">\n";
$numberinput .= (isset($element['error']) ? ' class="error"' : '');
if (isset($element['description'])) {
$numberinput .= ' aria-describedby="' . $form->get_name() . '_' . $element['id'] . '_description' . '"';
}
$numberinput .= ">\n";
$uselect = '<select name="' . $name . '_units" id="' . $formname . '_' . $name . '_units"' . ' tabindex="' . Pieform::hsc($element['tabindex']) . "\">\n";
$uselect = '<select name="' . $name . '_units" id="' . $formname . '_' . $name . '_units"' . ' tabindex="' . Pieform::hsc($element['tabindex']) . '"';
if (isset($element['description'])) {
$uselect .= ' aria-describedby="' . $form->get_name() . '_' . $element['id'] . '_description' . '"';
}
$uselect .= ">\n";
foreach (pieform_element_bytes_get_bytes_units() as $u) {
$uselect .= "\t<option value=\"$u\"" . (($values['units'] == $u) ? ' selected="selected"' : '') . '>'
. $form->i18n('element', 'bytes', $u, $element) . "</option>\n";
......
......@@ -46,7 +46,11 @@ function pieform_element_date(Pieform $form, $element) {/*{{{*/
$value = pieform_element_date_get_timeperiod_value('year', $element['minyear'], $element['maxyear'], $element, $form);
$year = '<select name="' . $name . '_year" id="' . $name . '_year"'
. (!$required && !isset($element['defaultvalue']) ? ' disabled="disabled"' : '')
. ' tabindex="' . Pieform::hsc($element['tabindex']) . "\">\n";
. ' tabindex="' . Pieform::hsc($element['tabindex']) . '"';
if (isset($element['description'])) {
$year .= ' aria-describedby="' . $form->get_name() . '_' . $element['id'] . '_description' . '"';
}
$year .= ">\n";
for ($i = $element['minyear']; $i <= $element['maxyear']; $i++) {
$year .= "\t<option value=\"$i\"" . (($value == $i) ? ' selected="selected"' : '') . ">$i</option>\n";
}
......@@ -56,7 +60,11 @@ function pieform_element_date(Pieform $form, $element) {/*{{{*/
$value = pieform_element_date_get_timeperiod_value('month', 1, 12, $element, $form);
$month = '<select name="' . $name . '_month" id="' . $name . '_month"'
. (!$required && !isset($element['defaultvalue']) ? ' disabled="disabled"' : '')
. ' tabindex="' . Pieform::hsc($element['tabindex']) . "\">\n";
. ' tabindex="' . Pieform::hsc($element['tabindex']) . '"';
if (isset($element['description'])) {
$month .= ' aria-describedby="' . $form->get_name() . '_' . $element['id'] . '_description' . '"';
}
$month .= ">\n";
$monthnames = explode(',', $form->i18n('element', 'date', 'monthnames', $element));
for ($i = 1; $i <= 12; $i++) {
$month .= "\t<option value=\"$i\"" . (($value == $i) ? ' selected="selected"' : '') . '>' . $monthnames[$i-1] . "</option>\n";
......@@ -67,7 +75,11 @@ function pieform_element_date(Pieform $form, $element) {/*{{{*/
$value = pieform_element_date_get_timeperiod_value('day', 1, 31, $element, $form);
$day = '<select name="' . $name . '_day" id="' . $name . '_day"'
. (!$required && !isset($element['defaultvalue']) ? ' disabled="disabled"' : '')
. ' tabindex="' . Pieform::hsc($element['tabindex']) . "\">\n";
. ' tabindex="' . Pieform::hsc($element['tabindex']) . '"';
if (isset($element['description'])) {
$day .= ' aria-describedby="' . $form->get_name() . '_' . $element['id'] . '_description' . '"';
}
$day .= ">\n";
for ($i = 1; $i <= 31; $i++) {
$day .= "\t<option value=\"$i\"" . (($value == $i) ? ' selected="selected"' : '') . ">$i</option>\n";
}
......@@ -78,7 +90,11 @@ function pieform_element_date(Pieform $form, $element) {/*{{{*/
$value = pieform_element_date_get_timeperiod_value('hour', 0, 23, $element, $form);
$hour = '<select name="' . $name . '_hour" id="' . $name . '_hour"'
. (!$required && !isset($element['defaultvalue']) ? ' disabled="disabled"' : '')
. ' tabindex="' . Pieform::hsc($element['tabindex']) . "\">\n";
. ' tabindex="' . Pieform::hsc($element['tabindex']) . '"';
if (isset($element['description'])) {
$hour .= ' aria-describedby="' . $form->get_name() . '_' . $element['id'] . '_description' . '"';
}
$hour .= ">\n";
for ($i = 0; $i <= 23; $i++) {
$hour .= "\t<option value=\"$i\"" . (($value == $i) ? ' selected="selected"' : '') . ">" . sprintf('%02d', $i) . "</option>\n";
}
......@@ -88,7 +104,11 @@ function pieform_element_date(Pieform $form, $element) {/*{{{*/
$value = pieform_element_date_get_timeperiod_value('minute', 0, 59, $element, $form);
$minute = '<select name="' . $name . '_minute" id="' . $name . '_minute"'
. (!$required && !isset($element['defaultvalue']) ? ' disabled="disabled"' : '')
. ' tabindex="' . Pieform::hsc($element['tabindex']) . "\">\n";
. ' tabindex="' . Pieform::hsc($element['tabindex']) . '"';
if (isset($element['description'])) {
$minute .= ' aria-describedby="' . $form->get_name() . '_' . $element['id'] . '_description' . '"';
}
$minute .= ">\n";
for ($i = 0; $i <= 59; $i++) {
$minute .= "\t<option value=\"$i\"" . (($value == $i) ? ' selected="selected"' : '') . ">" . sprintf('%02d', $i) . "</option>\n";
}
......@@ -125,7 +145,11 @@ EOF;
$optional .= ' ' . $form->i18n('element', 'date', 'or', $element) . ' <input type="checkbox" '
. (isset($element['defaultvalue']) ? '' : 'checked="checked" ')
. 'name="' . $name . '_optional" id="' . $name . '_optional" onchange="' . $name . '_toggle(this)" '
. 'tabindex="' . Pieform::hsc($element['tabindex']) . '">';
. 'tabindex="' . Pieform::hsc($element['tabindex']) . '"';
if (isset($element['description'])) {
$optional .= ' aria-describedby="' . $form->get_name() . '_' . $element['id'] . '_description' . '"';
}
$optional .= '>';
$optional .= ' <label for="' . $name . '_optional">' . $form->i18n('element', 'date', 'notspecified', $element);
$result .= $optional;
......
......@@ -69,10 +69,17 @@ function pieform_element_expiry(Pieform $form, $element) {/*{{{*/
$numberinput .= ($values['units'] == 'noenddate' && empty($element['rules']['required'])) ? ' disabled="disabled"' : '';
$numberinput .= ' type="text" size="4" name="' . $name . '"';
$numberinput .= ' id="' . $formname . '_' . $name . '" value="' . Pieform::hsc($values['number']) . '" tabindex="' . Pieform::hsc($element['tabindex']) . '"';
if (isset($element['description'])) {
$numberinput .= ' aria-describedby="' . $form->get_name() . '_' . $element['id'] . '_description' . '"';
}
$numberinput .= (isset($element['error']) ? ' class="error"' : '') . ">\n";
$uselect = '<select onchange="' . $name . '_change()" ';
$uselect .= 'name="' . $name . '_units" id="' . $formname . '_' . $name . '_units"' . ' tabindex="' . Pieform::hsc($element['tabindex']) . "\">\n";
$uselect .= 'name="' . $name . '_units" id="' . $formname . '_' . $name . '_units"' . ' tabindex="' . Pieform::hsc($element['tabindex']) . '"';
if (isset($element['description'])) {
$uselect .= ' aria-describedby="' . $form->get_name() . '_' . $element['id'] . '_description' . '"';
}
$uselect .= ">\n";
foreach (pieform_element_expire_get_expiry_units() as $u) {
// Don't allow 'no end date' if the element is required
if ($u == 'noenddate' && !empty($element['rules']['required'])) {
......
......@@ -56,8 +56,8 @@ function pieform_element_radio(Pieform $form, $element) {
$i = 0;
foreach ($element['options'] as $value => $data) {
$uid = $id . substr(md5(microtime()), 0, 4);
$element['id'] = $uid;
$idsuffix = substr(md5(microtime()), 0, 4);
$element['id'] = $uid = $id . $idsuffix;
if (is_array($data)) {
$text = $data['text'];
$description = (isset($data['description'])) ? $data['description'] : '';
......@@ -66,8 +66,10 @@ function pieform_element_radio(Pieform $form, $element) {
$text = $data;
$description = '';
}
$attributes = $form->element_attributes($element);
$attributes = preg_replace("/aria-describedby=\"([^\"]*){$idsuffix}_description\"/", 'aria-describedby="$1_description"', $attributes);
$result .= '<input type="radio"'
. $form->element_attributes($element)
. $attributes
. ' value="' . Pieform::hsc($value) . '"'
. (($form_value == $value) ? ' checked="checked"' : '')
. '>';
......
......@@ -91,6 +91,8 @@ function pieform_renderer_table(Pieform $form, $element) {/*{{{*/
// Description - optional description of the element, or other note that should be visible
// on the form itself (without the user having to hover over contextual help
if ((!$form->has_errors() || $form->get_property('showdescriptiononerror')) && !empty($element['description'])) {
$descriptionid = $form->get_name() . '_' . $element['id'] . '_description';
$result .= "\t<tr";
// Set the class of the enclosing <tr> to match that of the element
if (!empty($element['class'])) {
......@@ -98,10 +100,10 @@ function pieform_renderer_table(Pieform $form, $element) {/*{{{*/
}
$result .= ">\n\t\t";
if ($form->get_property('descriptionintwocells')) {
$result .= "<td></td><td class=\"description\">";
$result .= "<td></td><td class=\"description\" id=\"$descriptionid\">";
}
else {
$result .= "<td colspan=\"2\" class=\"description\">";
$result .= "<td colspan=\"2\" class=\"description\" id=\"$descriptionid\">";
}
$result .= $element['description'];
$result .= "</td>\n\t</tr>\n";
......
......@@ -2,7 +2,7 @@
{{foreach from=$validated item=email}}
<div class="validated">
<label>
<input disabled {{if $email == $default}} checked{{/if}} type="radio" name="{{$name}}_locked" value="{{$email}}">
<input disabled {{if $email == $default}} checked{{/if}}{{if $describedby}} aria-describedby="{{$describedby}}"{{/if}} type="radio" name="{{$name}}_locked" value="{{$email}}">
{{$email}}
</label>
</div>
......
......@@ -2,4 +2,4 @@
var tags_changed = false;
addLoadEvent(partial(augment_tags_control,'{{$id}}'))
</script>
<input type="text" size="{{$size}}" id="{{$id}}" name="{{$name}}" value="{{$value}}">
<input type="text" size="{{$size}}" id="{{$id}}" name="{{$name}}" value="{{$value}}" {{if $describedby}}aria-describedby="{{$describedby}}"{{/if}}>
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