Skip to content

Commit

Permalink
Improve labels for better accessibility:
Browse files Browse the repository at this point in the history
* Associate each label with it's control, by making sure that each
  control has an id, and using the labels `for` attribute to bind
  to this.
* Don't output label elements for button controls
  • Loading branch information
Duncan Lock committed Jan 14, 2017
1 parent 454fa0e commit 0e2c41c
Show file tree
Hide file tree
Showing 6 changed files with 6,994 additions and 32 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"scripts": {
"prebuild": "npm run test",
"build": "webpack --progress --config webpack.build.config.js",
"dev": "webpack-dev-server --config webpack.dev.config.js --inline --hot --content-base dev/",
"dev": "webpack-dev-server --config webpack.dev.config.js --inline --hot --content-base dev/ --port 8082",
"lint": "eslint --ext=.js,.vue src test/unit/specs",
"coverall": "cat ./test/unit/coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
"coverage": "npm run test && npm run coverall",
Expand Down
23 changes: 23 additions & 0 deletions src/fields/abstractField.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,29 @@ export default {
this.$set(this.schema, "errors", []); // Be reactive
else
this.schema.errors.splice(0); // Clear
},

getFieldID(schema) {
// Try to get a reasonable default id from the schema,
// then slugify it.
if (typeof schema.id !== 'undefined') {
// If an ID's been explicitly set, use it unchanged
return schema.id
} else {
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, '')
;
}
}
}
};
7 changes: 4 additions & 3 deletions src/fields/fieldInput.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<template lang="jade">
.wrapper
input.form-control(
:type="schema.inputType",
:id="getFieldID(schema)",
:type="schema.inputType",
:value="value",
@input="value = $event.target.value",
number="schema.inputType == 'number'"
Expand Down Expand Up @@ -62,12 +63,12 @@
return new Date(value).getTime();
}
}
return value;
}
}
};
</script>

<style lang="sass">
Expand Down
13 changes: 11 additions & 2 deletions src/fields/fieldTextArea.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
<template lang="jade">
textarea.form-control(v-model="value", :disabled="disabled", :maxlength="schema.max", :minlength="schema.min", :placeholder="schema.placeholder", :readonly="schema.readonly", :rows="schema.rows || 2", :name="schema.inputName")
textarea.form-control(
v-model="value",
:id="getFieldID(schema)",
:disabled="disabled",
:maxlength="schema.max",
:minlength="schema.min",
:placeholder="schema.placeholder",
:readonly="schema.readonly",
:rows="schema.rows || 2",
:name="schema.inputName")
</template>

<script>
Expand All @@ -8,7 +17,7 @@
export default {
mixins: [ abstractField ]
};
</script>


Expand Down
66 changes: 40 additions & 26 deletions src/formGenerator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ div
fieldset.vue-form-generator(v-if='schema != null')
template(v-for='field in fields')
.form-group(v-if='fieldVisible(field)', :class='getFieldRowClasses(field)')
label
label(v-if="fieldTypeHasLabel(field)", :for="getFieldID(field)")
| {{ field.label }}
span.help(v-if='field.help')
i.icon
Expand All @@ -20,6 +20,7 @@ div
<script>
// import Vue from "vue";
import {each, isFunction, isNil, isArray, isString} from "lodash";
import getFieldID from "./fields/abstractField";
// Load all fields from '../fields' folder
let Fields = require.context("./fields/", false, /^\.\/field([\w-_]+)\.vue$/);
Expand All @@ -32,7 +33,9 @@ div
export default {
components: fieldComponents,
mixins: [ getFieldID ],
props: {
schema: Object,
Expand All @@ -58,7 +61,7 @@ div
default: false
}
},
data () {
return {
errors: [] // Validation errors
Expand Down Expand Up @@ -111,15 +114,15 @@ div
}
});
},
methods: {
// Get style classes of field
getFieldRowClasses(field) {
let baseClasses = {
error: field.errors && field.errors.length > 0,
disabled: this.fieldDisabled(field),
readonly: field.readonly,
featured: field.featured,
error: field.errors && field.errors.length > 0,
disabled: this.fieldDisabled(field),
readonly: field.readonly,
featured: field.featured,
required: field.required
};
Expand All @@ -140,6 +143,17 @@ div
return "field-" + fieldSchema.type;
},
// Should field type have a label?
fieldTypeHasLabel(field) {
switch (field.type) {
case 'button':
case 'submit':
return false;
default:
return true;
}
},
// Get disabled attr of field
fieldDisabled(field) {
if (isFunction(field.disabled))
Expand All @@ -160,7 +174,7 @@ div
return true;
return field.visible;
},
},
// Validating the model properties
validate() {
Expand Down Expand Up @@ -190,7 +204,7 @@ div
each(this.$children, (child) => {
child.clearValidationErrors();
});
});
},
modelUpdated(newVal, schema){
// console.log("a child model has updated", newVal, schema);
Expand All @@ -205,19 +219,19 @@ div
}
}
};
</script>

<style lang="sass">
$errorColor: #F00;
fieldset.vue-form-generator {
* {
box-sizing: border-box;
}
}
.form-control {
// Default Bootstrap .form-control style
display: block;
Expand All @@ -231,10 +245,10 @@ div
border: 1px solid #ccc;
border-radius: 4px;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
} // .form-control
span.help {
margin-left: 0.3em;
position: relative;
Expand Down Expand Up @@ -283,13 +297,13 @@ div
left: 0;
position: absolute;
width: 100%;
}
}
&:hover .helpText {
opacity: 1;
pointer-events: auto;
transform: translateY(0px);
}
}
} // span.help
Expand All @@ -301,11 +315,11 @@ div
margin-left: 4px;
}
button, input[type=submit] {
button, input[type=submit] {
// Default Bootstrap button style
display: inline-block;
padding: 6px 12px;
margin: 0px;
margin: 0px;
font-size: 14px;
font-weight: normal;
line-height: 1.42857143;
Expand Down Expand Up @@ -340,7 +354,7 @@ div
} // button, input[submit]
} // .field-wrap
} // .field-wrap
.hint {
font-style: italic;
Expand All @@ -362,7 +376,7 @@ div
&.featured {
label {
font-weight: bold;
}
}
}
&.required {
Expand All @@ -373,14 +387,14 @@ div
position: absolute;
padding-left: 0.2em;
font-size: 1em;
}
}
}
&.disabled {
label {
color: #666;
font-style: italic;
}
}
}
&.error {
Expand All @@ -403,11 +417,11 @@ div
font-weight: 600;
}
} // .errors
} // .errors
} // .error
} // .form-group
} // fieldset
</style>
</style>
Loading

0 comments on commit 0e2c41c

Please sign in to comment.