How to Add, Remove, and Manage Custom Buttons in Frappe Forms
Custom ButtonLearn 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.
1 // Generic syntax to add a custom button 2 frm.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 7 frappe.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) 22 frm.remove_custom_button('Create Meeting', 'Make'); 23
24 // To clear all custom buttons from the form header 25 frm.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 moreForm 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 moreButton 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 moreStep-by-Step Tutorial
Follow along to understand how this code works
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'.
// Select 'Sales Order' in the 'DocType' field in the Client Script form.
// Leave 'View' as 'Form'.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.
frappe.ui.form.on('Sales Order', {
refresh: function(frm) {
// Your code will go here
}
});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.
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'));
}
}
});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.
// No code for this step. Simply save the script and refresh the Sales Order form.Common Issues & Solutions
Troubleshoot problems you might encounter