Form API

In TechMaju, the frm object provides a wide range of methods for interacting with forms. These methods are essential for setting values, refreshing forms, handling events, and more. Below is a detailed list of commonly used methods along with their descriptions and examples.

Setting Values

Method

Description

frm.set_value

Set the value of a field. Triggers the field change event.

// set a single value
frm.set_value('description', 'New description')

// set multiple values at once
frm.set_value({
    status: 'Open',
    description: 'New description'
})

// returns a promise
frm.set_value('description', 'New description')
    .then(() => {
        // do something after value is set
    })

Refreshing and Saving

Method

Description

Example

frm.refresh

Refresh the form with the latest values from the server.

frm.refresh();

frm.save

Trigger form save, with options for Submit, Cancel, and Update.

// save form
frm.save();

// submit form
frm.save('Submit');

// cancel form
frm.save('Cancel');

// update form (after submit)
frm.save('Update');

Enabling/Disabling Save

Method

Description

frm.enable_save

Enable the Save button.

frm.disable_save

Disable the Save button.

if (frappe.user_roles.includes('Custom Role')) {
    frm.enable_save();
} else {
    frm.disable_save();
}

Emailing Documents

Method

Description

frm.email_doc

Open Email dialog for this form.

// open email dialog
frm.email_doc();

// open email dialog with some message
frm.email_doc(`Hello ${frm.doc.customer_name}`);

Reloading and Refreshing Fields

Method

Description

Example

frm.reload_doc

Reload document with latest values from the server and call frm.refresh().

frm.reload_doc();

frm.refresh_field

Refresh a specific field and its dependencies.

frm.refresh_field('description');

Form State and Checks

Method

Description

Example

frm.is_dirty

Check if form values have been changed and not saved yet.

if (frm.is_dirty()) {    frappe.show_alert('Please save form before attaching a file')
}

frm.dirty

Set form as "dirty".

frm.doc.browser_data = navigator.appVersion;
frm.dirty();
frm.save();

frm.is_new

Check if the form is new and not saved yet.

// add custom button only if form is not new
if (!frm.is_new()) {
frm.add_custom_button('Click me', () => console.log('Clicked custom button'))
}

Setting Intro Text

Method

Description

frm.set_intro

Set intro text on the top of the form with optional color.

if (!frm.doc.description) {
    frm.set_intro('Please set the value of description', 'blue');
}

Intro text example

Custom Buttons

Method

Description

Example

frm.add_custom_button

Add a custom button in the inner toolbar.

// Custom buttons
frm.add_custom_button('Open Reference form', () => {
    frappe.set_route('Form', frm.doc.reference_type, frm.doc.reference_name);
})

// Custom buttons in groups
frm.add_custom_button('Closed', () => {
    frm.doc.status = 'Closed'
}, 'Set Status');

frm.change_custom_button_type

Change a custom button type by label.

// change type of ungrouped button
frm.change_custom_button_type('Open Reference form', null, 'primary');

// change type of a button in a group
frm.change_custom_button_type('Closed', 'Set Status', 'danger');

frm.remove_custom_button

Remove a custom button by label.

// remove custom button
frm.remove_custom_button('Open Reference form');

// remove custom button in a group
frm.remove_custom_button('Closed', 'Set Status');

frm.clear_custom_buttons

Remove all custom buttons from the inner toolbar.

frm.clear_custom_buttons();

DocField Properties

Method

Description

frm.set_df_property

Change the DocField property of a field and refresh it.

// change the fieldtype of description field to Text
frm.set_df_property('description', 'fieldtype', 'Text');

// set the options of the status field to only be [Open, Closed]
frm.set_df_property('status', 'options', ['Open', 'Closed'])

// set a field as mandatory
frm.set_df_property('title', 'reqd', 1)

// set a field as read only
frm.set_df_property('status', 'read_only', 1)

Field Toggles

Method

Description

Example

frm.toggle_enable

Toggle a field or list of fields as read-only based on a condition.

