Unfortunately, the design page you are looking for is not ready yet. But you might want to switch to the implementation tab. There you will find the corresponding Vue component and a description of the different use cases and what to consider when implementing it.
If you have any questions, suggestions or ideas for improvement right now, please feel free to contact us directly.
via Slack: #wescale-wui-public
via Mail: wescale-wui@wescale.com
Stay tuned!
import { WuiForm
WuiFormText
WuiFormInvalidFeedback
WuiFormValidFeedback
WuiFormRow } from "@wui/wui-vue/lib/form";
Description
WuiVue form component and helper components that optionally support inline form styles and validation states. Pair them up with other WuiVue form control components for an easy customized, and responsive, layout with a consistent look and feel.
Introduction to forms and controls
Be sure to use an appropriate type
on all inputs (e.g., email
for email address or number
for numerical information) to take advantage of newer input controls like email verification, number selection, and more.
Here's a quick example to demonstrate WuiVue's form styles. Keep reading for documentation on supported components, form layout, and more.
<template>
<div>
<wui-form @submit="onSubmit" @reset="onReset" v-if="show">
<wui-form-group
id="input-group-1"
label="Email address:"
label-for="input-1"
description="We'll never share your email with anyone else."
>
<wui-form-input
id="input-1"
v-model="form.email"
type="email"
placeholder="Enter email"
required
></wui-form-input>
</wui-form-group>
<wui-form-group
id="input-group-10"
label="Your Name:"
label-for="input-2"
>
<wui-form-input
id="input-2"
v-model="form.name"
placeholder="Enter name"
required
></wui-form-input>
</wui-form-group>
<wui-form-group id="input-group-3" label="Food:" label-for="input-3">
<wui-form-select
id="input-3"
v-model="form.food"
:options="foods"
required
></wui-form-select>
</wui-form-group>
<wui-form-group id="input-group-4" v-slot="{ ariaDescribedby }">
<wui-form-checkbox-group
v-model="form.checked"
id="checkboxes-4"
:aria-describedby="ariaDescribedby"
>
<wui-form-checkbox value="me">Check me out</wui-form-checkbox>
<wui-form-checkbox value="that">Check that out</wui-form-checkbox>
</wui-form-checkbox-group>
</wui-form-group>
<wui-button type="submit" variant="primary">Submit</wui-button>
<wui-button type="reset" variant="danger">Reset</wui-button>
</wui-form>
<wui-card class="mt-3" header="Form Data Result">
<pre class="m-0">{ form }</pre>
</wui-card>
</div>
</template>
<script>
export default {
data() {
return {
form: {
email: "",
name: "",
food: null,
checked: [],
},
foods: [
{ text: "Select One", value: null },
"Carrots",
"Beans",
"Tomatoes",
"Corn",
],
show: true,
};
},
methods: {
onSubmit(event) {
event.preventDefault();
alert(JSON.stringify(this.form));
},
onReset(event) {
event.preventDefault();
// Reset our form values
this.form.email = "";
this.form.name = "";
this.form.food = null;
this.form.checked = [];
// Trick to reset/clear native browser form validation state
this.show = false;
this.$nextTick(() => {
this.show = true;
});
},
},
};
</script>
<!-- wui-form.vue -->
Inline form
Use the inline
prop on <wui-form>
to display a series of labels, form controls, and buttons on a single horizontal row. Form controls within inline forms vary slightly from their default states.
- Controls and input groups receive
width: auto
to override the WUI default width: 100%. - Controls only appear inline in viewports that are at least 768px wide to account for narrow viewports on mobile devices.
You may need to manually address the width and alignment of individual form controls with spacing utilities (as shown below). Lastly, be sure to always include a <label>
with each form control, even if you need to hide it from non-screenreader visitors with class .sr-only
.
<div>
<wui-form inline>
<label class="sr-only" for="inline-form-input-name">Name</label>
<wui-form-input
id="inline-form-input-name"
class="m-b-5"
placeholder="Jane Doe"
></wui-form-input>
<label class="sr-only" for="inline-form-input-username">Username</label>
<wui-input-group prepend="@" class="m-b-5">
<wui-form-input
id="inline-form-input-username"
placeholder="Username"
></wui-form-input>
</wui-input-group>
<wui-form-checkbox class="m-b-5">Remember me</wui-form-checkbox>
<wui-button variant="primary">Save</wui-button>
</wui-form>
</div>
<!-- wui-form-inline.vue -->
Custom form controls and selects are also supported.
<div>
<wui-form inline>
<label class="m-r-15" for="inline-form-custom-select-pref"
>Preference</label
>
<wui-form-select
id="inline-form-custom-select-pref"
class="m-b-5"
:options="[{ text: 'Choose...', value: null }, 'One', 'Two', 'Three']"
:value="null"
></wui-form-select>
<wui-form-checkbox class="m-b-5">Remember my preference</wui-form-checkbox>
<wui-button variant="primary">Save</wui-button>
</wui-form>
</div>
<!-- wui-form-inline-custom.vue -->
Note: <wui-form-group>
is not supported in inline
forms due to layout conflicts.
Alternatives to hidden labels
Assistive technologies such as screen readers will have trouble with your forms if you don't include a label for every input. For these inline forms, you can hide the labels using the .sr-only
class. There are further alternative methods of providing a label for assistive technologies, such as the aria-label
, aria-labelledby
or title
attributes. If none of these are present, assistive technologies may resort to using the placeholder
attribute, if present, but note that use of placeholder
as a replacement for other labelling methods is not advised.
Related form control and layout components
See also:
<wui-form-input>
Textual and text-like inputs<wui-form-textarea>
Text area inputs<wui-form-select>
Select input<wui-form-radio>
Radio Inputs<wui-form-checkbox>
Checkbox Inputs<wui-form-file>
File Input<wui-form-tags>
Customizable tag input<wui-form-rating>
Star rating custom form input and display<wui-button>
Buttons<wui-form-group>
Form Input wrapper to generate form-groups that support labels, help text and feedback<wui-input-group>
Form Inputs with add-ons<wui-form-row>
Create grid rows and columns with tighter margins (available via the Layout and grid components)
Form helper components
The following helper components are available with the Form
plugin:
<wui-form-text>
Help text blocks for inputs<wui-form-invalid-feedback>
Invalid feedback text blocks for inputinvalid
states<wui-form-valid-feedback>
Valid feedback text blocks for inputvalid
states<wui-form-remaining-characters>
Displays the number of characters remaining for inputs or textareas
Form text helper
Display a block of help text below an input with the <wui-form-text>
helper component. Text is displayed with a muted color and slightly smaller font-size.
Tip: Help text should be explicitly associated with the form control it relates to using the aria-describedby
attribute. This will ensure that assistive technologies, such as screen readers, will announce this help text when the user focuses or enters the control.
<div>
<wui-form @submit.stop.prevent>
<label for="text-password">Password</label>
<wui-form-input
type="password"
id="text-password"
aria-describedby="password-help-block"
></wui-form-input>
<wui-form-text id="password-help-block">
Your password must be 8-20 characters long, contain letters and numbers,
and must not contain spaces, special characters, or emoji.
</wui-form-text>
</wui-form>
</div>
<!-- wui-form-help-text.vue -->
Feedback helpers
The <wui-form-valid-feedback>
and <wui-form-invalid-feedback>
helper components will display feedback (based on input state) as a block of colored text. They rely on being placed after an input (sibling) and will show based on the browser native validation state of the input. To force them to show, set the prop force-show
to true
, or bind the controls state
to the state
prop of the feedback helper, or set the was-validated
class on a parent element (such as a form). See the Validation section below for additional details.
Use the optional Boolean prop tooltip
to change the display from a block to a static tooltip style. The feedback will typically appear below the form control. When this mode is enabled, it is important that the parent container have a position: relative:
css style (or position-relative
class). Note that tooltip style feedback may, since its positioning is static, obscure other inputs, labels, etc.
Note: Some form controls, such as <wui-form-radio>
, <wui-form-checkbox>
, and <wui-form-file>
have wrapper elements which will prevent the feedback text from automatically showing (as the feedback component is not a direct sibling of the form control's input). Use the feedback component's state
prop (bound to the state of the form control) or the force-show
prop to display the feedback.
<template>
<div>
<wui-form @submit.stop.prevent>
<label for="feedback-user">User ID</label>
<wui-form-input
v-model="userId"
:state="validation"
id="feedback-user"
></wui-form-input>
<wui-form-invalid-feedback :state="validation">
Your user ID must be 5-12 characters long.
</wui-form-invalid-feedback>
<wui-form-valid-feedback :state="validation">
Looks Good.
</wui-form-valid-feedback>
</wui-form>
</div>
</template>
<script>
export default {
data() {
return {
userId: "",
};
},
computed: {
validation() {
return this.userId.length > 4 && this.userId.length < 13;
},
},
};
</script>
<!-- wui-form-feedback-example.vue -->
Remaining characters helper
New in 1.1.0
The helper component <wui-form-remaining-characters>
displays the number of remaining characters at the end of an input field or textarea. Use the show
prop to show or hide the character counter (useful to show the counter only when your input field has focus). Pass the value
of your input field and the maximum number of characters per max-length
to <wui-form-remaining-characters>
. The component calculates the remaining characters.
You can also use the scoped slot props remainingCharacters
and isValid
to build your own custom counter.
<template>
<wui-form>
<!-- Basic input field -->
<wui-form-group
label="Basic input"
label-for="remaining-example"
:state="isValid"
>
<wui-form-remaining-characters
:value="value"
:max-length="maxLength"
:show="showRemainingCharacters"
>
<wui-form-input
v-model="value"
id="remaining-example"
:state="isValid"
@focus="handleFocusEvent"
@blur="handleBlurEvent"
/>
</wui-form-remaining-characters>
<wui-form-valid-feedback :state="isValid"
>Value: { value }</wui-form-valid-feedback
>
<wui-form-invalid-feedback :state="isValid"
>Only { maxLength } characters are allowed.</wui-form-invalid-feedback
>
</wui-form-group>
<wui-form-group
label="Input group"
label-for="remaining-group-example"
:state="isValid"
>
<!-- Input group -->
<wui-input-group>
<wui-form-remaining-characters
:value="value"
:max-length="maxLength"
:show="showRemainingCharacters"
class="form-control border-0 p-0"
>
<wui-form-input
v-model="value"
id="remaining-group-example"
:state="isValid"
@focus="handleFocusEvent"
@blur="handleBlurEvent"
/>
</wui-form-remaining-characters>
<wui-input-group-append>
<wui-input-group-text
><wui-fa-icon icon="search"
/></wui-input-group-text>
</wui-input-group-append>
</wui-input-group>
</wui-form-group>
<wui-form-valid-feedback :state="isValid"
>Value: { value }</wui-form-valid-feedback
>
<wui-form-invalid-feedback :state="isValid"
>Only { maxLength } characters are allowed.</wui-form-invalid-feedback
>
<!-- Textarea -->
<wui-form-group
label="Textarea"
label-for="textarea-example"
:state="isValid"
>
<wui-form-remaining-characters
:value="value"
:max-length="maxLength"
:show="showRemainingCharacters"
>
<wui-form-textarea
v-model="value"
id="textarea-example"
:state="isValid"
:rows="4"
@focus="handleFocusEvent"
@blur="handleBlurEvent"
></wui-form-textarea>
</wui-form-remaining-characters>
<wui-form-valid-feedback :state="isValid"
>Value: { value }</wui-form-valid-feedback
>
<wui-form-invalid-feedback :state="isValid"
>Only { maxLength } characters are allowed.</wui-form-invalid-feedback
>
</wui-form-group>
</wui-form>
</template>
<script>
export default {
data() {
return {
value: "",
showRemainingCharacters: false,
maxLength: 10,
};
},
computed: {
isValid() {
return this.valueRemaining
? this.valueRemaining.length <= this.maxLength
? true
: false
: null;
},
},
methods: {
handleFocusEvent() {
this.showRemainingCharacters = true;
},
handleBlurEvent() {
this.showRemainingCharacters = false;
},
},
};
</script>
<!-- wui-form-remaining-characters-example.vue -->
Validation
Disable browser native HTML5 validation by setting the novalidate
prop to true on <wui-form>
.
Set the validated
prop, on <wui-form>
, to true
to add the WUI/Bootstrap v4 .was-validated
class to the form to trigger validation states
All of the form controls support a state
prop, which can be used to set the form control into one of three contextual abstract states or three states based on semantic string identifiers:
false
orerror
(denotes invalid state) is great for when there's a blocking or required field. A user must fill in this field properly to submit the form.true
orsuccess
(denotes valid state) is ideal for situations when you have per-field validation throughoutwarning
(denotes invalid state) is great for when there's a field with a value which is not an error but might be a risky value in the context of the submitted datanull
Displays no validation state (neither valid nor invalid)
Refer to the Bootstrap v3 Form Validation Documentation for details on the new Bootstrap v3 validation states.
Validation mechanisms
Additional resources:
- Bootstrap v3: Form Validation Documentation
- MDN: Learn Form Validation - Using JavaScript API
- MDN: HTML5 Constraint Validation
- MDN: Validity State API
Component reference
<wui-form>
Properties
Prop | Type | Default | Description |
---|---|---|---|
id | String | Used to set the id attribute on the rendered content, and used as the base to generate any additional element IDs as needed | |
inline | Boolean | false | When set, the form will be in inline mode which display labels, form controls, and buttons on a single horizontal row |
horizontal | Boolean | false | When set, adds the wui class 'wui-bs-form--horizontal' on the form to align labels and groups of form controls in a horizontal layout |
novalidate | Boolean | false | When set, disables browser native HTML5 validation on controls in the form |
Slots
Name | Description |
---|---|
default | Content to place in the form |
Events
Event | Arguments | Description |
---|---|---|
submit | event - Native submit event | Emitted when the form is being submitted |
<wui-form-text>
Properties
Prop | Type | Default | Description |
---|---|---|---|
id | String | Used to set the id attribute on the rendered content, and used as the base to generate any additional element IDs as needed | |
inline | Boolean | false | When set, renders the help text as an inline element, rather than a block element |
tag | String | 'small' | Specify the HTML tag to render instead of the default tag |
text-variant | String | 'info' | Applies one of the wui-message color variants to the text (info (default), success , error or warning ) |
Slots
Name | Description |
---|---|
default | Content to place in the form text |
<wui-form-invalid-feedback>
Properties
Prop | Type | Default | Description |
---|---|---|---|
aria-live | String | When the rendered element is an aria-live region (for screen reader users), set to either 'polite' or 'assertive' | |
force-show | Boolean | false | Shows the feedback text, regardless of the value of the 'state' prop |
id | String | Used to set the id attribute on the rendered content, and used as the base to generate any additional element IDs as needed | |
role | String | Sets the ARIA attribute role to a specific value | |
state | Boolean | null | When explicitly 'false', forces the feedback to show |
tag | String | 'div' | Specify the HTML tag to render instead of the default tag |
tooltip | Boolean | false | Renders the feedback text in a rudimentary tooltip style |
Slots
Name | Description |
---|---|
default | Content to place in the form invalid feedback |
<wui-form-valid-feedback>
Properties
Prop | Type | Default | Description |
---|---|---|---|
aria-live | String | When the rendered element is an aria-live region (for screen reader users), set to either 'polite' or 'assertive' | |
force-show | Boolean | false | Shows the feedback text, regardless of the value of the 'state' prop |
id | String | Used to set the id attribute on the rendered content, and used as the base to generate any additional element IDs as needed | |
role | String | Sets the ARIA attribute role to a specific value | |
state | Boolean | null | When explicitly 'false', forces the feedback to show |
tag | String | 'div' | Specify the HTML tag to render instead of the default tag |
tooltip | Boolean | false | Renders the feedback text in a rudimentary tooltip style |
Slots
Name | Description |
---|---|
default | Content to place in the form valid feedback element |
<wui-form-remaining-characters>
Properties
Prop | Type | Default | Description |
---|---|---|---|
maxLength Required | Number or String | The maximum allowed length of the input value. This value is also the initially displayed value if there is no user input yet | |
show | Boolean | false | Whether to display the remaining character counter or not (useful in conjunction with @focus and @blur input events) |
value | Number or String | The value of the input field to which the remaining characters refer |
Slots
Name | Scope | Description |
---|---|---|
count | isValid - Boolean - Whether the maximum length has been exceeded or notremainingCharacters - String - The number of characters remaining | Content to be placed in place of the character counter |
default | isValid - Boolean - Whether the maximum length has been exceeded or notremainingCharacters - String - The number of characters remaining | Content to place in the form remaining characters element (usually the input or textarea element) |