inputsDeferToFieldsets allows the developer to define specific inputs which should ignore the default error message placement immediately prior to the input, instead deferring the error placement to the parent fieldset (and placing the error message after the legend). This is specified by passing an array of input IDs when initialising VV.
inputsDeferToFieldsets additionally labels the message in the error summary with the legend, rather than the input's individual label.
The problem
- A developer doesn't necessarily know what IDs are needed—such as if these IDs are generated by a CMS.
- Having to configure by input ID doesn't practically support components that can be used multiple times on the same page.
- A developer doesn't necessarily want the error message's placement to be moved all the way up to the fieldset. They may just want it to not be immediately prior to the input (e.g. if select element styling adds a new wrapping element and the developer wants it to appear outside of that wrapping element).
Potential resolutions
Provide more ways to specify inputs
It would seem pertinent to copy the CSS-style selector syntax used by querySelector, querySelectorAll, et al. rather than limiting a developer to only using IDs.
Provide more ways to specify placement
Inline error placement is currently limited to either being immediately before the input element with the error (the default) or to be immediately after the legend element of the parent fieldset (if inputsDeferToFieldsets specifies it). This, in my opinion at least, provides a sensible default and a reading order that is best optimised for users of assistive technologies. However, it creates problems when the demands of styling or other frameworks cannot accommodate error messages in these locations.
The proposed rectification is twofold: To provide a "basic" way of defining the inline error placement via a keyword; and to provide an "advanced" option to give developers granular control over placement.
The "basic" keyword method could include options such as:
before — Inserts the error before the input. This is the current default functionality.
after — Inserts the error after the input.
beforeParent — Inserts the error before the input's parent element.
afterParent — Inserts the error after the input's parent element.
fieldsetStart — Inserts the error at the start of the input's parent fieldset (after the legend). This is the current inputsDeferToFieldsets functionality.
fieldsetEnd — Inserts the error at the end of the input's parent fieldset.
To preserve the labelling change that inputsDeferToFieldsets performs, this should also be included as a flag.
Example usage:
new Validate(form, {
overrideInlineErrorPlacement: [
{
selector: ".date-of-birth input",
placement: "fieldsetStart",
useLegendAsLabel: true
}
]
});
There are some implementation pain points around the this. The current ID limitation exists because that is a "known" piece of information in the context the check is being made in. Whether a specific input matches a given query string is a totally different kettle of fish, and may require an excessive number of DOM queries to achieve (number of inputs being checked × number of overrides defined).
The "advanced" method I imagine would allow the developer to provide a function that is ran to determine placement:
Example usage:
new Validate(form, {
overrideInlineErrorPlacement: [
{
selector: ".date-of-birth input",
placement: function(inputElement, errorElement) {
inputElement.closest(".date-of-birth").querySelector(".error").innerHTML = errorElement;
}
}
]
});
If we are providing this sort of granular placement then it would make sense to provide a global setting for it. For example, allowing the developer to always have error messages be placed below an input unless otherwise overridden.
Example usage:
new Validate(form, {
inlineErrorPlacement: "after"
});
It would also make sense to provide a limited some options for the error summary, although there isn't really anywhere it makes sense to display this except for at the start of the form/near the top of the page content.
Example usage:
new Validate(form, {
errorSummaryPlacement: "start"
});
Backwards compatibility
For backwards compatibility with previous VV versions, I would propose keeping the inputsDeferToFieldsets parameter and format identical to how it currently is, instead mapping its functions to the new functionality which is provided under new parameter names (e.g. inlineErrorPlacement and overrideInlineErrorPlacement).
inputsDeferToFieldsetsallows the developer to define specific inputs which should ignore the default error message placement immediately prior to the input, instead deferring the error placement to the parent fieldset (and placing the error message after the legend). This is specified by passing an array of input IDs when initialising VV.inputsDeferToFieldsetsadditionally labels the message in the error summary with the legend, rather than the input's individual label.The problem
Potential resolutions
Provide more ways to specify inputs
It would seem pertinent to copy the CSS-style selector syntax used by querySelector, querySelectorAll, et al. rather than limiting a developer to only using IDs.
Provide more ways to specify placement
Inline error placement is currently limited to either being immediately before the input element with the error (the default) or to be immediately after the legend element of the parent fieldset (if
inputsDeferToFieldsetsspecifies it). This, in my opinion at least, provides a sensible default and a reading order that is best optimised for users of assistive technologies. However, it creates problems when the demands of styling or other frameworks cannot accommodate error messages in these locations.The proposed rectification is twofold: To provide a "basic" way of defining the inline error placement via a keyword; and to provide an "advanced" option to give developers granular control over placement.
The "basic" keyword method could include options such as:
before— Inserts the error before the input. This is the current default functionality.after— Inserts the error after the input.beforeParent— Inserts the error before the input's parent element.afterParent— Inserts the error after the input's parent element.fieldsetStart— Inserts the error at the start of the input's parent fieldset (after the legend). This is the currentinputsDeferToFieldsetsfunctionality.fieldsetEnd— Inserts the error at the end of the input's parent fieldset.To preserve the labelling change that
inputsDeferToFieldsetsperforms, this should also be included as a flag.Example usage:
There are some implementation pain points around the this. The current ID limitation exists because that is a "known" piece of information in the context the check is being made in. Whether a specific input matches a given query string is a totally different kettle of fish, and may require an excessive number of DOM queries to achieve (number of inputs being checked × number of overrides defined).
The "advanced" method I imagine would allow the developer to provide a function that is ran to determine placement:
Example usage:
If we are providing this sort of granular placement then it would make sense to provide a global setting for it. For example, allowing the developer to always have error messages be placed below an input unless otherwise overridden.
Example usage:
It would also make sense to provide a limited some options for the error summary, although there isn't really anywhere it makes sense to display this except for at the start of the form/near the top of the page content.
Example usage:
Backwards compatibility
For backwards compatibility with previous VV versions, I would propose keeping the
inputsDeferToFieldsetsparameter and format identical to how it currently is, instead mapping its functions to the new functionality which is provided under new parameter names (e.g.inlineErrorPlacementandoverrideInlineErrorPlacement).