1# Forms 2 3Forms are created using the 4[bootstrap-vue form component](https://bootstrap-vue.org/docs/components/form) 5and validated with the [Vuelidate](https://vuelidate.js.org/#sub-installation) 6plugin. 7 8## Form component 9 10When creating a new form, use the `<b-form>` 11[form component](https://bootstrap-vue.org/docs/components/form). Use the 12`.prevent` event modifier on submit to prevent the submit event from reloading 13the page. 14 15## Form group component 16 17The `<b-form-group>` 18[form group component](https://bootstrap-vue.org/docs/components/form-group) 19pairs form controls with a legend or label, helper text, invalid/valid feedback 20text, and visual validation state feedback. Learn more about commonly used form 21components: 22 23- [Form checkbox](https://bootstrap-vue.org/docs/components/form-checkbox) 24- [Form input](https://bootstrap-vue.org/docs/components/form-input) 25- [Form radio](https://bootstrap-vue.org/docs/components/form-radio) 26- [Form select](https://bootstrap-vue.org/docs/components/form-select) 27- [Form file custom component](/guide/components/file-upload) 28 29When helper text is provided, use the `<b-form-text>` component and 30`aria-describedby` on the form group component the helper text describes. 31 32## Validation 33 34For custom form validation messages, disable browser native HTML5 validation by 35setting the `novalidate` prop on `<b-form>`. Use Vuelidate to check the form 36validation state and add custom validation messages in the 37`<b-form-invalid-feedback>` component. 38 39When creating a new form add the `VuelidateMixin` to the `scripts` block and 40import any [validators](https://vuelidate.js.org/#validators) needed such as: 41`required`, `requiredIf`, etc. The use of built-in validators is preferred. 42 43## Complete form 44 45A complete form will look like this. 46 47```vue 48<template> 49 <b-form novalidate @submit.prevent="handleSubmit"> 50 <b-form-group 51 :label="$t('pageName.form.inputLabel')" 52 label-for="form-input-id" 53 > 54 <b-form-text id="form-input-helper-text"> 55 {{ $t("pageName.form.helperText") }} 56 </b-form-text> 57 <b-form-input 58 id="form-input-id" 59 v-model="form.input" 60 type="text" 61 aria-describedby="form-input-helper-text" 62 :state="getValidationState($v.form.input)" 63 @change="$v.form.input.$touch()" 64 /> 65 <b-form-invalid-feedback role="alert"> 66 <div v-if="!$v.form.input.required"> 67 {{ $t("global.form.fieldRequired") }} 68 </div> 69 </b-form-invalid-feedback> 70 </b-form-group> 71 <b-button variant="primary" type="submit" class="mb-3"> 72 {{ $t("global.action.save") }} 73 </b-button> 74 </b-form> 75</template> 76 77<script> 78import VuelidateMixin from '@/components/Mixins/VuelidateMixin'; 79import { required } from 'vuelidate/lib/validators'; 80 81export default { 82 name: 'PageName', 83 components: { 84 ... 85 }, 86 mixins: [VuelidateMixin], 87 data(){ 88 form: { 89 input: '', 90 } 91 }, 92 validations() { 93 return { 94 form: { 95 input: { required }, 96 } 97 } 98 }, 99 computed: { 100 ... 101 }, 102 created() { 103 ... 104 }, 105 methods:{ 106 handleSubmit() { 107 this.$v.$touch(); 108 if (this.$v.$invalid) return; 109 this.$store 110 .dispatch( 111 'pageName/updateFormData', 112 formData 113 ) 114 .then((success) => { 115 this.successToast(success); 116 }) 117 .catch(({ message }) => this.errorToast(message)) 118 .finally(() => { 119 this.$v.form.$reset(); 120 this.endLoader(); 121 }); 122 }, 123}; 124</script> 125``` 126