gyrocode/jquery-datatables-checkboxes

Accesibility issues

Lb-lea opened this issue · 2 comments

Hello,
I am having trouble with using the generated checkboxes when using a screen reader to navigate
since the checkboxes are rendered without labels or any aria what so ever:
<input type="checkbox" class="dt-checkboxes">
It is really hard to know what am I checking.
Maybe this could be improved by giving more information in the generated checkboxes attributes.

I have an idea that could help although I have no idea how to implement it.
First giving a name to the column, like it can be empty but I could also want to call it "select someone" : that way we can link the name of the column with the line Id.
Then we could generate something like:

<td class=" dt-checkboxes-cell">
   <label for="lineID" class="sr-only"> lineID</label>
   <input name="lineID" type="checkbox" class="dt-checkboxes"  aria-checked="false">
</td>

Thus upon selecting the checkbox the screen reader would say stuff stuff like "selected line one" if "line one" is my ID or selected "Airi Satou" if my table uses people names as ID....something like that.

or:

<td class=" dt-checkboxes-cell">
   <input type="checkbox" class="dt-checkboxes"    aria-labelledby="lineID ColumnName">
</td>

Anyway, I'm still lacking a lot so this idea might not be of much help.
Here there are some example of best practises for checkboxes (althought these need to be fitted in the table context) : https://www.w3.org/TR/2016/WD-wai-aria-practices-1.1-20160317/examples/checkbox/checkbox-2.html

notes:
sr-only is the class used by Bootstrap to hide info so that it is only "visible" to non sighted users.
aria-checked="false" helps knowing what is checked

Thank you for your hard work

Thanks for bringing this up and detailed explanation. Let me review it and think about possible solutions.

Actually we need to render a blank column to make space to the checkbox. Probably a good workaround will be instead of do not pass any data just set the row id in that position and fill the check control name with that data. So:

<tr>
    <th>checkbox_name</th>//Note this is overrided by the plugin
    <th>First visible data</th>
</tr>
<tr>
     <td>checkbox_row_id_1</td>
     <td>data_1</td>
</tr>
<tr>
     <td>checkbox_row_id_2</td>
     <td>data_2</td>
</tr>

This can produce:

<input type="checkbox" class="dt-checkboxes"  name="checkbox_name[]" value="checkbox_row_id_1" aria-labelledby="checkbox_row_id_1 checkbox_name">
<input type="checkbox" class="dt-checkboxes"  name="checkbox_name[]" value="checkbox_row_id_2" aria-labelledby="checkbox_row_id_2 checkbox_name">

And finally this is how my settings is to make that possible:

options["columnDefs"].push({ 
    'targets': 0,
    'checkboxes': { 'selectRow': true, 'selectAllRender': function() {
        return '<input type="checkbox" class="dt-checked-main">';
    }},
    'render': function (data, type, row, meta) {
        var idx = meta.row;
        var api = new $.fn.dataTable.Api(meta.settings);
        var title = api.column(meta.col).header();
        if (!$(title).data("name")) { //workaround to not lost the header name.
            $(title).data("name", $(title).html());
        }
        var columnName = $(title).data("name");
        var lineID = $('<div/>').text(data).html();
        return '<input type="checkbox" class="dt-checkboxes" name="'+columnName+'[]" value="'+lineID+'" aria-labelledby="'+lineID+ ' ' +columnName+'">';
    }
});

I hope this help.