SpreadJS 14
Getting Started / Accessibility Support
In This Topic
    Accessibility Support
    In This Topic

    SpreadJS provides adequate accessibility support for users with disabilities who utilize assistive technologies such as screen readers. As a result, developers using the application will be able to utilize the accessibility support to provide a hassle-free end-user experience to all customers.

    The text content on a web page can be accessed in the following ways:

    To make the text more meaningful while being read out by the screen readers, different texts are used for different cases as follows:

    Cases Texts read by the Screen Reader
    The Cell(0, 1) becomes an active cell by pressing the Tab key, and its value is "name". Cell(0, 1) has value "name"
    The Mouse enters the cell (0, 1) in the viewport area, and its value is "name". Cell(0, 1) has value "name"
    The Mouse enters the cell (0, 1) in the column header area, its value is "name". Column header Cell(0, 1) has value "name"
    The Mouse enters the cell(1, 0) in the row header area, its value is "name". Row header Cell(1, 0) has value "name"
    The mouse enters the resize bar of the tab strip. Resize
    The mouse enters the first area of the tab strip. First
    The Mouse enters the previous arrow area of the tab strip. Previous arrow
    The Mouse enters the next arrow area of the tab strip. Next arrow
    The mouse enters the last area of the tab strip. Last
    The mouse enters the previous button area of the tab strip. Previous button
    The mouse enters the next button area of the tab strip. Next button
    The mouse enters the sheet tab area of the tab strip, and its name is "Sheet1". Sheet tab "Sheet1"
    The mouse enters the new sheet area of the tab strip. New sheet
    The mouse enters the blank area of the tab strip. Blank
    The mouse enters the left button area of the horizontal scrollbar. Scrollbar left button
    The mouse enters the top button area of the vertical scrollbar. Scrollbar top button
    The mouse enters the thumb button area of the scrollbar. Scrollbar thumb button
    The mouse enters the right button area of the horizontal scrollbar. Scrollbar right button
    The Mouse enters the bottom button area of the vertical scrollbar. Scrollbar bottom button
    The sample page is in the active tab, and the active cell is Cell(0, 1), then its value is "name". Cell(0, 1) has value "name"

    The accessibility support can be used by customers to use with screen-reading applications like Windows Narrator, NVDA (NonVisual Desktop Access) for Windows, and VoiceOver for Mac OS X. Some of the features such as 'Pressing tab key', 'Mouse hover', and 'Page in active tab' function differently depending upon the type of screen readers and browsers used.

    The following table shows the real-time test results of screen readers with various internet browsers:

    Screen Reader Browser

    Pressing Tab key

    Mouse hover Page in active tab
    NVDA for Windows Chrome Supported Supported Supported
    NVDA for Windows Firefox Supported Supported Not supported
    NVDA for Windows Chromium Edge Supported Supported Not supported
    NVDA for Windows Edge Not supported Not supported Not supported
    NVDA for Windows IE Not supported Not supported Not supported
    Windows Narrator Chrome Supported Supported Not supported
    Windows Narrator Firefox Supported Supported Not supported
    Windows Narrator Chromium Edge Supported Supported Not supported
    Windows Narrator Edge Supported Not supported Not supported
    Windows Narrator IE Supported Not supported Not supported
    VoiceOver for OS X Chrome Supported with limitations Supported with limitations Not supported
    VoiceOver for OS X Safari Supported with limitations Supported with limitations Not supported
    Note: The VoiceOver reader for Mac OSX is supported in Chrome and Safari browsers with few limitations. The reader ignores the aria-label attribute when a div element has content. So for the first case that "Cell(0, 1) becomes the active cell by pressing the Tab key, its value is "name", and the VoiceOver reader can only recognize the cell text "name". Likewise, the VoiceOver reader for OSX doesn't recognize the dynamical aria-label attribute, so the Worksheet provides the whole viewport content when the mouse hovers over the canvas element or when the sample page is in the active tab. Furthermore, the VoiceOver reader for OSX doesn't recognize tab strip, scrollbar, and floating objects like pictures, charts, and shapes.

    Enabling Accessibility Support

    To enable the accessibility feature, the user needs to set the enableAccessibility property to True.

    This example code enables accessibility support:

    JavaScript
    Copy Code
    spread.options.enableAccessibility = true;
    

    Setting Custom Alternative text for Picture, Shapes, and Charts

    For graphic contents like floating objects, pictures, charts, and shapes, SpreadJS does not provide proper alternative texts. But users can provide alternative texts to use the text for accessibility support. For this, the Picture, FloatingObject, ConnectorShape, GroupShape, Shape and Chart classes have the alt method.

    This example code sets custom alternative texts for pictures, shapes and charts:

    JavaScript
    Copy Code
    <script>
            $(document).ready(function () {
                // initializing Spread
                var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'), { sheetCount: 2 });
                // Get the activesheet
                var sheet = spread.getSheet(0);
                //enable accessibility
                spread.options.enableAccessibility = true;
                spread.suspendPaint();
                //set focus
                spread.focus();
                //change the commands related to Tab key, Shift key with Tab key
                var commands = spread.commandManager();
                //TAB
                commands.register("moveToNextCellThenControl", GC.Spread.Sheets.Commands.moveToNextCellThenControl, GC.Spread.Commands.Key.tab, false, false, false, false);
                //SHIFT+TAB
                commands.register("moveToPreviousCellThenControl", GC.Spread.Sheets.Commands.moveToPreviousCellThenControl, GC.Spread.Commands.Key.tab, false, true, false, false);
                //set default row height and column width
                sheet.defaults.rowHeight = 50;
                sheet.defaults.colWidth = 150;
                //set default horizontal alignment and vertical alignment
                var defaultStyle = sheet.getDefaultStyle();
                defaultStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.center;
                defaultStyle.vAlign = GC.Spread.Sheets.VerticalAlign.center;
                defaultStyle.rowHeight = 50;
                defaultStyle.colWidth = 150;
                sheet.setDefaultStyle(defaultStyle);
                //bind data source
                sheet.setDataSource(dataSource);
                // get another sheet 1
                var sheet = spread.getSheet(1);
                //prepare data for chart
                sheet.setValue(0, 1, "Q1");
                sheet.setValue(0, 2, "Q2");
                sheet.setValue(0, 3, "Q3");
                sheet.setValue(1, 0, "Mobile Phones");
                sheet.setValue(2, 0, "Laptops");
                sheet.setValue(3, 0, "Tablets");
                for (var r = 1; r <= 3; r++) {
                    for (var c = 1; c <= 3; c++) {
                        sheet.setValue(r, c, parseInt(Math.random() * 100));
                    }
                }
                //add columnClustered chart
                var c1 = chart_columnClustered = sheet.charts.add('chart_columnClustered', GC.Spread.Sheets.Charts.ChartType.columnClustered, 50, 300, 300, 300, "A1:D4");
                c1.alt("This is a column chart");
                var chartArea = c1.chartArea();
                chartArea.border.color = "rgba(20, 119, 167, 1)";
                chartArea.border.width = 2;
                c1.chartArea(chartArea);
                // add mango picture
                var p1 = sheet.pictures.add("p1", "mango.jpg", 500, 50, 200, 200);
                p1.alt("This is a mango image");
                p1.borderColor("rgba(20, 119, 167, 1)");
                p1.borderWidth(2);
                p1.borderStyle("solid");
                // add cloud shape
                var sp1 = sheet.shapes.add("sp1", GC.Spread.Sheets.Shapes.AutoShapeType.cloud, 250, 50, 200, 200);
                sp1.alt("This is a cloud shape");
                spread.resumePaint();
                //bind events to set alternative text
                function setAltText(collection, altText) {
                    var success = false;
                    collection.forEach(function (obj) {
                        if (obj.isSelected()) {
                            obj.alt(altText);
                            success = true;
                        }
                    });
                    return success;
                }
                var alternativeText = document.getElementById("alternativeText");
                document.getElementById("setAlternativeText").addEventListener("click", function () {
                    var altText = alternativeText.value;
                    var success = setAltText(sheet.pictures.all(), altText);
                    if (success) {
                        return;
                    }
                    success = setAltText(sheet.charts.all(), altText);
                    if (success) {
                        return;
                    }
                    setAltText(sheet.shapes.all(), altText);
                });
                spread.bind(GC.Spread.Sheets.Events.PictureChanged, function (event, args) {
                    if (args.propertyName === "isSelected" && args.picture.isSelected()) {
                        alternativeText.value = args.picture.alt();
                    }
                });
                spread.bind(GC.Spread.Sheets.Events.FloatingObjectChanged, function (event, args) {
                    var floatingObject = args.floatingObject;
                    if (floatingObject && floatingObject instanceof GC.Spread.Sheets.Charts.Chart) {
                        if (args.propertyName === "isSelected" && floatingObject.isSelected()) {
                            alternativeText.value = floatingObject.alt();
                        }
                    }
                });
                spread.bind(GC.Spread.Sheets.Events.ShapeChanged, function (event, args) {
                    if (args.propertyName === "isSelected" && args.shape.isSelected()) {
                        alternativeText.value = args.shape.alt();
                    }
                });
            });
        </script>
    
    Note: After enabling the accessibility support, the visually-impaired people can conveniently access the data. However, UI operations such as drag fill, filter, touch, etc. triggered by mouse or touch are still difficult to use.