How to override JavaScript Function

Hello everyone,

I am using Opportunity doctype in Frappe. Whenever I create an event, emails are automatically sent to the associated contact, which is not intended. I specifically want emails to be sent only to the event’s creator.
I’ve identified the function responsible for sending emails, which is located in form_timeline.js:
get_recipient() {
if (this.frm.email_field) {
return this.frm.doc[this.frm.email_field];
} else {
return this.frm.doc.email_id || this.frm.doc.email || “”;
}
}

Could someone please advise on how to override this function or suggest an alternative method to ensure emails are sent only to the event creator? Your assistance is greatly appreciated.

Thank you!

1 Like
1 Like

You can do monkey patching in your custom app. In your app’s hook, see the app_include_js list, and add your monkey patching file there. If no file is listed, you can create your own, like patching.bundle.js, in the public/js folder.

The code should look like this:

import FormTimeline from "../frappe/frappe/public/js/frappe/form/footer/form_timeline";

FormTimeline.prototype.get_recipient = function() {
  // your code
}
2 Likes

@Abdeali
I have one custom function make_quality_inspection in custom_app.js.

i want to override the core js function by this function.

That core function is : /home/kiranmai/Desktop/ERPNext/frappe-bench/apps/erpnext/erpnext/public/js/controllers/transaction.make_quality_inspection

Can anyone please share the steps.

Anyone?

Make folder structure like (depends on you):
image

forum_issue.bundle.js :

import "./monkey_patch/transaction.js";

transaction.js :

erpnext.TransactionController.prototype.make_quality_inspection = function () {
	// Your new implementation goes here
};

hooks.py:

app_include_js = ["forum_issue.bundle.js"]

Note: forum_issue :arrow_right: YOUR_APP_NAME

If not works build the bench.

bench build --app YOUR_APP_NAME
3 Likes

@Abdeali Thanks for your reply!

I followed all above mentioned steps and im getting error : GET http://127.0.0.1:8000/hilltop.bundle.js net::ERR_ABORTED 404 (NOT FOUND)Understand this error
jquery.js:3539

have you try to build?

Or can you share hook and folder structure?

@Abdeali I resolved it.

Is monkey_patch a correct method to follow to override core js functions??
Is there any method to do the same??

I don’t know other than monkey patching.

But you have to take care of original function/method. If Its change its behavior or signature then maybe your code can break.

1 Like

Hi @Abdeali

I was trying to create override a function from healthcare app which is I need create custom code for update_status method which is originally defined in patient_appointment.js

can I know how can override a function and it is not a class

Thanks is advance

  • Monkey Patching show_alert: position argument for show_alert()
const original_show_alert = frappe.show_alert;
const VALID_POSITIONS = {
    top: "100px",
    bottom: "0px"
};

function alert_custom_position(message, seconds, actions) {
    let alert_container = original_show_alert(message, seconds, actions);

    if (typeof message === "object" && VALID_POSITIONS.hasOwnProperty(message.position)) {
        let alert_element = document.querySelector("#alert-container");
        if (alert_element) {
            Object.keys(VALID_POSITIONS).forEach(position => {
                if (position !== message.position) {
                    alert_element.style.removeProperty(position);
                }
            });

            alert_element.style.setProperty(message.position, VALID_POSITIONS[message.position], 'important');
        }
    }

    return alert_container;
}

frappe.show_alert = alert_custom_position;

In your case you have to import function.

Yes @Anisha_Jain
This function is in FormTimeline class you can extend this class and overwrite the get_recipient function and the add the overwrite js file through hooks.py

Thank you for your reply!
Can you give me a hint which is how can I import a function which is not exported in the original file ?

Hello,

It wouldn’t work.

What is your use case?

I would suggest, hide that `cancel` custom button and create your own custom button and create your own logic.