89 lines
2.1 KiB
Vue
89 lines
2.1 KiB
Vue
<template>
|
|
<form @submit.prevent="submit()">
|
|
<div v-for="(item, key) in elements" :key="key">
|
|
<my-input
|
|
:description="item.description"
|
|
:label="item.label"
|
|
:name="key"
|
|
:placeholder="item.placeholder"
|
|
:type="item.type"
|
|
v-model="formData[key]"
|
|
@validate="validateData(key)"
|
|
:invalid="formErrors[key]"
|
|
>
|
|
</my-input>
|
|
</div>
|
|
<div>
|
|
<button v-for="(b, i) in buttons" :key="i" @click.prevent="buttonClick(b.type)">{{ b.label }}</button>
|
|
</div>
|
|
</form>
|
|
</template>
|
|
|
|
<script>
|
|
import MyInput from './my-input.vue';
|
|
|
|
export default {
|
|
name: "MyForm",
|
|
components: {
|
|
MyInput
|
|
},
|
|
props: {
|
|
elements: {
|
|
type: Object,
|
|
default: () => {
|
|
return [];
|
|
}
|
|
},
|
|
buttons: {
|
|
type: Array,
|
|
default: () => {
|
|
return [];
|
|
}
|
|
},
|
|
submitHandler: {
|
|
type: Function,
|
|
default: () => {
|
|
|
|
}
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
formData: {},
|
|
formErrors: {}
|
|
}
|
|
},
|
|
methods: {
|
|
validateData(name) {
|
|
if (this.elements[name].required) {
|
|
if (!this.formData[name]) {
|
|
this.$set(this.formErrors, name, {
|
|
error: 'required field'
|
|
});
|
|
|
|
return false;
|
|
} else {
|
|
this.$delete(this.formErrors, name);
|
|
}
|
|
}
|
|
return true;
|
|
},
|
|
buttonClick(type) {
|
|
switch(type) {
|
|
case 'submit':
|
|
this.submit();
|
|
break;
|
|
}
|
|
},
|
|
submit() {
|
|
let valid = true;
|
|
Object.keys(this.elements).forEach(key => {
|
|
valid = (this.validateData(key) && valid);
|
|
});
|
|
if (valid) {
|
|
this.submitHandler(this.formData);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script> |