人财事物信息化 - Action Buttons in Column
Action Buttons in Column
Use Case
As seen above, we want an inline “Close” button for each row in the above report. Clicking on this button should close the corresponding ToDo and refresh the report automatically.
The Report Python Script
The logic below is pretty simple. We are fetching the status
, description
and name
for the ToDo documents that are either created by or allocated to the currently logged in user using or_filters
:
my_todos.py
import frappe
def execute(filters=None):
return get_columns(), get_data()
def get_data():
current_user = frappe.session.user
todos = frappe.get_all(
"ToDo",
filters={"status": "Open"},
# created by or allocated to current user
or_filters=[{"owner": current_user}, {"allocated_to": current_user}],
fields=["name", "description", "status"],
)
return todos
# 3 columns
def get_columns():
return [
{
"label": "Description",
"fieldname": "description",
"fieldtype": "Data",
"width": 400,
},
{"label": "Status", "fieldname": "status", "fieldtype": "Data", "width": 200},
# This column will be used to render the close buttons
{
"label": "Close Action",
"fieldname": "name",
"fieldtype": "Data",
"width": 150,
},
]
The JS Script
We will basically be making (a clever 😆) use of the formatter
feature of query report scripts to render a button in every row of the “Close Action” column (field name is name):
my_todos.js
frappe.query_reports["My ToDos"] = {
filters: [],
onload(report) {
// add an action button to visit ToDo List View
report.page.add_inner_button("Go to ToDo List", () => {
frappe.set_route("List", "ToDo");
});
},
formatter(value, row, column, data, default_formatter) {
// Show a button instead of the "name"
if (column.fieldname == "name") {
const button_html = ``;
value = button_html;
}
return default_formatter(value, row, column, data);
},
close_todo(name) {
frappe.db.set_value("ToDo", name, "status", "Closed").then(() => {
// refresh this report and show alert
frappe.query_report.refresh();
frappe.show_alert("ToDo Closed Successfully!");
});
},
};
Some Notes From Above Script
-
We are using the
add_inner_button
JavaScript API to add a button at the top of the report page:report.page.add_inner_button("Go to ToDo List", () => { frappe.set_route("List", "ToDo"); });
-
frappe.query_report
refers to the currently open report view. (analogous tocur_frm
in form view andcur_list
in list view) -
On click of a button, we are triggering the
close_todo
method of the report script:// ${value} is the name of the ToDo document we sent from backend frappe.query_reports['My ToDos'].close_todo('${value}')