Files
books/src/pages/FormView/FormView.vue
T
thefalconx33 86d0ef3d06 - Dashboard
- SearchBar
- Invoice & Bill Rename
2019-08-01 17:22:58 +05:30

184 lines
4.0 KiB
Vue

<template>
<div class="bg-white">
<page-header :breadcrumbs="breadcrumbs" />
<div class="form-container col-sm-8 col-lg-6 mx-2 mt-4">
<form-actions
v-if="shouldRenderForm"
:doc="doc"
@save="save"
@submit="submit"
@revert="revert"
@print="print"
:links="links"
/>
<hr class="mb-3" />
<form-layout
v-if="shouldRenderForm"
:doc="doc"
:fields="meta.fields"
:layout="meta.layout"
:invalid="isFormInvalid"
/>
</div>
</div>
</template>
<script>
import frappe from 'frappejs';
import FormActions from 'frappejs/ui/components/Form/FormActions';
import FormLayout from 'frappejs/ui/components/Form/FormLayout';
import PageHeader from '@/components/PageHeader';
export default {
name: 'FormView',
props: ['doctype', 'name'],
components: {
PageHeader,
FormActions,
FormLayout
},
watch: {
name(newValue, oldValue) {
if (newValue !== oldValue) {
this.loadDoc();
}
}
},
data() {
return {
doc: null,
links: [],
isFormInvalid: false,
notFound: false
};
},
computed: {
breadcrumbs() {
if (this.doc)
return [
{
title: this.meta.label,
route: '#/list/' + this.doctype
},
{
title: this.doc._notInserted
? 'New ' + this.meta.label
: this.doc.name,
route: ''
}
];
},
shouldRenderForm() {
return this.name && this.doc;
},
meta() {
return frappe.getMeta(this.doctype);
}
},
created() {
this.loadDoc();
},
methods: {
async loadDoc() {
if (!this.name) return;
try {
// need to de-reference to let vue know that doc is changed
this.doc = null;
this.doc = await frappe.getDoc(this.doctype, this.name);
if (
this.doc._notInserted &&
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.defaultValues) {
for (let fieldname in this.defaultValues) {
const value = this.defaultValues[fieldname];
this.doc.set(fieldname, value);
}
}
this.setLinks();
this.doc.on('change', this.setLinks);
} catch (e) {
this.notFound = true;
this.$router.push(
`/list/${this.doctype === 'Party' ? 'Customer' : this.doctype}`
); //if reloaded while insert new Item,Invoice etc form.
}
},
async save() {
this.setValidity();
if (this.isFormInvalid) return;
try {
if (this.doc._notInserted) {
await this.doc.insert();
} else {
await this.doc.update();
}
this.$emit('save', this.doc);
} catch (e) {
console.error(e);
throw e;
}
},
async submit() {
this.doc.set('submitted', 1);
try {
await this.save();
} catch (e) {
this.doc.set('submitted', 0);
this.doc.set('_dirty', false);
}
},
async revert() {
this.doc.set('submitted', 0);
try {
await this.save();
} catch (e) {
this.doc.set('submitted', 1);
this.doc._dirty = false;
}
},
print() {
this.$router.push(`/print/${this.doctype}/${this.name}`);
},
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;
}
},
setValidity() {
const form = this.$el.querySelector('form');
let validity = form.checkValidity();
this.isFormInvalid = !validity;
}
}
};
</script>
<style>
.table th,
.table td {
vertical-align: middle;
}
</style>