|
| 1 | +<template> |
| 2 | + <h1>VUE FORM BUILDER DEMO</h1> |
| 3 | + <p>Sample demo to showcase VueFormBuilder's functionalities.</p> |
| 4 | + <vfb id="options" :fields="fieldsOptions" v-model="m" /> |
| 5 | + <TabView id="demo" class="tabview-custom"> |
| 6 | + <TabPanel header="VueFormBuilder"> |
| 7 | + <vfb v-bind="commonParams" :fields="fields1" /> |
| 8 | + </TabPanel> |
| 9 | + <TabPanel header="PrimeVue"> |
| 10 | + <vfb v-bind="commonParams" :fields="fields2" provider="primevue" /> |
| 11 | + </TabPanel> |
| 12 | + <TabPanel header="Vuetify"> |
| 13 | + Because Vuetify's CSS conflicts with PrimeVue's one, the Vuetify |
| 14 | + demo will be available in its own demo in the future. |
| 15 | + </TabPanel> |
| 16 | + </TabView> |
| 17 | +</template> |
| 18 | +<script lang="ts"> |
| 19 | +import { defineComponent } from "vue"; |
| 20 | +
|
| 21 | +const model = { |
| 22 | + name: "john", |
| 23 | + email: "john@email.test", |
| 24 | + gender: "male", |
| 25 | + phone: "+1 999 9999-9999", |
| 26 | + fruits: ["banana", "avocado"], |
| 27 | + website: "http://example.test/", |
| 28 | + country: "Canada", |
| 29 | + agree: true, |
| 30 | + bio: "Commodo proident incididunt anim reprehenderit amet occaecat in exercitation fugiat minim reprehenderit irure voluptate ad.", |
| 31 | +}; |
| 32 | +
|
| 33 | +const emptyModel = { |
| 34 | + name: "", |
| 35 | + email: "", |
| 36 | + gender: "", |
| 37 | + phone: "", |
| 38 | + fruits: [], |
| 39 | + website: "", |
| 40 | + country: "", |
| 41 | + agree: false, |
| 42 | + bio: "", |
| 43 | +} |
| 44 | +
|
| 45 | +const messages = { |
| 46 | + name: "god job", |
| 47 | + email: "awesome", |
| 48 | + gender: "god job", |
| 49 | + bio: "awesome", |
| 50 | + fruits: "god job", |
| 51 | + photo: "awesome", |
| 52 | + country: "god job", |
| 53 | + agree: "awesome", |
| 54 | + website: "god job", |
| 55 | + amount: "awesome job", |
| 56 | + birthday: "god job", |
| 57 | +}; |
| 58 | +
|
| 59 | +const errors = { |
| 60 | + name: "Name must be longer.", |
| 61 | + email: "Email is required.", |
| 62 | + phone: "Phone is invalid.", |
| 63 | + website: "Website must be valid URL.", |
| 64 | + amount: "too much!", |
| 65 | + password: "Password must contain letters and numbers.", |
| 66 | + bio: "Bio cannot have more than 100 words.", |
| 67 | + gender: "Pick a gender", |
| 68 | + photo: [ |
| 69 | + "Photo size must be below 2MB.", |
| 70 | + "Photo contains invalid dimensions.", |
| 71 | + "Supported formats are JPG or PNG.", |
| 72 | + ], |
| 73 | + fruits: "Choose at most 3 fruits", |
| 74 | + country: "Select a country.", |
| 75 | + agree: "We cannot procede without agreement.", |
| 76 | +}; |
| 77 | +
|
| 78 | +const validation = { |
| 79 | + name: (val: any) => { |
| 80 | + if (val.length < 5) return "name must be longer"; |
| 81 | + if (val.length > 20) return "name must be smaller"; |
| 82 | + return true; |
| 83 | + }, |
| 84 | + bio: (val: any) => { |
| 85 | + if (!val.includes("hello")) return 'bio must include the world "hello"'; |
| 86 | + return true; |
| 87 | + }, |
| 88 | + fruits: (val: any) => { |
| 89 | + if (val.length < 2) return "must choose at least 2 items!"; |
| 90 | + return true; |
| 91 | + }, |
| 92 | + agree: (val: any) => val, |
| 93 | +}; |
| 94 | +
|
| 95 | +const fields1 = [ |
| 96 | + "name:name|text|min=5|max=30", |
| 97 | + "name:email|email", |
| 98 | + "name:phone|tel|label:Phone number", |
| 99 | + "name:website|url|label:Personal website", |
| 100 | + "name:password|password|label:Choose your password", |
| 101 | + "name:birthday|date", |
| 102 | + "name:bio|textarea|label:Personal bio|rows=6", |
| 103 | + "name:gender|options:male,female", |
| 104 | + "name:photo|label:Profile picture|file", |
| 105 | + "name:fruits|stacked|checkboxes|options:apple,banana,orange,avocado", |
| 106 | + "name:country|stacked|options:United States,Mexico,Canada,Other", |
| 107 | + "name:agree|label:Agree to the terms and conditions|checkbox", |
| 108 | + "name:token|hidden|label:none|text", |
| 109 | + "component:vfb-buttons|label:none|class=block", |
| 110 | +]; |
| 111 | +
|
| 112 | +const fields2 = [ |
| 113 | + "name:date|component:Calendar|label:Choose a date:|dateFormat=MM dd, yy", |
| 114 | + { |
| 115 | + name: 'city', |
| 116 | + component: 'Dropdown', |
| 117 | + props: { options: ['New York', 'Dubai', 'Chicago', 'Moscou', 'Rio de Janeiro'] } |
| 118 | + }, |
| 119 | + { |
| 120 | + name: 'rate', |
| 121 | + label: 'Rate me!', |
| 122 | + component: 'Rating', |
| 123 | + props: { cancel: false, stars: 5 }, |
| 124 | + }, |
| 125 | + "name:tags|label:Enter tags:|component:Chips", |
| 126 | + "name:color|label:Pick a color:|component:ColorPicker|class=color-picker", |
| 127 | + "name:name|text|min=5|max=30", |
| 128 | + "name:email|email", |
| 129 | + "name:phone|tel|label:Phone number", |
| 130 | + "name:password|password|label:Choose your password", |
| 131 | + "name:bio|textarea|label:Personal bio|rows=6", |
| 132 | + "component:vfb-buttons|label:none|class=block", |
| 133 | +]; |
| 134 | +
|
| 135 | +const fields3 : any = [ |
| 136 | +]; |
| 137 | +
|
| 138 | +const emptyErrors = {} |
| 139 | +const emptyMsg = {} |
| 140 | +
|
| 141 | +export default defineComponent({ |
| 142 | + computed: { |
| 143 | + commonParams() { |
| 144 | + return { |
| 145 | + errors: (this.m.showErrors) ? errors : emptyErrors, |
| 146 | + modelValue: (this.m.useModel) ? model : emptyModel, |
| 147 | + messages: (this.m.showMessages) ? messages : emptyMsg, |
| 148 | + validateOnInput: this.m.validateOnInput, |
| 149 | + validateOnSubmit: this.m.validateOnSubmit, |
| 150 | + validation: validation, |
| 151 | + } |
| 152 | + } |
| 153 | + }, |
| 154 | + data: () => { |
| 155 | + return { |
| 156 | + fields1, |
| 157 | + fields2, |
| 158 | + fields3, |
| 159 | + fieldsOptions: [ |
| 160 | + 'checkbox|name:validateOnInput', |
| 161 | + 'checkbox|name:validateOnSubmit', |
| 162 | + 'checkbox|name:showMessages', |
| 163 | + 'checkbox|name:showErrors', |
| 164 | + 'checkbox|name:useModel', |
| 165 | + ], |
| 166 | + m: { |
| 167 | + validateOnInput: true, |
| 168 | + validateOnSubmit: true, |
| 169 | + useModel: false, |
| 170 | + showMessages: false, |
| 171 | + showErrors: false, |
| 172 | + }, |
| 173 | + } |
| 174 | + }, |
| 175 | +}); |
| 176 | +</script> |
| 177 | +<style> |
| 178 | +#options .vfb-group { |
| 179 | + margin-bottom: 0; |
| 180 | +} |
| 181 | +
|
| 182 | +#demo form { |
| 183 | + max-width: 500px; |
| 184 | + border: 1px solid #bbb; |
| 185 | + border-radius: 0.25em; |
| 186 | + padding: 1em; |
| 187 | + margin: 0 auto; |
| 188 | +} |
| 189 | +
|
| 190 | +.p-chips, |
| 191 | +.p-calendar, |
| 192 | +.p-inputtext, |
| 193 | +.p-textarea, |
| 194 | +.p-dropdown { |
| 195 | + width: 100%; |
| 196 | +} |
| 197 | +
|
| 198 | +.color-picker { |
| 199 | + margin-left: 8px; |
| 200 | + width: 2em; |
| 201 | + height: 2em; |
| 202 | +} |
| 203 | +</style> |
0 commit comments