Meeting WCAG requirements for cardLayout 'buttons'

We are using a cardLayouts as a stack of buttons for actions the user must take before submitting the form.  The cardLayout has a label informing the user the type of action to perform and a status indicator to show the user visually whether the task is complete.  When you click the cardLayout, it displays a subpanel of information is displayed for the user to perform the needed task.

Ultimately, we may have 7 – 10 of these cardLayouts stacked on the page.  This design allows users to see only what they want to see when they want to see it.  It also, helps them know when all steps are completed.  We feel that this is a very appealing UI design.

 

We are facing a challenge meeting WCAG requirements for this design.  Specifically, Criterion 4.1.2 which requires the following:

4.1.2 Name, Role, Value: For all user interface components (including but not limited to: form elements, links and components generated by scripts), the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies. (Level A)

Taken from w3.org.

 

These cardLayouts essentially are like collapsible sectionLayouts but with a status indicator (and maybe other data we add as needed).  To meet WCAG 4.1.2, the cardLayout needs to include certain ARIA attributes to show that it owns/controls other page controls and indicate whether its current expanded/collapsed status.  A sectionLayout control has the aria-expanded attribute but does not use aria-owns or aria-controls.  The section layout, thus, does not fully meet WCAG 4.1.2.

 

The question is…. How can we add the appropriate aria tags into the page HTML for these cardLayouts so they meet the WCAG 4.1.2 standard for programmatic determination of states?  We need aria-controls to point to the container for the child controls (i.e. sectionLayout, columnsLayout, whatever) and aria-expanded to indicate the current shown/hidden state (like what a sectionLayout currently does).

 

 

a!localVariables(
  local!statuses: {
    a!map(
      name: "Not Started",
      icon: "circle-o-large",
      color: "#2B3A44"
    ),
    a!map(
      name: "Started",
      icon: "adjust",
      color: "#1931E3"
    ),
    a!map(
      name: "Completed",
      icon: "check-circle",
      color: "POSITIVE"
    )
  },
  local!currentSatus: "Not Started",
  local!showChild: false,
  {
    a!cardLayout(
      contents: a!sideBySideLayout(
        items: {
          a!sideBySideItem(
            item: a!richTextDisplayField(
              labelPosition: "COLLAPSED",
              value: {
                a!richTextItem(
                  text: "Step 1 label (w/ child controls)",
                  color: "#007958",
                  size: "MEDIUM",
                  style: { "STRONG" }
                )
              },
              align: "LEFT",
              marginAbove: "NONE",
              marginBelow: "NONE"
            )
          ),
          a!sideBySideItem(
            item: a!richTextDisplayField(
              labelPosition: "COLLAPSED",
              value: a!localVariables(
                local!statusIndex: wherecontains(
                  tostring(local!currentSatus),
                  local!statuses.name
                ),
                local!currentStatus: index(local!statuses, local!statusIndex),
                a!richTextIcon(
                  icon: index(local!currentStatus, "icon"),
                  caption: index(local!currentStatus, "name"),
                  color: index(local!currentStatus, "color"),
                  size: "MEDIUM"
                )
              ),
              align: "RIGHT",
              marginAbove: "NONE",
              marginBelow: "NONE"
            ),
            width: "MINIMIZE"
          )
        }
      ),
      link: a!dynamicLink(
        value: not(local!showChild),
        saveInto: local!showChild
      ),
      style: "STANDARD"
    ),
    a!columnsLayout(
      columns: {
        a!columnLayout(width: "EXTRA_NARROW"),
        a!columnLayout(
          contents: {
                a!richTextDisplayField(value: "Hello, World.  Here is where a bunch of controls will live.")
          }
        )
      },
      showWhen: local!showChild,
      marginAbove: "STANDARD"
    ),
    a!sectionLayout(),
    a!cardLayout(
      contents: a!sideBySideLayout(
        items: {
          a!sideBySideItem(
            item: a!richTextDisplayField(
              labelPosition: "COLLAPSED",
              value: {
                a!richTextItem(
                  text: "Step 2 label (no children, illustrative only)",
                  color: "#007958",
                  size: "MEDIUM",
                  style: { "STRONG" }
                )
              },
              align: "LEFT",
              marginAbove: "NONE",
              marginBelow: "NONE"
            )
          ),
          a!sideBySideItem(
            item: a!richTextDisplayField(
              labelPosition: "COLLAPSED",
              value: a!localVariables(
                local!statusIndex: wherecontains(
                  tostring(local!currentSatus),
                  local!statuses.name
                ),
                local!currentStatus: index(local!statuses, local!statusIndex),
                a!richTextIcon(
                  icon: index(local!statuses[2], "icon"),
                  caption: index(local!statuses[2], "name"),
                  color: index(local!statuses[2], "color"),
                  size: "MEDIUM"
                )
              ),
              align: "RIGHT",
              marginAbove: "NONE",
              marginBelow: "NONE"
            ),
            width: "MINIMIZE"
          )
        }
      ),
      style: "STANDARD"
    ),
    a!sectionLayout(),
    a!cardLayout(
      contents: a!sideBySideLayout(
        items: {
          a!sideBySideItem(
            item: a!richTextDisplayField(
              labelPosition: "COLLAPSED",
              value: {
                a!richTextItem(
                  text: "Step 3 label (no children, illustrative only)",
                  color: "#007958",
                  size: "MEDIUM",
                  style: { "STRONG" }
                )
              },
              align: "LEFT",
              marginAbove: "NONE",
              marginBelow: "NONE"
            )
          ),
          a!sideBySideItem(
            item: a!richTextDisplayField(
              labelPosition: "COLLAPSED",
              value: a!localVariables(
                local!statusIndex: wherecontains(
                  tostring(local!currentSatus),
                  local!statuses.name
                ),
                local!currentStatus: index(local!statuses, local!statusIndex),
                a!richTextIcon(
                  icon: index(local!statuses[3], "icon"),
                  caption: index(local!statuses[3], "name"),
                  color: index(local!statuses[3], "color"),
                  size: "MEDIUM"
                )
              ),
              align: "RIGHT",
              marginAbove: "NONE",
              marginBelow: "NONE"
            ),
            width: "MINIMIZE"
          )
        }
      ),
      style: "STANDARD"
    )
  }
)

  Discussion posts and replies are publicly visible