// set status and priority as read_only
// if user does not have System Manager role
let is_allowed = frappe.user_roles.includes('System Manager');
frm.toggle_enable(['status', 'priority'], is_allowed);

frm.toggle_reqd

Toggle a field or list of fields as mandatory based on a condition.

// set priority as mandatory
// if status is Open
frm.toggle_reqd('priority', frm.doc.status === 'Open');

frm.toggle_display

Show/hide a field or list of fields based on a condition.

// show priority and due_date field
// if status is Open
frm.toggle_display(['priority', 'due_date'], frm.doc.status === 'Open');

Setting Queries

Method

Description

frm.set_query

Apply filters on a Link field to show limited records to choose from. You must call frm.set_query very early in the form lifecycle, usually in setup or onload.

// show only customers whose territory is set to India
frm.set_query('customer', () => {
    return {
        filters: {
            territory: 'India'
        }
    }
})

// show customers whose territory is any of India, Nepal, Japan
frm.set_query('customer', () => {
    return {
        filters: {
            territory: ['in', ['India', 'Nepal', 'Japan']]
        }
    }
})

// set filters for Link field item_code in
// items field which is a Child Table
frm.set_query('item_code', 'items', () => {
    return {
        filters: {
            item_group: 'Products'
        }
    }
})

You can also override the filter method and provide your own custom method on the server side. Just the set the query to the module path of your python method.

// change the filter method by passing a custom method
frm.set_query('fieldname', () => {
    return {
        query: 'dotted.path.to.custom.custom_query',
        filters: {
            field1: 'value1'
        }
    }
})
# python method signature
def custom_query(doctype, txt, searchfield, start, page_len, filters):
    # your logic
    return filtered_list

Child Table Operations

Method

Description

Example

frm.add_child

Add a row with values to a Table field.

let row = frm.add_child('items', {
    item_code: 'Tennis Racket',
    qty: 2
});

frm.refresh_field('items');

Server Calls

Method

Description

frm.call

Call a server-side controller method with arguments. While accessing any server side method using frm.call(), you need to whitelist such method using the @frappe.whitelist decorator.

class ToDo(Document):
    @frappe.whitelist()
    def get_linked_doc(self, throw_if_missing=False):
        if not frappe.db.exists(self.reference_type, self.reference_name):
            if throw_if_missing:
                frappe.throw('Linked document not found')

        return frappe.get_doc(self.reference_type, self.reference_name)

You can call it from client using frm.call.

frm.call('get_linked_doc', { throw_if_missing: true })
    .then(r => {
        if (r.message) {
            let linked_doc = r.message;
            // do something with linked_doc
        }
    })

Triggering Events

Method

Description

frm.trigger

Trigger any form event explicitly.

frappe.ui.form.on('ToDo', {
    refresh(frm) {
        frm.trigger('set_mandatory_fields');
    },

    set_mandatory_fields(frm) {
        frm.toggle_reqd('priority', frm.doc.status === 'Open');
    }
})

Getting Selected Rows

Method

Description

Example

frm.get_selected

Get selected rows in Child Tables in an object where key is the table fieldname and values are row names.

let selected = frm.get_selected()
console.log(selected)
// {
//  items: ["bbfcb8da6a", "b1f1a43233"]
//  taxes: ["036ab9452a"]
// }

Ignoring Linked Doctypes

Method

Description

frm.ignore_doctypes_on_cancel_all

To avoid cancellation of linked documents during cancel all, you need to set the frm.ignored_doctypes_on_cancel_all property with an array of DocTypes of linked documents.

frappe.ui.form.on("DocType 1", {
    onload: function(frm) {
        // Ignore cancellation for all linked documents of respective DocTypes.
        frm.ignore_doctypes_on_cancel_all = ["DocType 2", "DocType 3"];
    }
}

In the above example, the system will avoid cancellation for all documents of 'DocType 2' and 'DocType 3' which are linked with document of 'DocType 1' during cancellation.

Discard
Save

On this page

Review Changes ← Back to Content
Message Status Space Raised By Last update on