Custom Actions
Custom Actions allow you to add custom buttons and dropdown actions to Lead and Deal pages in Frappe CRM. These actions can execute your own logic, such as creating documents, updating records, navigating to pages, or triggering custom workflows.
You can create individual action buttons, group multiple actions under a dropdown menu, or create labeled dropdown buttons based on your business requirements.
Tip
Use Custom Actions to add shortcuts for frequently performed tasks. Well-designed actions can reduce manual steps and help users complete workflows faster.
Creating Custom Actions
Custom Actions are created using a CRM Form Script. You can define actions for Lead or Deal records by adding the this.actions property inside the onLoad() function.
To create a custom action:
- Open CRM Form Script from Desk.
- Select the required DocType (Lead or Deal).
- Create a script class.
- Define your actions inside the
onLoad()method. - Save and test the action from the document page.
Adding a Single Action Button
You can create a simple button that appears directly in the page header.
class CRMDeal {
onLoad() {
this.actions = [
{
label: "Open in Desk",
onClick: (close) => {
let URL = `https://frappecrm.frappe.cloud/app/crm-deal/${this.doc.name}`
window.open(URL, '_blank')
}
}
]
}
}
This creates an Open in Desk button that opens the current Deal record in a new browser tab.
Grouped Actions
Multiple actions can be grouped together under a dropdown menu using the group property. This helps organize several related actions without adding multiple buttons to the header.
Three-Dot Menu Actions
Use hideLabel: true to display grouped actions inside a three-dot menu without showing the group name.
class CRMDeal {
onLoad() {
this.actions = [
{
group: "Add",
hideLabel: true,
items: [
{ label: "Create Quotation", onClick: (close) => {} },
{ label: "Create Sales Order", onClick: (close) => {} },
]
},
{
group: "Delete",
items: [
{ label: "Delete Quotation", onClick: (close) => {} },
{ label: "Delete Sales Order", onClick: (close) => {} },
]
}
]
}
}
Creating a Labeled Dropdown Button
You can use buttonLabel to display a named dropdown button instead of the default three-dot icon.
class CRMDeal {
onLoad() {
this.actions = [
{
buttonLabel: "Create",
group: "Add",
hideLabel: true,
items: [
{ label: "Create Quotation", onClick: (close) => {} },
{ label: "Create Sales Order", onClick: (close) => {} },
]
}
]
}
}
Combining Buttons and Groups
You can use individual buttons and grouped actions together within the same action list.
class CRMDeal {
onLoad() {
this.actions = [
{
label: "Refresh Score",
icon: "refresh-cw",
onClick: (close) => { /* Logic here */ }
},
{
group: "More",
hideLabel: true,
items: [
{ label: "Export PDF", onClick: (close) => {} },
{ label: "Duplicate", onClick: (close) => {} },
]
}
]
}
}
Available Helpers
Custom Action scripts provide built-in helpers that allow you to update records, call server methods, display messages, and navigate between pages.
Available Helpers
- this.doc — Access the current document and read or update field values.
- call(method, params) — Execute server-side Python methods and return results as a Promise.
- createDialog(options) — Display confirmation dialogs with custom actions.
- formDialog(options) — Create forms inside dialogs to collect user input.
- toast.success(), toast.error(), toast.info() — Display notifications to users.
- router.push(), router.replace() — Navigate users to different pages.
- throwError(msg) — Display an error message and stop execution.
Examples of Custom Actions
Create Quotation for Won Deals
This action checks whether a Deal is marked as Won. If the condition is met, it creates a quotation using a server-side method and redirects the user to the quotation page.
class CRMDeal {
onLoad() {
this.actions = [
{
label: "Create Quotation",
icon: "file-text",
onClick: (close) => {
if (this.doc.status !== "Won") {
toast.info("This action is only available for Won deals");
return;
}
call("crm.api.quotation.create_from_deal", {
deal: this.doc.name,
customer: this.doc.organization,
}).then((data) => {
if (data?.name) {
router.push({
name: "Quotation",
params: { name: data.name }
});
toast.success("Quotation created successfully");
} else {
toast.error("Could not create quotation");
}
});
},
},
];
}
}
Mark Deal as Lost
You can use confirmation dialogs before performing important actions, such as changing a Deal status.
- Shows a confirmation message before updating the record.
- Updates the Deal status directly after confirmation.
- Displays a success notification after completion.
Schedule Follow-Up
Custom Actions can also collect user input using form dialogs. For example, you can create a follow-up scheduler with date and notes fields.
- Create custom dialog fields.
- Collect information from users.
- Send entered values to server-side methods.
- Display confirmation messages after completion.
Delete Deal with Confirmation
You can create protected delete actions by asking users for confirmation before removing records.
- Display a confirmation dialog.
- Delete the selected Deal record.
- Redirect users back to the Deal list.
- Show a success message after deletion.
Showing and Hiding Actions Based on Field Values
Custom Actions can be displayed conditionally based on document values. For example, you may want to show the Mark as Lost action only when the Deal is not already lost.
To update actions dynamically:
- Create a function that updates
this.actions. - Call the function when the document loads.
- Run the function again whenever related fields change.
class CRMDeal {
onLoad() {
this._updateActions();
}
status() {
this._updateActions();
}
_updateActions() {
const isLost = this.doc.status === "Lost";
this.actions = [
{
label: "Create Quotation",
onClick: (close) => {
/* Logic */
},
},
...(!isLost
? [
{
label: "Mark as Lost",
icon: "x-circle",
onClick: (close) => {
/* Logic */
},
},
]
: []),
];
}
}
Best Practice
Keep Custom Actions focused on frequently used workflows. Avoid adding too many actions, as excessive buttons can make the interface harder for users to navigate.
Common Uses for Custom Actions
- Create quotations, orders, or related documents.
- Update Lead or Deal status.
- Trigger approval workflows.
- Schedule follow-ups.
- Open external pages or internal Desk views.
- Run custom business logic.
- Export or generate documents.
Best Practices
- Create actions for repetitive tasks that users perform regularly.
- Use meaningful button labels that clearly explain the action.
- Add confirmation dialogs before critical changes.
- Use grouped actions when multiple related options exist.
- Display actions conditionally when they are only useful in specific situations.
Note
Custom Actions are configured through CRM Form Scripts and require JavaScript knowledge. Always test actions in a development environment before applying them to production workflows.