Parents
  • You can add aria-expanded attribute by simply adding angle-down and angle-right icons to your cardLayout  to indicate if a control is expanded or collapsed.

          

    a!localVariables(
      local!statuses: {
        a!map(
          name: "Not Started",
          icon: "circle-o-large",
          color: "#2B3A44"
        ),
        a!map(
          name: "Started",
          icon: "adjust",
          color: "#1931E3"
        ),
        a!map(
          name: "Completed",
          icon: "check-circle",
          color: "POSITIVE"
        )
      },
      local!isExpanded: false,
      local!currentSatus: "Not Started",
      local!showChild: false,
      {
        a!cardLayout(
          contents: a!sideBySideLayout(
            items: {
              a!sideBySideItem(
                item: a!richTextDisplayField(
                  labelPosition: "COLLAPSED",
                  value: a!richTextIcon(
                    icon: if(
                      local!isExpanded,
                      "angle-right",
                      "angle-down"
                    ),
                    size: "MEDIUM"
                  )
                ),
                width: "MINIMIZE"
              ),
              a!sideBySideItem(
                item: a!richTextDisplayField(
                  labelPosition: "COLLAPSED",
                  value: {
                    a!richTextItem(
                      text: "Step 1 label (w/ child controls)",
                      color: "#007958",
                      size: "MEDIUM",
                      style: { "STRONG" }
                    )
                  },
                  align: "LEFT",
                  marginAbove: "NONE",
                  marginBelow: "NONE"
                )
              ),
              a!sideBySideItem(
                item: a!richTextDisplayField(
                  labelPosition: "COLLAPSED",
                  value: a!localVariables(
                    local!statusIndex: wherecontains(
                      tostring(local!currentSatus),
                      local!statuses.name
                    ),
                    local!currentStatus: index(local!statuses, local!statusIndex),
                    a!richTextIcon(
                      icon: index(local!currentStatus, "icon"),
                      caption: index(local!currentStatus, "name"),
                      color: index(local!currentStatus, "color"),
                      size: "MEDIUM"
                    )
                  ),
                  align: "RIGHT",
                  marginAbove: "NONE",
                  marginBelow: "NONE"
                ),
                width: "MINIMIZE"
              )
            }
          ),
          link: a!dynamicLink(
            value: not(local!showChild),
            saveInto: {
              local!showChild,
              a!save(local!isExpanded, not(local!isExpanded))
            }
          ),
          style: "STANDARD"
        ),
        a!columnsLayout(
          columns: {
            a!columnLayout(width: "EXTRA_NARROW"),
            a!columnLayout(
              contents: {
                a!richTextDisplayField(
                  value: "Hello, World.  Here is where a bunch of controls will live."
                )
              }
            )
          },
          showWhen: local!showChild,
          marginAbove: "STANDARD"
        ),
        a!sectionLayout(),
        a!cardLayout(
          contents: a!sideBySideLayout(
            items: {
              a!sideBySideItem(
                item: a!richTextDisplayField(
                  labelPosition: "COLLAPSED",
                  value: {
                    a!richTextItem(
                      text: "Step 2 label (no children, illustrative only)",
                      color: "#007958",
                      size: "MEDIUM",
                      style: { "STRONG" }
                    )
                  },
                  align: "LEFT",
                  marginAbove: "NONE",
                  marginBelow: "NONE"
                )
              ),
              a!sideBySideItem(
                item: a!richTextDisplayField(
                  labelPosition: "COLLAPSED",
                  value: a!localVariables(
                    local!statusIndex: wherecontains(
                      tostring(local!currentSatus),
                      local!statuses.name
                    ),
                    local!currentStatus: index(local!statuses, local!statusIndex),
                    a!richTextIcon(
                      icon: index(local!statuses[2], "icon"),
                      caption: index(local!statuses[2], "name"),
                      color: index(local!statuses[2], "color"),
                      size: "MEDIUM"
                    )
                  ),
                  align: "RIGHT",
                  marginAbove: "NONE",
                  marginBelow: "NONE"
                ),
                width: "MINIMIZE"
              )
            }
          ),
          style: "STANDARD"
        ),
        a!sectionLayout(),
        a!cardLayout(
          contents: a!sideBySideLayout(
            items: {
              a!sideBySideItem(
                item: a!richTextDisplayField(
                  labelPosition: "COLLAPSED",
                  value: {
                    a!richTextItem(
                      text: "Step 3 label (no children, illustrative only)",
                      color: "#007958",
                      size: "MEDIUM",
                      style: { "STRONG" }
                    )
                  },
                  align: "LEFT",
                  marginAbove: "NONE",
                  marginBelow: "NONE"
                )
              ),
              a!sideBySideItem(
                item: a!richTextDisplayField(
                  labelPosition: "COLLAPSED",
                  value: a!localVariables(
                    local!statusIndex: wherecontains(
                      tostring(local!currentSatus),
                      local!statuses.name
                    ),
                    local!currentStatus: index(local!statuses, local!statusIndex),
                    a!richTextIcon(
                      icon: index(local!statuses[3], "icon"),
                      caption: index(local!statuses[3], "name"),
                      color: index(local!statuses[3], "color"),
                      size: "MEDIUM"
                    )
                  ),
                  align: "RIGHT",
                  marginAbove: "NONE",
                  marginBelow: "NONE"
                ),
                width: "MINIMIZE"
              )
            }
          ),
          style: "STANDARD"
        )
      }
    )

  • I can try that, but it will only be half the solution.

    How do you get aria-owns/aria-controls added?  aria-expanded by itself does not fully meet the WCAG standard (this is the problem the sectionLayout has.... it has aria-expanded but does not indicate aria-owns/aria-controls).

  • 0
    Certified Lead Developer
    in reply to stevenh6272

    I suggest to contact Appian for any details. We, as Appian developers, only have the options provided by the components.

  • I figured that would be the recommendation.

    Thanks.

Reply Children
No Data