3

Is there a way to customize the validationSummary so that it can output anchor tags who's HREF is the name of the field that the validation message in teh summary is displaying for? This way, using jquery, i can add onclick events that focus the field when the anchor tag is clicked on the validation summary.

This is primarely for visually impaired people, so that when they have errors, the validation summary focuses, they tab to an error entry, the anchor tag with the field label focuses and the screen reader reads the anchor then the message, then they can click on the anchor to focus on the erroneous field.

<a href="#First_Name">First Name</a> - Please enter your first name.

Thanks.

user648490
  • 41
  • 3

1 Answers1

5

I don't think that there is any functionality within the framework for this so you would need to use a custom extension method. For example:

    public static string AccessibleValidationSummary(this HtmlHelper htmlHelper, string message, IDictionary<string, object> htmlAttributes)
    {
        // Nothing to do if there aren't any errors
        if (htmlHelper.ViewData.ModelState.IsValid)
        {
            return null;
        }

        string messageSpan;
        if (!String.IsNullOrEmpty(message))
        {
            TagBuilder spanTag = new TagBuilder("span");
            spanTag.MergeAttributes(htmlAttributes);
            spanTag.MergeAttribute("class", HtmlHelper.ValidationSummaryCssClassName);
            spanTag.SetInnerText(message);
            messageSpan = spanTag.ToString(TagRenderMode.Normal) + Environment.NewLine;
        }
        else
        {
            messageSpan = null;
        }

        StringBuilder htmlSummary = new StringBuilder();
        TagBuilder unorderedList = new TagBuilder("ul");
        unorderedList.MergeAttributes(htmlAttributes);
        unorderedList.MergeAttribute("class", HtmlHelper.ValidationSummaryCssClassName);

        foreach (string key in htmlHelper.ViewData.ModelState.Keys)
        {
            ModelState modelState = htmlHelper.ViewData.ModelState[key];
            foreach (ModelError modelError in modelState.Errors)
            {
                string errorText = htmlHelper.ValidationMessage(key);
                if (!String.IsNullOrEmpty(errorText))
                {
                    TagBuilder listItem = new TagBuilder("li");

                    TagBuilder aTag = new TagBuilder("a");
                    aTag.Attributes.Add("href", "#" + key);
                    aTag.InnerHtml = errorText;
                    listItem.InnerHtml = aTag.ToString(TagRenderMode.Normal);
                    htmlSummary.AppendLine(listItem.ToString(TagRenderMode.Normal));
                }
            }
        }

        unorderedList.InnerHtml = htmlSummary.ToString();

        return messageSpan + unorderedList.ToString(TagRenderMode.Normal);
    }

This is using the existing extension method from within the framework and changing the tag that is inserted into the list. This is a quick sample and there are some things to consider before using this:

  • This does not encode the error message as I have used the existing html.ValidationMessage. If you need to encode the message then you would need to include so code to provide default messages and any localization requirements.
  • Due to the use of the existing ValidationMessage method there is a span tag within the anchor. If you want to tidy your HTML then this should be replaced.
  • This is the most complicated of the usual overloads. If you want to use some of the simpler ones such as html.ValidationSummary() then you would need to create the relevant signatures and call to the method provided.
detaylor
  • 7,112
  • 1
  • 27
  • 46