如何在将焦点移动到错误的字段时允许屏幕阅读器宣布ASP.NET MVC 5表单验证消息?

Gre*_*rdt 5 html asp.net-mvc razor jaws-screen-reader web-accessibility

我们有一个ASP.NET MVC 5 Web应用程序.我们使用JAWS与Internet Explorer 11(企业授权)和Chrome进行定期可访问性测试.当用户选择进入字段时,我们一直遇到JAWS无法读取与表单字段关联的验证消息的问题.我们使用FluentValidation和标准HTML帮助程序来显示表单字段和验证消息(如下所示):

@Html.LabelFor(model => model.Email)
@Html.EditorFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email, null, new { role = "alert" })
Run Code Online (Sandbox Code Playgroud)

示例FluentValidation可能会在数据库中查询表单中的电子邮件地址,并在服务器端显示"已收到此电子邮件"的消息.

生成的HTML发送回浏览器是:

<label for="Email">E-mail address:</label>

<input type="text" name="Email" id="Email" ...>

<span class="..." data-valmsg-for="Email" data-valmsg-replace="true" role="alert">
    This e-mail has already been taken
</span>
Run Code Online (Sandbox Code Playgroud)

没有任何内容将验证消息与表单字段相关联.我一直认为MVC框架自动建立了这种连接,但显然它没有.

根据WebAIM,我们应该利用该aria-describedby属性将表单字段与内联验证错误相关联,但是要重新使用现有的MVC5框架来完成这项任务是非常重要的.

当将焦点转移到ASP.NET MVC5生成的表单字段而不重写主要HTML帮助程序时,我们如何让屏幕阅读器宣布内联验证消息?

小智 6

无需创建自定义HtmlHelper扩展方法来aria-describedby在for控件中生成属性,而id在error元素中创建关联的属性,则需要使用javascript来添加它们。

请注意,每个错误消息占位符(由生成@Html.ValidationMessageFor())都通过data-valmsg-for="...."属性与其表单控件相关联。

假设您要aria-describedby为所有表单控件都包含一个相关的错误消息(并包含在一个<form>元素中),因此,如果通过来添加客户端错误jquery.validate.js,则可以使用它,那么脚本(jQuery)将是

$(function () {
    // Get the form controls
    var controls = $('form').find('input, textarea, select')
        .not(':hidden, :input[type=submit], :input[type=button], :input[type=reset]');
    $.each(controls, function (index, item) {
        // Get the name of the form control
        var name = $(this).attr('name'); 
        if (!name) {
            return true;
        }
        // Get the associated error element
        var errorElement = $('[data-valmsg-for="' + name + '"]');
        if (!errorElement) {
            return true;
        }
        // Generate an id attribute based on the name of the control
        var errorId = name + "-error"
        // Add attributes to the input and the error element
        $(this).attr('aria-describedby', errorId)
        errorElement.attr('id', errorId);
    });
});
Run Code Online (Sandbox Code Playgroud)

如果您对客户端验证错误不感兴趣,则可以将其var controls = $('.input-validation-error');用作选择器,以仅获取已添加服务器端验证错误的表单控件。

我建议将此脚本包含在一个外部(例如)screenreadervalidation.js文件中,并将其包含在您的文件包jqueryjqueryval捆绑文件中,以便将其包含在所有视图中,这些视图包括用于创建或编辑数据的表单。