2018-01-16 06:09:17 +00:00
|
|
|
const frappe = require('frappejs');
|
2018-01-12 12:25:07 +00:00
|
|
|
const controls = require('./controls');
|
2018-01-31 10:13:33 +00:00
|
|
|
const Observable = require('frappejs/utils/observable');
|
2018-01-12 12:25:07 +00:00
|
|
|
|
2018-01-31 10:13:33 +00:00
|
|
|
module.exports = class BaseForm extends Observable {
|
2018-02-08 09:38:47 +00:00
|
|
|
constructor({doctype, parent, submit_label='Submit', page}) {
|
2018-01-31 10:13:33 +00:00
|
|
|
super();
|
2018-02-08 09:38:47 +00:00
|
|
|
Object.assign(this, arguments[0]);
|
2018-01-12 12:25:07 +00:00
|
|
|
this.controls = {};
|
2018-02-08 09:38:47 +00:00
|
|
|
this.controlList = [];
|
2018-01-12 12:25:07 +00:00
|
|
|
|
2018-02-08 06:46:38 +00:00
|
|
|
this.meta = frappe.getMeta(this.doctype);
|
2018-01-24 11:52:05 +00:00
|
|
|
if (this.setup) {
|
|
|
|
this.setup();
|
|
|
|
}
|
2018-01-12 12:25:07 +00:00
|
|
|
this.make();
|
|
|
|
}
|
|
|
|
|
|
|
|
make() {
|
|
|
|
if (this.body || !this.parent) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.body = frappe.ui.add('div', 'form-body', this.parent);
|
2018-02-08 09:38:47 +00:00
|
|
|
this.makeToolbar();
|
2018-01-12 12:25:07 +00:00
|
|
|
|
2018-02-09 12:55:55 +00:00
|
|
|
this.form = frappe.ui.add('form', 'form-container', this.body);
|
|
|
|
this.form.onValidate = true;
|
|
|
|
|
|
|
|
this.makeControls();
|
|
|
|
}
|
|
|
|
|
|
|
|
makeControls() {
|
2018-02-06 17:14:07 +00:00
|
|
|
for(let field of this.meta.fields) {
|
2018-02-09 12:55:55 +00:00
|
|
|
if (!field.hidden && controls.getControlClass(field.fieldtype)) {
|
2018-02-08 09:38:47 +00:00
|
|
|
let control = controls.makeControl({field: field, form: this});
|
|
|
|
this.controlList.push(control);
|
2018-02-06 17:14:07 +00:00
|
|
|
this.controls[field.fieldname] = control;
|
2018-01-12 12:25:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-08 09:38:47 +00:00
|
|
|
makeToolbar() {
|
2018-02-09 12:55:55 +00:00
|
|
|
this.btnSubmit = this.page.addButton(frappe._("Save"), 'btn-primary', async (event) => {
|
2018-02-08 09:38:47 +00:00
|
|
|
await this.submit();
|
2018-01-23 08:00:29 +00:00
|
|
|
})
|
|
|
|
|
2018-02-09 12:55:55 +00:00
|
|
|
this.btnDelete = this.page.addButton(frappe._("Delete"), 'btn-outline-secondary', async (e) => {
|
2018-01-12 12:25:07 +00:00
|
|
|
await this.doc.delete();
|
2018-02-08 09:38:47 +00:00
|
|
|
this.showAlert('Deleted', 'success');
|
2018-01-31 10:13:33 +00:00
|
|
|
this.trigger('delete');
|
2018-01-12 12:25:07 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-02-09 12:55:55 +00:00
|
|
|
async use(doc) {
|
2018-01-12 12:25:07 +00:00
|
|
|
if (this.doc) {
|
|
|
|
// clear handlers of outgoing doc
|
2018-02-08 09:38:47 +00:00
|
|
|
this.doc.clearHandlers();
|
2018-01-12 12:25:07 +00:00
|
|
|
}
|
2018-02-08 09:38:47 +00:00
|
|
|
this.clearAlert();
|
2018-01-12 12:25:07 +00:00
|
|
|
this.doc = doc;
|
2018-02-08 09:38:47 +00:00
|
|
|
for (let control of this.controlList) {
|
2018-01-12 12:25:07 +00:00
|
|
|
control.bind(this.doc);
|
|
|
|
}
|
2018-01-25 10:04:48 +00:00
|
|
|
|
2018-02-09 12:55:55 +00:00
|
|
|
this.setupChangeHandler();
|
|
|
|
this.trigger('use', {doc:doc});
|
|
|
|
}
|
|
|
|
|
|
|
|
setupChangeHandler() {
|
2018-01-25 10:04:48 +00:00
|
|
|
// refresh value in control
|
2018-02-08 09:38:47 +00:00
|
|
|
this.doc.addHandler('change', (params) => {
|
2018-02-08 11:45:32 +00:00
|
|
|
if (params.fieldname) {
|
|
|
|
// only single value changed
|
|
|
|
let control = this.controls[params.fieldname];
|
|
|
|
if (control && control.getInputValue() !== control.format(params.fieldname)) {
|
|
|
|
control.setDocValue();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// multiple values changed
|
|
|
|
this.refresh();
|
2018-01-25 10:04:48 +00:00
|
|
|
}
|
2018-02-09 12:55:55 +00:00
|
|
|
this.form.classList.remove('was-validated');
|
2018-01-25 10:04:48 +00:00
|
|
|
});
|
2018-01-12 12:25:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async submit() {
|
2018-02-09 12:55:55 +00:00
|
|
|
if (!this.form.checkValidity()) {
|
|
|
|
this.form.classList.add('was-validated');
|
|
|
|
return;
|
|
|
|
}
|
2018-01-12 12:25:07 +00:00
|
|
|
try {
|
2018-02-09 12:55:55 +00:00
|
|
|
if (this.doc._notInserted) {
|
2018-01-12 12:25:07 +00:00
|
|
|
await this.doc.insert();
|
|
|
|
} else {
|
|
|
|
await this.doc.update();
|
|
|
|
}
|
|
|
|
await this.refresh();
|
2018-02-08 09:38:47 +00:00
|
|
|
this.showAlert('Saved', 'success');
|
2018-01-12 12:25:07 +00:00
|
|
|
} catch (e) {
|
2018-02-08 09:38:47 +00:00
|
|
|
this.showAlert('Failed', 'danger');
|
2018-02-09 12:55:55 +00:00
|
|
|
return;
|
2018-01-12 12:25:07 +00:00
|
|
|
}
|
2018-01-31 10:13:33 +00:00
|
|
|
await this.trigger('submit');
|
2018-01-12 12:25:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
refresh() {
|
2018-02-08 09:38:47 +00:00
|
|
|
for(let control of this.controlList) {
|
2018-01-12 12:25:07 +00:00
|
|
|
control.refresh();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-08 09:38:47 +00:00
|
|
|
showAlert(message, type, clear_after = 5) {
|
|
|
|
this.clearAlert();
|
2018-01-31 10:13:33 +00:00
|
|
|
this.alert = frappe.ui.add('div', `alert alert-${type}`, this.body);
|
|
|
|
this.alert.textContent = message;
|
|
|
|
setTimeout(() => {
|
2018-02-08 09:38:47 +00:00
|
|
|
this.clearAlert();
|
2018-01-31 10:13:33 +00:00
|
|
|
}, clear_after * 1000);
|
|
|
|
}
|
|
|
|
|
2018-02-08 09:38:47 +00:00
|
|
|
clearAlert() {
|
2018-01-31 10:13:33 +00:00
|
|
|
if (this.alert) {
|
|
|
|
frappe.ui.remove(this.alert);
|
|
|
|
this.alert = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-15 11:55:31 +00:00
|
|
|
}
|