Skip to main content Skip to footer

How to Add Accessibility Support to your JavaScript Spreadsheet Applications

Quick Start Guide
What You Will Need SpreadJS, Visual Studio Code
Controls Referenced

SpreadJS – JavaScript Spreadsheet Component

Documentation | Demos

Tutorial Concept JavaScript Accessibility Support - Adding features to make your web application compliant with accessibility standards. This tutorial will use SpreadJS to make a JavaScript spreadsheet application.

Accessibility and Section 503 Compliance in apps are a requirement for many different companies, so it is important to make sure your application has accessibility options in it. With SpreadJS, a JavaScript spreadsheet, you can set different accessibility options to help make your applications compliant when presenting data within the spreadsheet. This blog will go over the different accessibility options that you can set in the spreadsheet and what they do.

  • Screen Readers
  • Accessibility Support
  • Alternative Text

If needed, you can download a 30-day fully functional trial here to follow along with this blog.

Screen Readers

SpreadJS supports screen readers:

  • NVDA for Windows
  • VoiceOver for Mac

These screen readers work with different types of cells in SpreadJS in addition to basic text and number cells. These cells include:

  • Buttons - Reads as “Cell (cell reference, i.e. A1) has button (button name)”
  • Checkboxes - Reads as “Cell (cell reference, i.e. A1) has checkbox (checkbox name)”
  • Links - Reads as “Cell (cell reference, i.e. A1) has hyperlink (hyperlink name)”

Accessibility Support

To get started with adding accessibility, the option must be set to true:

var spread = GC.Spread.Sheets.findControl(document.getElementById('ss'));
spread.options.enableAccessibility = true;

This can also be enabled in the SpreadJS Designer using the Settings>General window:

Accessibility Support

Accessibility Support

It should be noted that enabling this option does not affect the performance of SpreadJS.

In addition to traditional spreadsheet navigation, you can also interact with the context menus of headers as well, such as a filter on the column. This can be done through a keyboard shortcut with the following code:

var spread = new GC.Spread.Sheets.Workbook("ss", { sheetCount: 3 });
var sheet = spread.getActiveSheet();
spread.commandManager().register('openColumnContextMenu', function (workbook, options) {
    var host = workbook.getHost(), sheet = spread.getActiveSheet();
    var activeColIndex = sheet.getActiveColumnIndex();
    var colHeaderRect = sheet.getCellRect(0, activeColIndex, -1);
    var pointerEvent = new PointerEvent("contextmenu", {
        bubbles: true,
        cancelable: true,
        view: window,
        clientX: colHeaderRect.x + colHeaderRect.width / 2 + host.offsetLeft,
        clientY: colHeaderRect.y + colHeaderRect.height / 2 + host.offsetTop,
        button: 2
    });
    host.dispatchEvent(pointerEvent);
}, 49, true, true, false, false);//ctrl+shift+1

Alternative Text

SpreadJS supports using alternative text for cells. This is descriptive text that helps users with disabilities and those who are using screen readers to interact with cells. If the alt text is set for a cell, the screen reader will read the alt text out loud. Alt text supports plain text in addition to placeholders, such as “{value}” for cell values and {formatted} for formatted cell values.

Alt text can be set, viewed, copied, moved, and modified, and they are supported in serialization and deserialization for .SSJSON or .SJS file formats. There are a few different ways that you can set alt text:

// Set and get the alternative text value with the cell value using setAltText and getAltText methods.
activeSheet.setAltText(0, 0, "Set alternative text for the cell ");
console.log(activeSheet.getAltText(0, 0));
  • altText method of the CellRange class:
// Set and get the alternative text value of a cell using altText method.
activeSheet.getCell(0, 0).altText("Set alternative text for the cell");
var B1= activeSheet.getCell(1, 1).value(1000);
B1.altText("Alt Text is the cell value: " + activeSheet.getCell(1, 1).value());
console.log(activeSheet.getCell(0, 0).altText());
console.log(activeSheet.getCell(1, 1).altText());

activeSheet.setValue(0, 3, new Date(2013, 3, 1));
activeSheet.getCell(0, 3).formatter('d-mmm;@');
console.log("Cell formatter of cell[0,3] is :" + activeSheet.getCell(0, 3).formatter());
console.log("Formatted value of cell[0,3] is :" + activeSheet.getCell(0, 3).value());
  • altText option of the StorageType enumeration:
// Use StorageType enumeration to get the alternative text value of cell.
activeSheet.getCell(0, 0).altText("Alternative text for the cell ");
activeSheet.clear(0, 0, 3, 3, GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.altText);
  • altText option of the CopyToOptions enumeration:
//Use CopyToOption enumeration to copy the alternative text value of cell.
activeSheet.getCell(0, 0).altText("Alternative text for the cell ");
activeSheet.copyTo(0, 0, 1, 1, 2, 2, GC.Spread.Sheets.CopyToOptions.altText);

You can also set altText using the UI by right-clicking on a cell:

Alternative Text

The altText feature also allows you to create custom alternative text for cells, which is especially useful for custom fonts and icons within a cell. You can manually control what the screen reader will read aloud for specific cells.

In addition to cells, you can set custom alternative text for pictures, shapes, and charts. This can be done just using the “alt” method for the following classes:

  • Picture
  • FloatingObject
  • ConnectorShape
  • GroupShape
  • Shape
  • Chart

This can be done with the following code:

$(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();
        }
    });
});

These are just a few of the accessibility options that are available in SpreadJS. We are continuously working with customers and adding more accessibility features to ensure apps are compliant. If you have any accessibility requirements you’d like to see implemented, don’t hesitate to reach out to our support team here!

Ready to Check it Out? Download a 30-day Free Trial of SpreadJS Today!

Tags:

comments powered by Disqus