Field Change Event Trigger doesn't work

I need to perform some calculation when the Quotation total changes, but I can’t get any useful trigger to work.

I have tried two different trigger definitions:

frappe.ui.form.on('Quotation', {
	total(frm) {
		console.log("total changed");
	},
});

frappe.ui.form.on("Quotation", "total", function(frm) {
	console.log("total changed");
});

But they are not triggered for any of those fields:
total, net_total, grand_total etc…

It is the same in the Quotation Item childtable, fields like amount don’t trigger.

The triggers do work for those fields:
currency, quotation_to and others

I can confirm that this is not caused by readonly status, as the behaviour is the same when I disable readonly. My guess is that when ERPNext updates the values of those fields, it does not trigger the field change events.

Any input is greatly appreciated!


ERPNext: v13.19.0 (version-13)
Frappe Framework: v13.19.0 (version-13)

Hi, @philippm,

Please try the script and it works in the console.

 frappe.ui.form.on('Quotation', {
	total(frm) {
        frm.refresh_fields("total");
		console.log(frm.doc.total, "total changed");
	},
});

Thank You!

1 Like

Try this

frappe.ui.form.on('Quotation', {
	total: function(frm) {
		console.log("total changed");
	}
});

Hi @NCP,
thanks for the input but his doesn’t work because total(frm){} is never executed when ERPNext updates the field.
frm.refresh_fields("total") would trigger the field change event if I did the change myself, but it is ERPNext who changes the field.

@capintervencion
Thanks, I have never seen this syntax being used. Unfortunately it behaves the same as my other attempts and doesn’t get triggered when ERPNext changes the fields value.

Hi @philippm,

Please try before_save trigger.

Thanks.

@NCP before_save is only a workaround, because it runs on save. I want to update the field live, i.e. while the document is edited.

@philippm
Onchange event is not trigger on quick entry form. I think that was the reason that you can’t see console. Try this on full edit form. But if you want to call this event on quick entry form then check this link.

Since ERPNext does not trigger the field change event for certain fields, I ended up using a JS MutationObserver to know when a field value was changed:

onload_post_render(frm) {
    // EVENT LISTENERS
    if (frm.event_listeners_set !== true) {
        
        new MutationObserver(throttle(() => {
            console.debug("MutationObserver: Total changed");
            frm.trigger('total');
        }, 300)).observe(getElement('total'), { childList: true, subtree: true });
        
        frm.event_listeners_set = true;
    }
},
function getElement (fieldname, childtable = null, row = null) {
    let formPage = getFormPage();

    if (formPage && childtable && row) {
        formPage = getFormPageChildTable(formPage, childtable, row)
    }

    if (formPage) {
        let elements = formPage.querySelectorAll("div[data-fieldname='" + fieldname + "']");
        let elements_onform = Array.from(elements).filter(element => $(element).parentsUntil($(formPage), "[data-fieldtype='Table']").length == 0); // Filter for elements not in Tables

        if (elements_onform.length == 1) {
            return elements_onform[0];
        }
    }

    console.error("Unable to get element with fieldname '" + fieldname + "'");
    console.error(formPage);
    console.error(elements);
    return null;
}
1 Like