Skip to content

Instantly share code, notes, and snippets.

@Yemolai
Created July 10, 2019 01:56
Show Gist options
  • Save Yemolai/f26d1b32708c742d5620c8e13eec2192 to your computer and use it in GitHub Desktop.
Save Yemolai/f26d1b32708c742d5620c8e13eec2192 to your computer and use it in GitHub Desktop.
Form generator component example
<template>
<div>
<div class="row" v-for="(row, rowId) in rows" :key="rowId">
<div v-for="(field, fieldId) in row" :key="fieldId" :class="['q-pa-sm', colFor(field)]">
<template v-if="!!field">
<q-input
v-if="field.type === 'email'"
v-model="form[field.name]"
:label="field.label"
:hint="field.hint || undefined"
:rules="[ ...(field.rules || []), Validators.EmailRegex('Requer email válido') ]"
lazy-rules
/>
<q-input
v-else-if="field.type === 'tel'"
v-model="form[field.name]"
:label="field.label"
:hint="field.hint || undefined"
:rules="[ ...(field.rules || []), Validators.TelRegex('Requer número de telefone válido') ]"
lazy-rules
/>
<q-select
v-else-if="field.type === 'enum'"
:label="field.label"
:hint="field.hint || undefined"
:options="generateOptions(field)"
v-model="form[field.name]"
/>
<q-input
v-else
:label="field.label"
:hint="field.hint || undefined"
:rules="field.rules || []"
v-model="form[field.name]"
lazy-rules
/>
</template>
</div>
</div>
</div>
</template>
<script>
import { QInput, QSelect } from 'quasar'
import * as Validators from '@/shared/formValidators'
export default {
name: 'FormGenerator',
components: { QInput, QSelect },
props: {
value: {
type: Object,
default: () => ({})
},
schema: {
type: Object,
required: true
}
},
data() {
return {
Validators
}
},
computed: {
rows() {
if (!this.schema || !this.schema.fields) {
return []
}
return this.schema.fields.reduce((a, c) => {
if (!a[c.row]) {
a[c.row] = []
}
a[c.row][c.idx] = c
return a
}, [])
},
form: {
get() {
return this.value
},
set(val) {
return this.$emit('input', val)
},
deep: true
}
},
methods: {
colFor(field) {
if (field.col) {
return `col-${field.col}`
} else {
const breakpoints = ['xs', 'sm', 'md', 'lg', 'xl']
const cols = breakpoints
.map(size => (field[size] ? `col-${size}-${field[size]}` : null))
.filter(v => v)
if (cols.length < 1) {
return 'col'
} else {
return cols.join(' ')
}
}
},
generateOptions(field) {
return [
{ value: null, label: field.placeholder || 'Selecione' },
...field.options
]
}
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment