2
0
mirror of https://github.com/frappe/books.git synced 2024-11-14 01:14:03 +00:00
books/ui/components/Form/Form.vue

159 lines
3.4 KiB
Vue
Raw Normal View History

2018-06-27 14:38:27 +00:00
<template>
<div class="frappe-form">
<form-actions
class="p-3 border-bottom"
v-if="shouldRenderForm"
:doc="doc"
:links="links"
@save="save"
@submit="submit"
@revert="revert"
@print="print"
/>
<form-layout
class="p-3"
v-if="shouldRenderForm"
:doc="doc"
:fields="meta.fields"
:layout="meta.layout"
:invalid="invalid"
/>
<not-found v-if="notFound" />
</div>
2018-06-27 14:38:27 +00:00
</template>
<script>
import frappe from 'frappejs';
import FormLayout from './FormLayout';
import FormActions from './FormActions';
import { _ } from 'frappejs/utils';
export default {
name: 'Form',
props: ['doctype', 'name', 'defaultValues'],
2018-06-27 14:38:27 +00:00
components: {
FormActions,
FormLayout
},
data() {
return {
docLoaded: false,
notFound: false,
invalid: false,
2018-07-14 14:58:18 +00:00
invalidFields: [],
links: [],
defaults: this.defaultValues
2018-07-14 14:58:18 +00:00
};
2018-06-27 14:38:27 +00:00
},
computed: {
meta() {
return frappe.getMeta(this.doctype);
},
shouldRenderForm() {
return this.name && this.docLoaded;
}
},
async created() {
if (!this.defaults) {
this.defaults = {};
}
this.meta.fields.forEach(field => {
if (field.defaultValue)
this.defaults[field.fieldname] = field.defaultValue;
});
2018-06-27 14:38:27 +00:00
if (!this.name) return;
try {
this.doc = await frappe.getDoc(this.doctype, this.name);
if (
this.doc.isNew() &&
this.meta.fields.map(df => df.fieldname).includes('name')
) {
// For a user editable name field,
// it should be unset since it is autogenerated
this.doc.set('name', '');
}
if (this.defaults) {
for (let fieldname in this.defaults) {
const value = this.defaults[fieldname];
await this.doc.set(fieldname, value);
}
}
2018-06-27 14:38:27 +00:00
this.docLoaded = true;
2018-07-14 14:58:18 +00:00
} catch (e) {
console.error(e);
2018-06-27 14:38:27 +00:00
this.notFound = true;
}
2018-07-14 14:58:18 +00:00
this.setLinks();
this.doc.on('change', this.setLinks);
2018-06-27 14:38:27 +00:00
},
methods: {
async save() {
this.setValidity();
if (this.invalid) return;
try {
2018-11-09 19:07:14 +00:00
if (this.doc.isNew()) {
2018-06-27 14:38:27 +00:00
await this.doc.insert();
} else {
await this.doc.update();
}
this.$emit('save', this.doc);
} catch (e) {
console.error(e);
return;
}
},
2018-07-14 14:58:18 +00:00
setLinks() {
if (this.meta.links) {
let links = [];
for (let link of this.meta.links) {
if (link.condition(this)) {
link.handler = () => {
link.action(this);
};
links.push(link);
}
}
this.links = links;
}
},
async submit() {
this.doc.set('submitted', 1);
await this.save();
},
async revert() {
this.doc.set('submitted', 0);
await this.save();
},
2018-07-13 05:16:15 +00:00
print() {
this.$router.push(`/print/${this.doctype}/${this.name}`);
},
2018-06-27 14:38:27 +00:00
onValidate(fieldname, isValid) {
if (!isValid && !this.invalidFields.includes(fieldname)) {
this.invalidFields.push(fieldname);
} else if (isValid) {
2018-07-14 14:58:18 +00:00
this.invalidFields = this.invalidFields.filter(
invalidField => invalidField !== fieldname
);
2018-06-27 14:38:27 +00:00
}
},
setValidity() {
const form = this.$el.querySelector('form');
let validity = form.checkValidity();
this.invalid = !validity;
2018-07-14 14:58:18 +00:00
}
2018-06-27 14:38:27 +00:00
}
};
</script>
<style>
</style>