Frappe UIJavascript

How to Add, Remove, and Manage Custom Buttons in Frappe Forms

Custom Button

Learn to dynamically add, remove, and clear custom buttons on Frappe forms using the frm.add_custom_button and related client script APIs for enhanced UI.

In the Frappe Framework, custom buttons provide a powerful way to extend the functionality of DocType forms. They allow developers to add user-triggered actions directly to the form's user interface. These actions can range from simple navigation links to complex operations that call server-side Python methods, trigger other client scripts, or open new documents.

The primary API for managing these buttons is available through the `frm` object in Client Scripts. This includes methods for adding, removing, and clearing buttons, giving you full dynamic control over the form's interactive elements based on user roles, document status, or field values.

javascript
1// Generic syntax to add a custom button
2frm.add_custom_button(__(label), () => {
3 // Action to perform on click
4}, __(group_name));
5
6// Example: Adding a 'Meeting' button to the 'Meeting Schedule' DocType
7frappe.ui.form.on('Meeting Schedule', {
8 refresh: function(frm) {
9 if (!frm.doc.__islocal) { // Only show button on saved documents
10 frm.add_custom_button(__("Create Meeting"), function() {
11 frappe.model.open_mapped_doc({
12 method : "eie.eie.doctype.meeting_schedule.meeting_schedule.make_meeting",
13 frm : cur_frm
14 })
15 }, __("Make"))
16 }
17 }
18});
19
20
21// To Remove a particular custom button (must match label and group)
22frm.remove_custom_button('Create Meeting', 'Make');
23
24// To clear all custom buttons from the form header
25frm.clear_custom_buttons()

Understanding This Code

What It Does

This snippet provides the client-side API methods to dynamically add, remove, and clear all custom buttons on a Frappe DocType form. This allows for creating a more interactive and role-specific user experience.

When To Use

Use these methods within form-level Client Scripts, typically inside the `onload` or `refresh` events. The `refresh` event is often preferred as it fires every time the form is loaded or reloaded after a save.

Prerequisites

  • A basic understanding of Frappe Client Scripts.
  • Familiarity with DocType forms and their lifecycle events.

Key Concepts

Important ideas to understand in this code

frm Object

The 'frm' object is the primary handle for interacting with a form in a Frappe Client Script. It contains the document's data, metadata, and provides methods like `add_custom_button`, `set_value`, and `refresh_field`.

Learn more

Form Triggers

Form triggers are JavaScript events that fire at specific points in a DocType's lifecycle (e.g., onload, refresh, validate). The `refresh` trigger is ideal for UI manipulations like adding buttons, as it ensures they are present on load and after saves.

Learn more

Button Groups

The optional third parameter in `add_custom_button` is the group name. If multiple buttons share the same group name, Frappe automatically renders them within a single dropdown menu, helping to de-clutter the form's action bar.

Learn more

Step-by-Step Tutorial

Follow along to understand how this code works

1

Create a New Client Script

Navigate to 'Client Script' from the Awesome Bar. Click 'Add Client Script' and select the DocType you want to modify, for example, 'Sales Order'.

text
// Select 'Sales Order' in the 'DocType' field in the Client Script form.
// Leave 'View' as 'Form'.
Next Step
2

Hook into the 'refresh' Event

Within the script editor, use the `frappe.ui.form.on` method to attach your code to the 'refresh' event. This ensures your script runs every time the form is loaded or updated.

javascript
frappe.ui.form.on('Sales Order', {
    refresh: function(frm) {
        // Your code will go here
    }
});
Next Step
3

Add the Custom Button

Inside the `refresh` function, call `frm.add_custom_button`. We'll add a button to check stock levels, which will appear in an 'Actions' group.

javascript
frappe.ui.form.on('Sales Order', {
    refresh: function(frm) {
        if (frm.doc.docstatus === 1) { // Only show button for submitted orders
            frm.add_custom_button(__('Check Stock Availability'), () => {
                frappe.msgprint('Checking stock levels...');
                // In a real scenario, you would call a server method here
            }, __('Actions'));
        }
    }
});
Next Step
4

Save and Test

Save the Client Script. Make sure it is enabled. Now, open a submitted 'Sales Order' form. You should see an 'Actions' dropdown button containing your 'Check Stock Availability' option.

text
// No code for this step. Simply save the script and refresh the Sales Order form.

Common Issues & Solutions

Troubleshoot problems you might encounter