vue-generators / vue-form-generator

:clipboard: A schema-based form generator component for Vue.js
MIT License
2.99k stars 531 forks source link

Better accessibility #74

Closed lionel-bijaoui closed 7 years ago

lionel-bijaoui commented 8 years ago

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:

icebob commented 8 years ago

Good idea.

icebob commented 7 years ago

Some tool: https://github.com/addyosmani/a11y/

dflock commented 7 years ago

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?

dflock commented 7 years ago

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.

icebob commented 7 years ago

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

jmverges commented 7 years ago

What is the status on this? @dflock ?

dflock commented 7 years ago

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

dflock commented 7 years ago

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

lionel-bijaoui commented 7 years ago

Some resources : http://inclusive-components.club/toggle-button/

icebob commented 7 years ago

Closed by #201