I added an event after field edition, what do you think ?
melBoh opened this issue · 8 comments
Hi !
I needed to save data after inline edition. seeing #46 I thought I should try my hand on it.
It's working for me, but I don't know if it's good enough for community, so, what do you think ?
in apps/frappe/node_modules/frappe-datatable/dist/frappe-datatable.cjs.js
from line 2525
class CellManager { constructor(instance) { this.instance = instance; linkProperties(this, this.instance, [ 'wrapper', 'options', 'style', 'header', 'bodyScrollable', 'columnmanager', 'rowmanager', 'datamanager', 'keyboard', 'fireEvent', //<= add this ]); this.bindEvents();
then, from line 3022
` submitEditing() {
if (!this.$editingCell) return;
const $cell = this.$editingCell;
const {
rowIndex,
colIndex
} = $.data($cell);
const col = this.datamanager.getColumn(colIndex);
if ($cell) {
const editor = this.currentCellEditor;
if (editor) {
let valuePromise = editor.getValue();
// convert to stubbed Promise
if (!valuePromise.then) {
valuePromise = Promise.resolve(valuePromise);
}
valuePromise.then((value) => {
const done = editor.setValue(value, rowIndex, col);
const oldValue = this.getCell(colIndex, rowIndex).content;
// update cell immediately
this.updateCell(colIndex, rowIndex, value);
$cell.focus();
// =>add this : BEGINNING OF add edit submit event
let rowData = this.datamanager.getData(rowIndex);
this.fireEvent('onSubmitEditing', [rowData, this.getCell(colIndex, rowIndex).column.id, value]);
// END OF add edit submit event
if (done && done.then) {
// revert to oldValue if promise fails
done.catch((e) => {
console.log(e);
this.updateCell(colIndex, rowIndex, oldValue);
});
}
});
}
}
this.currentCellEditor = null;
}`
Then in custom JS (associated to a report in my case)
`
frappe.query_reports["my_report"] = {
...
get_datatable_options(options) {
// loops on each column and make one ore more of them editable
options.columns.forEach(function(column, i) {
// column id i want to make editable
if(column.id == "your_editable_id") {
column.editable = true
}
});
// change datatable options
return Object.assign(options, {
checkboxColumn: true,
events: {
onSubmitEditing: function (cell) {
// rowValues : all cell values from row before edition
// cellId : key id of cell edited
// newVal : edited val
let [rowValues, cellId, newVal] = cell;
if(cellId == "your_editable_id") {
frappe.call({
method: "your.method",
type: "GET",
args: {name: rowValues.id, qty: newVal}, // for example
callback: function (r) {
if (r.message) {
frappe.msgprint(__(r.message));
}
},
});
}
},
}
});
},
};
`
Is there any way to get selected rows in Datatable?
But how to get row Ids, that is selected?
What is the Event to capture selected rows?
Thanks in Advance…
@hetal1110 you can get selected rows of report having checkbox as mentioned below:
onload: function() {
// add a button to report
frappe.query_report.page.add_inner_button(__("Get Selected"), function() {
var selected_rows = [];
$('.dt-scrollable').find(":input[type=checkbox]").each((idx, row) => {
if(row.checked){
console.log("*** selected row id : " + idx);
selected_rows.push(frappe.query_report.data[idx]);
}
});
});
},
Hi @melBoh, thank you very much. I think it's working real well as I have used it to enabled a feature of editing inline and update it in the database. I wonder why it's still not merged to the repository.
If I make the changes on my own, how to prevent the changes be override with next frappe version updates.
why this is still open? Can a PR be made for this?
Actually, I found using the setValue
function when setting the datatable's getEditor
return object provided the same functionality.
For example (using Frappe Controls)
getEditor: function(colIndex, rowIndex, value, parent, column, row, data) {
// colIndex, rowIndex of the cell being edited
// value: value of cell before edit
// parent: edit container (use this to append your own custom control)
// column: the column object of editing cell
// row: the row of editing cell
// data: array of all rows
const control = frappe.ui.form.make_control({
parent: parent,
df: {
label: '',
fieldname: doctype,
fieldtype: 'Link',
options: doctype
},
render_input: true,
only_input: true,
});
let oldValue = '';
return {
// called when cell is being edited
initValue(value) {
control.input.focus();
control.input.value = value;
oldValue = value;
},
// called when cell value is set
setValue(newValue) {
// ----------- Do whatever is needed here.
control.input.value = newValue;
},
// value to show in cell
getValue() {
return control.input.value;
}
}
}
I've hit a strange roadblock.
Inline editing works in Report Builder, but calculated fields are not possible.
Calculated fields are possible in script editor, but inline editing is not possible.
I've hit a strange roadblock.
Inline editing works in Report Builder, but calculated fields are not possible.
Calculated fields are possible in script editor, but inline editing is not possible.
Editing a calculated field goes against their purpose. I would make it whatever type it should be and do the calculation manually. Alternatively, you can make a hidden calculation field and copy the value over to the editable field.
I've hit a strange roadblock.
Inline editing works in Report Builder, but calculated fields are not possible.
Calculated fields are possible in script editor, but inline editing is not possible.Editing a calculated field goes against their purpose. I would make it whatever type it should be and do the calculation manually. Alternatively, you can make a hidden calculation field and copy the value over to the editable field.
Obviously! I wouldn't want a calculated field to be editable. Instead, I have a report where both type of columns are needed - one for calculated and another for inline editing.