Vue-form-generator: Better accessibility

Created on 22 Sep 2016  路  10Comments  路  Source: vue-generators/vue-form-generator

Let's not forget about this, the web is for everybody.
I don't have experience with this, it could be nice to have someone who know about these stuff on board to help.
We could start with labels.

Documentation and information:

enhancement help wanted

Most helpful comment

I have experience in this area and have started work on this. As I'm fairly new to Vue, I wanted to validate my approach before I go to much further. I started with labels:

Labels

Associate with Control

To make labels accessible, you need to associate them with 'their' control. The best way to do this is to use a for attribute on the label, along with an id attribute on the control, like this:

<label for="first-name">First Name</label>
<input id="first-name" ... />

This means that we need an id on every input - which is a good idea for lots of reasons. My approach to solving this was to add a getFieldID function to abstractField.js:

getFieldID(schema) {
  if (typeof schema.id !== 'undefined') {
    // If an ID's been explicitly set, use it unchanged
    return schema.id
  } else {
    // Try to get a reasonable default id from the schema, then slugify it.
    return (schema.inputName || schema.label || schema.model)
      .toString()
      .trim()
      .toLowerCase()
      // Spaces to dashes
      .replace(/ /g, '-')
      // Multiple dashes to one
      .replace(/-{2,}/g, '-')
      // Remove leading & trailing dashes
      .replace(/^-+|-+$/g, '')
      // Remove anything that isn't a (English/ASCII) letter or number.
      .replace(/([^a-zA-Z0-9\._-]+)/g, '')
    ;
  }
}

This can then be used in every field*.vue component to set an id - for example, in fieldInput.vue:

<template lang="jade">
.wrapper
  input.form-control(
    :id="getFieldID(schema)",
    :type="schema.inputType",
    ...

Then, in formGenerator.vue, output the for attribute in the appropriate place:

label(v-if="fieldTypeHasLabel(field)", :for="getFieldID(field)")
  | {{ field.label }}

Don't output labels for buttons

I also noticed that labels were being output for buttons, which isn't the correct thing to do. I added a fieldTypeHasLabel function to formGenerator.vue (referenced in the above template):

fieldTypeHasLabel(field) {
  switch (field.type) {
    case 'button':
    case 'submit':
      return false;
    default:
      return true;
  }
},

This is all working fine for me locally, using the test/dev app. I'll push a fork/branch tomorrow and link it here - but in the meantime - does this sound like the correct way to go about these changes - and should I carry on?

All 10 comments

Good idea.

I have experience in this area and have started work on this. As I'm fairly new to Vue, I wanted to validate my approach before I go to much further. I started with labels:

Labels

Associate with Control

To make labels accessible, you need to associate them with 'their' control. The best way to do this is to use a for attribute on the label, along with an id attribute on the control, like this:

<label for="first-name">First Name</label>
<input id="first-name" ... />

This means that we need an id on every input - which is a good idea for lots of reasons. My approach to solving this was to add a getFieldID function to abstractField.js:

getFieldID(schema) {
  if (typeof schema.id !== 'undefined') {
    // If an ID's been explicitly set, use it unchanged
    return schema.id
  } else {
    // Try to get a reasonable default id from the schema, then slugify it.
    return (schema.inputName || schema.label || schema.model)
      .toString()
      .trim()
      .toLowerCase()
      // Spaces to dashes
      .replace(/ /g, '-')
      // Multiple dashes to one
      .replace(/-{2,}/g, '-')
      // Remove leading & trailing dashes
      .replace(/^-+|-+$/g, '')
      // Remove anything that isn't a (English/ASCII) letter or number.
      .replace(/([^a-zA-Z0-9\._-]+)/g, '')
    ;
  }
}

This can then be used in every field*.vue component to set an id - for example, in fieldInput.vue:

<template lang="jade">
.wrapper
  input.form-control(
    :id="getFieldID(schema)",
    :type="schema.inputType",
    ...

Then, in formGenerator.vue, output the for attribute in the appropriate place:

label(v-if="fieldTypeHasLabel(field)", :for="getFieldID(field)")
  | {{ field.label }}

Don't output labels for buttons

I also noticed that labels were being output for buttons, which isn't the correct thing to do. I added a fieldTypeHasLabel function to formGenerator.vue (referenced in the above template):

fieldTypeHasLabel(field) {
  switch (field.type) {
    case 'button':
    case 'submit':
      return false;
    default:
      return true;
  }
},

This is all working fine for me locally, using the test/dev app. I'll push a fork/branch tomorrow and link it here - but in the meantime - does this sound like the correct way to go about these changes - and should I carry on?

You could simplify this by setting the input's id to the same value as it's name - this is very common when creating forms manually.

But I think you'd want to add a form-level prefix to the inputs id - they need to be unique in the DOM, so you'd have potential for collisions if you had two forms in the DOM at the same time. (This isn't currently implemented, but would probably be a good idea).

You could leave this all to the user - and make them fill in a schema.id property, but I'd rather that things just worked, without lots of extra config required.

@dflock Thanks your suggestion. I think it is good way. Please make a PR and I will test it.

What is the status on this? @dflock ?

_Just_ about freed myself up to start working on this again. Hope to have an updated version of #105 pushed by this evening.

After that, I want to work on sorting out the current <fieldset> and <legend> issues, as part of this accessibility thread.

Closed by #201

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Atiladanvi picture Atiladanvi  路  4Comments

ndro picture ndro  路  4Comments

DelfsEngineering picture DelfsEngineering  路  4Comments

reardestani picture reardestani  路  5Comments

afourmeaux picture afourmeaux  路  4Comments